From 80690175adf49dc775e0dc292f0389afe69a1dea Mon Sep 17 00:00:00 2001 From: Alex Konradi Date: Wed, 15 May 2024 11:07:42 -0400 Subject: [PATCH 1/2] Make #[non_exhaustive] for oneofs configurable Add a configuration option to disable annotating generated enum types for proto `oneof`s with `#[non_exhaustive]`. The annotation makes sense for self-contained crates, but it's convenient to be able to turn it off. One use case is for larger projects that consist of multiple crates that are developed together. Being unable to exhaustively match on the contents of `oneof`s not just in the crate that includes the generated protobuf code is very useful. --- proto/rustproto.proto | 6 + protobuf-codegen/src/customize/mod.rs | 7 + .../src/customize/rustproto_proto.rs | 6 + protobuf-codegen/src/gen/oneof.rs | 9 +- protobuf-parse/src/proto/rustproto.proto | 6 + protobuf/src/rustproto.rs | 183 ++++++++++-------- 6 files changed, 137 insertions(+), 80 deletions(-) diff --git a/proto/rustproto.proto b/proto/rustproto.proto index 89f037775..b9ca843c5 100644 --- a/proto/rustproto.proto +++ b/proto/rustproto.proto @@ -19,6 +19,8 @@ extend google.protobuf.FileOptions { optional bool tokio_bytes_all = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string_all = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive_all = 17013; // When true, will only generate codes that works with lite runtime. optional bool lite_runtime_all = 17035; @@ -33,6 +35,8 @@ extend google.protobuf.MessageOptions { optional bool tokio_bytes = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive = 17013; } extend google.protobuf.FieldOptions { @@ -44,4 +48,6 @@ extend google.protobuf.FieldOptions { optional bool tokio_bytes_field = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string_field = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive_field = 17013; } diff --git a/protobuf-codegen/src/customize/mod.rs b/protobuf-codegen/src/customize/mod.rs index 826bd3f6d..bebb7658b 100644 --- a/protobuf-codegen/src/customize/mod.rs +++ b/protobuf-codegen/src/customize/mod.rs @@ -98,6 +98,8 @@ pub struct Customize { pub(crate) tokio_bytes: Option, /// Use `bytes::Bytes` for `string` fields pub(crate) tokio_bytes_for_string: Option, + /// When false, `#[non_exhaustive]` is not generated for `oneof` fields. + pub(crate) oneofs_non_exhaustive: Option, /// Enable lite runtime. pub(crate) lite_runtime: Option, /// Generate `mod.rs` in the output directory. @@ -148,6 +150,11 @@ impl Customize { self } + pub fn oneofs_non_exhaustive(mut self, non_exhaustive: bool) -> Self { + self.oneofs_non_exhaustive = Some(non_exhaustive); + self + } + /// Generate code for "lite runtime". Generated code contains no code for reflection. /// So the generated code (and more importantly, generated binary size) is smaller, /// but reflection, text format, JSON serialization won't work. diff --git a/protobuf-codegen/src/customize/rustproto_proto.rs b/protobuf-codegen/src/customize/rustproto_proto.rs index 3d9a77b2f..e48303102 100644 --- a/protobuf-codegen/src/customize/rustproto_proto.rs +++ b/protobuf-codegen/src/customize/rustproto_proto.rs @@ -12,6 +12,7 @@ pub(crate) fn customize_from_rustproto_for_message(source: &MessageOptions) -> C let generate_getter = rustproto::exts::generate_getter.get(source); let tokio_bytes = rustproto::exts::tokio_bytes.get(source); let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string.get(source); + let oneofs_non_exhaustive = rustproto::exts::oneofs_non_exhaustive.get(source); let lite_runtime = None; let gen_mod_rs = None; let inside_protobuf = None; @@ -21,6 +22,7 @@ pub(crate) fn customize_from_rustproto_for_message(source: &MessageOptions) -> C generate_getter, tokio_bytes, tokio_bytes_for_string, + oneofs_non_exhaustive, lite_runtime, gen_mod_rs, inside_protobuf, @@ -37,6 +39,7 @@ pub(crate) fn customize_from_rustproto_for_field(source: &FieldOptions) -> Custo let generate_getter = rustproto::exts::generate_getter_field.get(source); let tokio_bytes = rustproto::exts::tokio_bytes_field.get(source); let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string_field.get(source); + let oneofs_non_exhaustive = rustproto::exts::oneofs_non_exhaustive_field.get(source); let lite_runtime = None; let gen_mod_rs = None; let inside_protobuf = None; @@ -46,6 +49,7 @@ pub(crate) fn customize_from_rustproto_for_field(source: &FieldOptions) -> Custo generate_getter, tokio_bytes, tokio_bytes_for_string, + oneofs_non_exhaustive, lite_runtime, gen_mod_rs, inside_protobuf, @@ -58,6 +62,7 @@ pub(crate) fn customize_from_rustproto_for_file(source: &FileOptions) -> Customi let generate_getter = rustproto::exts::generate_getter_all.get(source); let tokio_bytes = rustproto::exts::tokio_bytes_all.get(source); let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string_all.get(source); + let oneofs_non_exhaustive = rustproto::exts::oneofs_non_exhaustive_all.get(source); let lite_runtime = rustproto::exts::lite_runtime_all.get(source); let gen_mod_rs = None; let inside_protobuf = None; @@ -67,6 +72,7 @@ pub(crate) fn customize_from_rustproto_for_file(source: &FileOptions) -> Customi generate_getter, tokio_bytes, tokio_bytes_for_string, + oneofs_non_exhaustive, lite_runtime, inside_protobuf, gen_mod_rs, diff --git a/protobuf-codegen/src/gen/oneof.rs b/protobuf-codegen/src/gen/oneof.rs index 3f34cdccf..e1bd33901 100644 --- a/protobuf-codegen/src/gen/oneof.rs +++ b/protobuf-codegen/src/gen/oneof.rs @@ -252,7 +252,14 @@ impl<'a> OneofGen<'a> { fn write_enum(&self, w: &mut CodeWriter) { let derive = vec!["Clone", "PartialEq", "Debug"]; w.derive(&derive); - w.write_line("#[non_exhaustive]"); + if self + .customize + .for_elem + .oneofs_non_exhaustive + .unwrap_or(true) + { + w.write_line("#[non_exhaustive]"); + } write_protoc_insertion_point_for_oneof(w, &self.customize.for_elem, &self.oneof.oneof); w.pub_enum(&self.oneof.rust_name().ident.to_string(), |w| { for variant in self.variants_except_group() { diff --git a/protobuf-parse/src/proto/rustproto.proto b/protobuf-parse/src/proto/rustproto.proto index 89f037775..b9ca843c5 100644 --- a/protobuf-parse/src/proto/rustproto.proto +++ b/protobuf-parse/src/proto/rustproto.proto @@ -19,6 +19,8 @@ extend google.protobuf.FileOptions { optional bool tokio_bytes_all = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string_all = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive_all = 17013; // When true, will only generate codes that works with lite runtime. optional bool lite_runtime_all = 17035; @@ -33,6 +35,8 @@ extend google.protobuf.MessageOptions { optional bool tokio_bytes = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive = 17013; } extend google.protobuf.FieldOptions { @@ -44,4 +48,6 @@ extend google.protobuf.FieldOptions { optional bool tokio_bytes_field = 17011; // Use `bytes::Bytes` for `string` fields optional bool tokio_bytes_for_string_field = 17012; + // When false, `#[non_exhaustive]` is not generated for `oneof` fields. + optional bool oneofs_non_exhaustive_field = 17013; } diff --git a/protobuf/src/rustproto.rs b/protobuf/src/rustproto.rs index 84db4409e..aaf03428f 100644 --- a/protobuf/src/rustproto.rs +++ b/protobuf/src/rustproto.rs @@ -32,6 +32,8 @@ pub mod exts { pub const tokio_bytes_for_string_all: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17012, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + pub const oneofs_non_exhaustive_all: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17013, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + pub const lite_runtime_all: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17035, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); pub const generate_accessors: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17004, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); @@ -42,6 +44,8 @@ pub mod exts { pub const tokio_bytes_for_string: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17012, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + pub const oneofs_non_exhaustive: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17013, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + pub const generate_accessors_field: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17004, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); pub const generate_getter_field: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17005, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); @@ -49,6 +53,8 @@ pub mod exts { pub const tokio_bytes_field: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17011, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); pub const tokio_bytes_for_string_field: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17012, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + + pub const oneofs_non_exhaustive_field: crate::ext::ExtFieldOptional = crate::ext::ExtFieldOptional::new(17013, crate::descriptor::field_descriptor_proto::Type::TYPE_BOOL); } static file_descriptor_proto_data: &'static [u8] = b"\ @@ -59,85 +65,104 @@ static file_descriptor_proto_data: &'static [u8] = b"\ R\x11generateGetterAll:F\n\x0ftokio_bytes_all\x18\xf3\x84\x01\x20\x01(\ \x08\x12\x1c.google.protobuf.FileOptionsR\rtokioBytesAll:Z\n\x1atokio_by\ tes_for_string_all\x18\xf4\x84\x01\x20\x01(\x08\x12\x1c.google.protobuf.\ - FileOptionsR\x16tokioBytesForStringAll:H\n\x10lite_runtime_all\x18\x8b\ - \x85\x01\x20\x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x0eliteRuntim\ - eAll:P\n\x12generate_accessors\x18\xec\x84\x01\x20\x01(\x08\x12\x1f.goog\ - le.protobuf.MessageOptionsR\x11generateAccessors:J\n\x0fgenerate_getter\ - \x18\xed\x84\x01\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\ - \x0egenerateGetter:B\n\x0btokio_bytes\x18\xf3\x84\x01\x20\x01(\x08\x12\ - \x1f.google.protobuf.MessageOptionsR\ntokioBytes:V\n\x16tokio_bytes_for_\ - string\x18\xf4\x84\x01\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptio\ - nsR\x13tokioBytesForString:Y\n\x18generate_accessors_field\x18\xec\x84\ - \x01\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x16generateAcces\ - sorsField:S\n\x15generate_getter_field\x18\xed\x84\x01\x20\x01(\x08\x12\ - \x1d.google.protobuf.FieldOptionsR\x13generateGetterField:K\n\x11tokio_b\ - ytes_field\x18\xf3\x84\x01\x20\x01(\x08\x12\x1d.google.protobuf.FieldOpt\ - ionsR\x0ftokioBytesField:_\n\x1ctokio_bytes_for_string_field\x18\xf4\x84\ - \x01\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x18tokioBytesFor\ - StringFieldJ\x9d\x0f\n\x06\x12\x04\0\0.\x01\n\x08\n\x01\x0c\x12\x03\0\0\ - \x12\n\t\n\x02\x03\0\x12\x03\x02\0*\n\xe5\x01\n\x01\x02\x12\x03\n\0\x122\ - ^\x20see\x20https://github.com/gogo/protobuf/blob/master/gogoproto/gogo.\ - proto\n\x20for\x20the\x20original\x20idea\n2{\x20Generated\x20files\x20c\ - an\x20be\x20customized\x20using\x20this\x20proto\n\x20or\x20using\x20`Cu\ - stomize`\x20struct\x20when\x20codegen\x20is\x20invoked\x20programmatical\ - ly.\n\n\t\n\x01\x07\x12\x04\x0c\0\x18\x01\nP\n\x02\x07\0\x12\x03\x0e\x04\ - 1\x1aE\x20When\x20false,\x20`get_`,\x20`set_`,\x20`mut_`\x20etc.\x20acce\ - ssors\x20are\x20not\x20generated\n\n\n\n\x03\x07\0\x02\x12\x03\x0c\x07\"\ - \n\n\n\x03\x07\0\x04\x12\x03\x0e\x04\x0c\n\n\n\x03\x07\0\x05\x12\x03\x0e\ - \r\x11\n\n\n\x03\x07\0\x01\x12\x03\x0e\x12(\n\n\n\x03\x07\0\x03\x12\x03\ - \x0e+0\nL\n\x02\x07\x01\x12\x03\x10\x04.\x1aA\x20When\x20false,\x20`get_\ - `\x20is\x20not\x20generated\x20even\x20if\x20`syntax\x20=\x20\"proto2\"`\ - \n\n\n\n\x03\x07\x01\x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\x01\x04\x12\x03\ - \x10\x04\x0c\n\n\n\x03\x07\x01\x05\x12\x03\x10\r\x11\n\n\n\x03\x07\x01\ - \x01\x12\x03\x10\x12%\n\n\n\x03\x07\x01\x03\x12\x03\x10(-\n2\n\x02\x07\ - \x02\x12\x03\x12\x04*\x1a'\x20Use\x20`bytes::Bytes`\x20for\x20`bytes`\ - \x20fields\n\n\n\n\x03\x07\x02\x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\x02\ - \x04\x12\x03\x12\x04\x0c\n\n\n\x03\x07\x02\x05\x12\x03\x12\r\x11\n\n\n\ - \x03\x07\x02\x01\x12\x03\x12\x12!\n\n\n\x03\x07\x02\x03\x12\x03\x12$)\n3\ - \n\x02\x07\x03\x12\x03\x14\x045\x1a(\x20Use\x20`bytes::Bytes`\x20for\x20\ - `string`\x20fields\n\n\n\n\x03\x07\x03\x02\x12\x03\x0c\x07\"\n\n\n\x03\ - \x07\x03\x04\x12\x03\x14\x04\x0c\n\n\n\x03\x07\x03\x05\x12\x03\x14\r\x11\ - \n\n\n\x03\x07\x03\x01\x12\x03\x14\x12,\n\n\n\x03\x07\x03\x03\x12\x03\ - \x14/4\nN\n\x02\x07\x04\x12\x03\x17\x04+\x1aC\x20When\x20true,\x20will\ - \x20only\x20generate\x20codes\x20that\x20works\x20with\x20lite\x20runtim\ - e.\n\n\n\n\x03\x07\x04\x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\x04\x04\x12\ - \x03\x17\x04\x0c\n\n\n\x03\x07\x04\x05\x12\x03\x17\r\x11\n\n\n\x03\x07\ - \x04\x01\x12\x03\x17\x12\"\n\n\n\x03\x07\x04\x03\x12\x03\x17%*\n\t\n\x01\ - \x07\x12\x04\x1a\0#\x01\nP\n\x02\x07\x05\x12\x03\x1c\x04-\x1aE\x20When\ - \x20false,\x20`get_`,\x20`set_`,\x20`mut_`\x20etc.\x20accessors\x20are\ - \x20not\x20generated\n\n\n\n\x03\x07\x05\x02\x12\x03\x1a\x07%\n\n\n\x03\ - \x07\x05\x04\x12\x03\x1c\x04\x0c\n\n\n\x03\x07\x05\x05\x12\x03\x1c\r\x11\ - \n\n\n\x03\x07\x05\x01\x12\x03\x1c\x12$\n\n\n\x03\x07\x05\x03\x12\x03\ - \x1c',\nL\n\x02\x07\x06\x12\x03\x1e\x04*\x1aA\x20When\x20false,\x20`get_\ - `\x20is\x20not\x20generated\x20even\x20if\x20`syntax\x20=\x20\"proto2\"`\ - \n\n\n\n\x03\x07\x06\x02\x12\x03\x1a\x07%\n\n\n\x03\x07\x06\x04\x12\x03\ - \x1e\x04\x0c\n\n\n\x03\x07\x06\x05\x12\x03\x1e\r\x11\n\n\n\x03\x07\x06\ - \x01\x12\x03\x1e\x12!\n\n\n\x03\x07\x06\x03\x12\x03\x1e$)\n2\n\x02\x07\ - \x07\x12\x03\x20\x04&\x1a'\x20Use\x20`bytes::Bytes`\x20for\x20`bytes`\ - \x20fields\n\n\n\n\x03\x07\x07\x02\x12\x03\x1a\x07%\n\n\n\x03\x07\x07\ - \x04\x12\x03\x20\x04\x0c\n\n\n\x03\x07\x07\x05\x12\x03\x20\r\x11\n\n\n\ - \x03\x07\x07\x01\x12\x03\x20\x12\x1d\n\n\n\x03\x07\x07\x03\x12\x03\x20\ - \x20%\n3\n\x02\x07\x08\x12\x03\"\x041\x1a(\x20Use\x20`bytes::Bytes`\x20f\ - or\x20`string`\x20fields\n\n\n\n\x03\x07\x08\x02\x12\x03\x1a\x07%\n\n\n\ - \x03\x07\x08\x04\x12\x03\"\x04\x0c\n\n\n\x03\x07\x08\x05\x12\x03\"\r\x11\ - \n\n\n\x03\x07\x08\x01\x12\x03\"\x12(\n\n\n\x03\x07\x08\x03\x12\x03\"+0\ - \n\t\n\x01\x07\x12\x04%\0.\x01\nP\n\x02\x07\t\x12\x03'\x043\x1aE\x20When\ - \x20false,\x20`get_`,\x20`set_`,\x20`mut_`\x20etc.\x20accessors\x20are\ - \x20not\x20generated\n\n\n\n\x03\x07\t\x02\x12\x03%\x07#\n\n\n\x03\x07\t\ - \x04\x12\x03'\x04\x0c\n\n\n\x03\x07\t\x05\x12\x03'\r\x11\n\n\n\x03\x07\t\ - \x01\x12\x03'\x12*\n\n\n\x03\x07\t\x03\x12\x03'-2\nL\n\x02\x07\n\x12\x03\ - )\x040\x1aA\x20When\x20false,\x20`get_`\x20is\x20not\x20generated\x20eve\ - n\x20if\x20`syntax\x20=\x20\"proto2\"`\n\n\n\n\x03\x07\n\x02\x12\x03%\ - \x07#\n\n\n\x03\x07\n\x04\x12\x03)\x04\x0c\n\n\n\x03\x07\n\x05\x12\x03)\ - \r\x11\n\n\n\x03\x07\n\x01\x12\x03)\x12'\n\n\n\x03\x07\n\x03\x12\x03)*/\ - \n2\n\x02\x07\x0b\x12\x03+\x04,\x1a'\x20Use\x20`bytes::Bytes`\x20for\x20\ - `bytes`\x20fields\n\n\n\n\x03\x07\x0b\x02\x12\x03%\x07#\n\n\n\x03\x07\ - \x0b\x04\x12\x03+\x04\x0c\n\n\n\x03\x07\x0b\x05\x12\x03+\r\x11\n\n\n\x03\ - \x07\x0b\x01\x12\x03+\x12#\n\n\n\x03\x07\x0b\x03\x12\x03+&+\n3\n\x02\x07\ - \x0c\x12\x03-\x047\x1a(\x20Use\x20`bytes::Bytes`\x20for\x20`string`\x20f\ - ields\n\n\n\n\x03\x07\x0c\x02\x12\x03%\x07#\n\n\n\x03\x07\x0c\x04\x12\ - \x03-\x04\x0c\n\n\n\x03\x07\x0c\x05\x12\x03-\r\x11\n\n\n\x03\x07\x0c\x01\ - \x12\x03-\x12.\n\n\n\x03\x07\x0c\x03\x12\x03-16\ + FileOptionsR\x16tokioBytesForStringAll:Y\n\x19oneofs_non_exhaustive_all\ + \x18\xf5\x84\x01\x20\x01(\x08\x12\x1c.google.protobuf.FileOptionsR\x16on\ + eofsNonExhaustiveAll:H\n\x10lite_runtime_all\x18\x8b\x85\x01\x20\x01(\ + \x08\x12\x1c.google.protobuf.FileOptionsR\x0eliteRuntimeAll:P\n\x12gener\ + ate_accessors\x18\xec\x84\x01\x20\x01(\x08\x12\x1f.google.protobuf.Messa\ + geOptionsR\x11generateAccessors:J\n\x0fgenerate_getter\x18\xed\x84\x01\ + \x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x0egenerateGetter:\ + B\n\x0btokio_bytes\x18\xf3\x84\x01\x20\x01(\x08\x12\x1f.google.protobuf.\ + MessageOptionsR\ntokioBytes:V\n\x16tokio_bytes_for_string\x18\xf4\x84\ + \x01\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x13tokioBytesF\ + orString:U\n\x15oneofs_non_exhaustive\x18\xf5\x84\x01\x20\x01(\x08\x12\ + \x1f.google.protobuf.MessageOptionsR\x13oneofsNonExhaustive:Y\n\x18gener\ + ate_accessors_field\x18\xec\x84\x01\x20\x01(\x08\x12\x1d.google.protobuf\ + .FieldOptionsR\x16generateAccessorsField:S\n\x15generate_getter_field\ + \x18\xed\x84\x01\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x13g\ + enerateGetterField:K\n\x11tokio_bytes_field\x18\xf3\x84\x01\x20\x01(\x08\ + \x12\x1d.google.protobuf.FieldOptionsR\x0ftokioBytesField:_\n\x1ctokio_b\ + ytes_for_string_field\x18\xf4\x84\x01\x20\x01(\x08\x12\x1d.google.protob\ + uf.FieldOptionsR\x18tokioBytesForStringField:^\n\x1boneofs_non_exhaustiv\ + e_field\x18\xf5\x84\x01\x20\x01(\x08\x12\x1d.google.protobuf.FieldOption\ + sR\x18oneofsNonExhaustiveFieldJ\xca\x12\n\x06\x12\x04\0\04\x01\n\x08\n\ + \x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x02\0*\n\xe5\x01\n\x01\ + \x02\x12\x03\n\0\x122^\x20see\x20https://github.com/gogo/protobuf/blob/m\ + aster/gogoproto/gogo.proto\n\x20for\x20the\x20original\x20idea\n2{\x20Ge\ + nerated\x20files\x20can\x20be\x20customized\x20using\x20this\x20proto\n\ + \x20or\x20using\x20`Customize`\x20struct\x20when\x20codegen\x20is\x20inv\ + oked\x20programmatically.\n\n\t\n\x01\x07\x12\x04\x0c\0\x1a\x01\nP\n\x02\ + \x07\0\x12\x03\x0e\x041\x1aE\x20When\x20false,\x20`get_`,\x20`set_`,\x20\ + `mut_`\x20etc.\x20accessors\x20are\x20not\x20generated\n\n\n\n\x03\x07\0\ + \x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\0\x04\x12\x03\x0e\x04\x0c\n\n\n\x03\ + \x07\0\x05\x12\x03\x0e\r\x11\n\n\n\x03\x07\0\x01\x12\x03\x0e\x12(\n\n\n\ + \x03\x07\0\x03\x12\x03\x0e+0\nL\n\x02\x07\x01\x12\x03\x10\x04.\x1aA\x20W\ + hen\x20false,\x20`get_`\x20is\x20not\x20generated\x20even\x20if\x20`synt\ + ax\x20=\x20\"proto2\"`\n\n\n\n\x03\x07\x01\x02\x12\x03\x0c\x07\"\n\n\n\ + \x03\x07\x01\x04\x12\x03\x10\x04\x0c\n\n\n\x03\x07\x01\x05\x12\x03\x10\r\ + \x11\n\n\n\x03\x07\x01\x01\x12\x03\x10\x12%\n\n\n\x03\x07\x01\x03\x12\ + \x03\x10(-\n2\n\x02\x07\x02\x12\x03\x12\x04*\x1a'\x20Use\x20`bytes::Byte\ + s`\x20for\x20`bytes`\x20fields\n\n\n\n\x03\x07\x02\x02\x12\x03\x0c\x07\"\ + \n\n\n\x03\x07\x02\x04\x12\x03\x12\x04\x0c\n\n\n\x03\x07\x02\x05\x12\x03\ + \x12\r\x11\n\n\n\x03\x07\x02\x01\x12\x03\x12\x12!\n\n\n\x03\x07\x02\x03\ + \x12\x03\x12$)\n3\n\x02\x07\x03\x12\x03\x14\x045\x1a(\x20Use\x20`bytes::\ + Bytes`\x20for\x20`string`\x20fields\n\n\n\n\x03\x07\x03\x02\x12\x03\x0c\ + \x07\"\n\n\n\x03\x07\x03\x04\x12\x03\x14\x04\x0c\n\n\n\x03\x07\x03\x05\ + \x12\x03\x14\r\x11\n\n\n\x03\x07\x03\x01\x12\x03\x14\x12,\n\n\n\x03\x07\ + \x03\x03\x12\x03\x14/4\nQ\n\x02\x07\x04\x12\x03\x16\x044\x1aF\x20When\ + \x20false,\x20`#[non_exhaustive]`\x20is\x20not\x20generated\x20for\x20`o\ + neof`\x20fields.\n\n\n\n\x03\x07\x04\x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\ + \x04\x04\x12\x03\x16\x04\x0c\n\n\n\x03\x07\x04\x05\x12\x03\x16\r\x11\n\n\ + \n\x03\x07\x04\x01\x12\x03\x16\x12+\n\n\n\x03\x07\x04\x03\x12\x03\x16.3\ + \nN\n\x02\x07\x05\x12\x03\x19\x04+\x1aC\x20When\x20true,\x20will\x20only\ + \x20generate\x20codes\x20that\x20works\x20with\x20lite\x20runtime.\n\n\n\ + \n\x03\x07\x05\x02\x12\x03\x0c\x07\"\n\n\n\x03\x07\x05\x04\x12\x03\x19\ + \x04\x0c\n\n\n\x03\x07\x05\x05\x12\x03\x19\r\x11\n\n\n\x03\x07\x05\x01\ + \x12\x03\x19\x12\"\n\n\n\x03\x07\x05\x03\x12\x03\x19%*\n\t\n\x01\x07\x12\ + \x04\x1c\0'\x01\nP\n\x02\x07\x06\x12\x03\x1e\x04-\x1aE\x20When\x20false,\ + \x20`get_`,\x20`set_`,\x20`mut_`\x20etc.\x20accessors\x20are\x20not\x20g\ + enerated\n\n\n\n\x03\x07\x06\x02\x12\x03\x1c\x07%\n\n\n\x03\x07\x06\x04\ + \x12\x03\x1e\x04\x0c\n\n\n\x03\x07\x06\x05\x12\x03\x1e\r\x11\n\n\n\x03\ + \x07\x06\x01\x12\x03\x1e\x12$\n\n\n\x03\x07\x06\x03\x12\x03\x1e',\nL\n\ + \x02\x07\x07\x12\x03\x20\x04*\x1aA\x20When\x20false,\x20`get_`\x20is\x20\ + not\x20generated\x20even\x20if\x20`syntax\x20=\x20\"proto2\"`\n\n\n\n\ + \x03\x07\x07\x02\x12\x03\x1c\x07%\n\n\n\x03\x07\x07\x04\x12\x03\x20\x04\ + \x0c\n\n\n\x03\x07\x07\x05\x12\x03\x20\r\x11\n\n\n\x03\x07\x07\x01\x12\ + \x03\x20\x12!\n\n\n\x03\x07\x07\x03\x12\x03\x20$)\n2\n\x02\x07\x08\x12\ + \x03\"\x04&\x1a'\x20Use\x20`bytes::Bytes`\x20for\x20`bytes`\x20fields\n\ + \n\n\n\x03\x07\x08\x02\x12\x03\x1c\x07%\n\n\n\x03\x07\x08\x04\x12\x03\"\ + \x04\x0c\n\n\n\x03\x07\x08\x05\x12\x03\"\r\x11\n\n\n\x03\x07\x08\x01\x12\ + \x03\"\x12\x1d\n\n\n\x03\x07\x08\x03\x12\x03\"\x20%\n3\n\x02\x07\t\x12\ + \x03$\x041\x1a(\x20Use\x20`bytes::Bytes`\x20for\x20`string`\x20fields\n\ + \n\n\n\x03\x07\t\x02\x12\x03\x1c\x07%\n\n\n\x03\x07\t\x04\x12\x03$\x04\ + \x0c\n\n\n\x03\x07\t\x05\x12\x03$\r\x11\n\n\n\x03\x07\t\x01\x12\x03$\x12\ + (\n\n\n\x03\x07\t\x03\x12\x03$+0\nQ\n\x02\x07\n\x12\x03&\x040\x1aF\x20Wh\ + en\x20false,\x20`#[non_exhaustive]`\x20is\x20not\x20generated\x20for\x20\ + `oneof`\x20fields.\n\n\n\n\x03\x07\n\x02\x12\x03\x1c\x07%\n\n\n\x03\x07\ + \n\x04\x12\x03&\x04\x0c\n\n\n\x03\x07\n\x05\x12\x03&\r\x11\n\n\n\x03\x07\ + \n\x01\x12\x03&\x12'\n\n\n\x03\x07\n\x03\x12\x03&*/\n\t\n\x01\x07\x12\ + \x04)\04\x01\nP\n\x02\x07\x0b\x12\x03+\x043\x1aE\x20When\x20false,\x20`g\ + et_`,\x20`set_`,\x20`mut_`\x20etc.\x20accessors\x20are\x20not\x20generat\ + ed\n\n\n\n\x03\x07\x0b\x02\x12\x03)\x07#\n\n\n\x03\x07\x0b\x04\x12\x03+\ + \x04\x0c\n\n\n\x03\x07\x0b\x05\x12\x03+\r\x11\n\n\n\x03\x07\x0b\x01\x12\ + \x03+\x12*\n\n\n\x03\x07\x0b\x03\x12\x03+-2\nL\n\x02\x07\x0c\x12\x03-\ + \x040\x1aA\x20When\x20false,\x20`get_`\x20is\x20not\x20generated\x20even\ + \x20if\x20`syntax\x20=\x20\"proto2\"`\n\n\n\n\x03\x07\x0c\x02\x12\x03)\ + \x07#\n\n\n\x03\x07\x0c\x04\x12\x03-\x04\x0c\n\n\n\x03\x07\x0c\x05\x12\ + \x03-\r\x11\n\n\n\x03\x07\x0c\x01\x12\x03-\x12'\n\n\n\x03\x07\x0c\x03\ + \x12\x03-*/\n2\n\x02\x07\r\x12\x03/\x04,\x1a'\x20Use\x20`bytes::Bytes`\ + \x20for\x20`bytes`\x20fields\n\n\n\n\x03\x07\r\x02\x12\x03)\x07#\n\n\n\ + \x03\x07\r\x04\x12\x03/\x04\x0c\n\n\n\x03\x07\r\x05\x12\x03/\r\x11\n\n\n\ + \x03\x07\r\x01\x12\x03/\x12#\n\n\n\x03\x07\r\x03\x12\x03/&+\n3\n\x02\x07\ + \x0e\x12\x031\x047\x1a(\x20Use\x20`bytes::Bytes`\x20for\x20`string`\x20f\ + ields\n\n\n\n\x03\x07\x0e\x02\x12\x03)\x07#\n\n\n\x03\x07\x0e\x04\x12\ + \x031\x04\x0c\n\n\n\x03\x07\x0e\x05\x12\x031\r\x11\n\n\n\x03\x07\x0e\x01\ + \x12\x031\x12.\n\n\n\x03\x07\x0e\x03\x12\x03116\nQ\n\x02\x07\x0f\x12\x03\ + 3\x046\x1aF\x20When\x20false,\x20`#[non_exhaustive]`\x20is\x20not\x20gen\ + erated\x20for\x20`oneof`\x20fields.\n\n\n\n\x03\x07\x0f\x02\x12\x03)\x07\ + #\n\n\n\x03\x07\x0f\x04\x12\x033\x04\x0c\n\n\n\x03\x07\x0f\x05\x12\x033\ + \r\x11\n\n\n\x03\x07\x0f\x01\x12\x033\x12-\n\n\n\x03\x07\x0f\x03\x12\x03\ + 305\ "; /// `FileDescriptorProto` object which was a source for this generated file From d15e6d39df579ebed19bc801d3ea7677f6c80b98 Mon Sep 17 00:00:00 2001 From: Alex Konradi Date: Mon, 17 Jun 2024 14:03:56 -0400 Subject: [PATCH 2/2] Add test case for disabling #[non_exhaustive] --- .../src/common/v2/test_oneof_nonexhaustive.rs | 15 +++++++++++++++ .../common/v2/test_oneof_nonexhaustive_pb.proto | 14 ++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive.rs create mode 100644 test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive_pb.proto diff --git a/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive.rs b/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive.rs new file mode 100644 index 000000000..9353a53cc --- /dev/null +++ b/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive.rs @@ -0,0 +1,15 @@ +use protobuf::OneofFull; +use protobuf_test_common::*; + +use super::test_oneof_nonexhaustive_pb::*; + +#[test] +fn test_oneof_nonexhaustive_disabled() { + use message_with_oneof_nonexhaustive_disabled::One; + match MessageWithOneofNonexhaustiveDisabled::default().one { + None => (), + Some(one) => match one { + One::FirstField(_) | One::SecondField(_) => (), + }, + } +} diff --git a/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive_pb.proto b/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive_pb.proto new file mode 100644 index 000000000..8afde37e9 --- /dev/null +++ b/test-crates/protobuf-codegen-protoc-test/src/common/v2/test_oneof_nonexhaustive_pb.proto @@ -0,0 +1,14 @@ +syntax = "proto2"; + +import "rustproto.proto"; + +package test_oneof; + +message MessageWithOneofNonexhaustiveDisabled{ + option (rustproto.oneofs_non_exhaustive) = false; + + oneof one { + uint32 first_field = 1; + string second_field = 2; + } +}