From f3613fe5970ebad9706e8439ec7723d7a0e51467 Mon Sep 17 00:00:00 2001 From: Geoffry Song Date: Fri, 20 Oct 2023 01:35:15 -0700 Subject: [PATCH] Use r# syntax for keywords instead of appending _ This is more faithful to the input and guarantees that there can't be a collision. Also included is a fix for reflection since the munged names shouldn't be used at runtime. This also adds a couple missing keywords from Rust 2018. --- pb-jelly-gen/codegen/codegen.py | 178 +++++----- .../pb-jelly/proto_pbtest/src/lib.rs.expected | 1 + .../proto_pbtest/src/mod/mod.rs.expected | 3 + .../proto_pbtest/src/mod/struct.rs.expected | 61 ++++ .../proto_pbtest/src/pbtest2.rs.expected | 112 +++---- .../proto_pbtest/src/pbtest3.rs.expected | 316 ++++++++++++++++++ .../proto/packages/pbtest/mod/struct.proto | 5 + pb-test/proto/packages/pbtest/pbtest3.proto | 16 + pb-test/src/pbtest.rs | 6 +- pb-test/src/verify_generated_files.rs | 2 +- 10 files changed, 565 insertions(+), 135 deletions(-) create mode 100644 pb-test/gen/pb-jelly/proto_pbtest/src/mod/mod.rs.expected create mode 100644 pb-test/gen/pb-jelly/proto_pbtest/src/mod/struct.rs.expected create mode 100644 pb-test/proto/packages/pbtest/mod/struct.proto diff --git a/pb-jelly-gen/codegen/codegen.py b/pb-jelly-gen/codegen/codegen.py index 08275a3..0329edf 100755 --- a/pb-jelly-gen/codegen/codegen.py +++ b/pb-jelly-gen/codegen/codegen.py @@ -63,15 +63,25 @@ # Keywords in rust which cannot be module names. RESERVED_KEYWORDS = { + "Self", + "abstract", + "alignof", "as", + "async", + "await", + "become", + "box", "break", "const", "continue", "crate", + "do", + "dyn", "else", "enum", "extern", "false", + "final", "fn", "for", "if", @@ -79,44 +89,44 @@ "in", "let", "loop", + "macro", "match", "mod", "move", "mut", + "offsetof", + "override", + "priv", + "proc", "pub", + "pure", "ref", "return", - "Self", "self", + "sizeof", "static", "struct", "super", "trait", "true", "type", + "typeof", "unsafe", + "unsized", "use", + "virtual", "where", "while", - "abstract", - "alignof", - "become", - "box", - "do", - "final", - "macro", - "offsetof", - "override", - "priv", - "proc", - "pure", - "sizeof", - "typeof", - "unsized", - "virtual", "yield", } + +def escape_name(s: str) -> str: + if s in RESERVED_KEYWORDS: + return "r#" + s + return s + + # SourceCodeLocation is defined by `message Location` here # https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto SourceCodeLocation = List[int] @@ -381,7 +391,7 @@ def take_method(self) -> Tuple[Optional[Text], Optional[Text]]: if not self.field.type in has_take_method: return None, None - expr = "self.%s.take().unwrap_or_default()" % self.field.name + expr = "self.%s.take().unwrap_or_default()" % escape_name(self.field.name) if self.field.type == FieldDescriptorProto.TYPE_STRING: if self.is_small_string_optimization(): @@ -408,7 +418,7 @@ def take_method(self) -> Tuple[Optional[Text], Optional[Text]]: def get_method(self) -> Tuple[Text, Text]: assert not self.is_repeated() - name = self.field.name + name = escape_name(self.field.name) if self.field.type == FieldDescriptorProto.TYPE_FLOAT: return "f32", "self.%s.unwrap_or(0.)" % name @@ -574,7 +584,7 @@ def field_iter( with block( ctx, "if let %s = self.%s" - % (typ.oneof_val(msg_name, "ref " + var), typ.oneof.name), + % (typ.oneof_val(msg_name, "ref " + var), escape_name(typ.oneof.name)), ): if typ.is_empty_oneof_field(): ctx.write( @@ -595,7 +605,7 @@ def field_iter( # Always emit messages explicitly marked as non-nullable deref = "*" if typ.is_boxed() else "" with block(ctx, ""): - ctx.write("let %s = &%sself.%s;" % (var, deref, field.name)) + ctx.write("let %s = &%sself.%s;" % (var, deref, escape_name(field.name))) yield elif ( field.type == FieldDescriptorProto.TYPE_ENUM @@ -605,7 +615,7 @@ def field_iter( # The default value (as considered by proto) doesn't appear in the generated enum and # doesn't map to .default(). All of the values that actually get generated need to get # encoded. - ctx.write("let %s = &self.%s;" % (var, field.name)) + ctx.write("let %s = &self.%s;" % (var, escape_name(field.name))) yield elif not typ.is_nullable() and not typ.is_repeated(): # For proto3, we remove the Option for primitive fields. @@ -614,16 +624,16 @@ def field_iter( with block( ctx, "if self.%s != <%s as ::std::default::Default>::default()" - % (field.name, typ.storage_type()), + % (escape_name(field.name), typ.storage_type()), ): if typ.is_boxed(): - ctx.write("let %s = &*self.%s;" % (var, field.name)) + ctx.write("let %s = &*self.%s;" % (var, escape_name(field.name))) else: - ctx.write("let %s = &self.%s;" % (var, field.name)) + ctx.write("let %s = &self.%s;" % (var, escape_name(field.name))) yield else: # This iterates through Vec and the Option<> type for optional fieldds - with block(ctx, "for %s in &self.%s" % (var, field.name)): + with block(ctx, "for %s in &self.%s" % (var, escape_name(field.name))): if typ.is_boxed(): ctx.write("let %s = &**%s;" % (var, var)) yield @@ -895,14 +905,7 @@ def gen_msg( ) -> None: assert self.indentation == 0 name = "_".join(path + [msg_type.name]) - - # Adjust some field names - for field in msg_type.field: - if field.name in RESERVED_KEYWORDS: - field.name = field.name + "_" - for oneof in msg_type.oneof_decl: - if oneof.name in RESERVED_KEYWORDS: - oneof.name = oneof.name + "_" + escaped_name = escape_name(name) oneof_fields: DefaultDict[Text, List[FieldDescriptorProto]] = defaultdict(list) proto3_optional_synthetic_oneofs: Set[int] = { @@ -928,7 +931,7 @@ def gen_msg( self.write_comments(self.source_code_info_by_scl.get(tuple(scl))) self.write("#[derive(%s)]" % ", ".join(sorted(derives))) - with block(self, "pub struct " + name): + with block(self, "pub struct " + escaped_name): for idx, field in enumerate(msg_type.field): ffn = DescriptorProto.FIELD_FIELD_NUMBER self.write_comments( @@ -939,17 +942,20 @@ def gen_msg( if typ.oneof: oneof_fields[typ.oneof.name].append(field) else: - self.write("pub %s: %s," % (field.name, typ.storage_type())) + self.write( + "pub %s: %s," % (escape_name(field.name), typ.storage_type()) + ) for oneof in oneof_decls: if oneof_nullable(oneof): self.write( "pub %s: ::std::option::Option<%s>," - % (oneof.name, oneof_msg_name(name, oneof)) + % (escape_name(oneof.name), oneof_msg_name(name, oneof)) ) else: self.write( - "pub %s: %s," % (oneof.name, oneof_msg_name(name, oneof)) + "pub %s: %s," + % (escape_name(oneof.name), oneof_msg_name(name, oneof)) ) if msg_type.options.Extensions[extensions_pb2.preserve_unrecognized]: @@ -964,7 +970,7 @@ def gen_msg( self.write("%s," % typ.oneof_field_match(typ.storage_type())) if not self.is_proto3: - with block(self, "impl " + name): + with block(self, "impl " + escaped_name): for field in msg_type.field: typ = self.rust_type(msg_type, field) if typ.oneof: @@ -975,21 +981,24 @@ def gen_msg( "pub fn set_%s(&mut self, v: ::std::vec::Vec<%s>)" % (field.name, typ.rust_type()), ): - self.write("self.%s = v;" % field.name) + self.write("self.%s = v;" % escape_name(field.name)) with block( self, "pub fn take_%s(&mut self) -> ::std::vec::Vec<%s>" % (field.name, typ.rust_type()), ): - self.write("::std::mem::take(&mut self.%s)" % field.name) + self.write( + "::std::mem::take(&mut self.%s)" + % escape_name(field.name) + ) with block( self, "pub fn get_%s(&self) -> &[%s]" % (field.name, typ.rust_type()), ): - self.write("&self.%s" % field.name) + self.write("&self.%s" % escape_name(field.name)) with block( self, @@ -1000,7 +1009,7 @@ def gen_msg( elif typ.is_nullable(): with block(self, "pub fn has_%s(&self) -> bool" % field.name): - self.write("self.%s.is_some()" % field.name) + self.write("self.%s.is_some()" % escape_name(field.name)) input_type, input_expr = typ.set_method() with block( @@ -1008,7 +1017,10 @@ def gen_msg( "pub fn set_%s(&mut self, v: %s)" % (field.name, input_type), ): - self.write("self.%s = Some(%s);" % (field.name, input_expr)) + self.write( + "self.%s = Some(%s);" + % (escape_name(field.name), input_expr) + ) return_type, return_expr = typ.take_method() if return_type is not None and return_expr is not None: @@ -1031,17 +1043,21 @@ def gen_msg( ): self.write(return_expr) - with block(self, "impl ::std::default::Default for " + name): + with block(self, "impl ::std::default::Default for " + escaped_name): with block(self, "fn default() -> Self"): - with block(self, name): + with block(self, escaped_name): for field in msg_type.field: typ = self.rust_type(msg_type, field) if not typ.oneof: - self.write("%s: %s," % (field.name, typ.default(name))) + self.write( + "%s: %s," % (escape_name(field.name), typ.default(name)) + ) for oneof in oneof_decls: oneof_field = oneof_fields[oneof.name][0] typ = self.rust_type(msg_type, oneof_field) - self.write("%s: %s," % (oneof.name, typ.default(name))) + self.write( + "%s: %s," % (escape_name(oneof.name), typ.default(name)) + ) if msg_type.options.Extensions[ extensions_pb2.preserve_unrecognized ]: @@ -1049,10 +1065,11 @@ def gen_msg( with block(self, "lazy_static!"): self.write( - "pub static ref %s_default: %s = %s::default();" % (name, name, name) + "pub static ref %s_default: %s = %s::default();" + % (name, escaped_name, escaped_name) ) - with block(self, "impl ::pb_jelly::Message for " + name): + with block(self, "impl ::pb_jelly::Message for " + escaped_name): with block( self, "fn descriptor(&self) -> ::std::option::Option<::pb_jelly::MessageDescriptor>", @@ -1186,7 +1203,9 @@ def gen_msg( # In proto2, this ensures we don't emit fields set to None # In proto3, this ensures we don't emit fields set to their default value if typ.should_serialize_packed(): - with block(self, "if !self.%s.is_empty()" % field.name): + with block( + self, "if !self.%s.is_empty()" % escape_name(field.name) + ): self.write("let mut size = 0;") with field_iter(self, "val", name, msg_type, field): self.write( @@ -1244,7 +1263,7 @@ def gen_msg( if enum_err_if_default_or_unknown(enum_type) and not typ.oneof: self.write( "let mut %s: ::std::option::Option<%s> = None;" - % (field.name, typ.rust_type()) + % (escape_name(field.name), typ.rust_type()) ) err_if_default_field_names[field.name] = None @@ -1279,7 +1298,8 @@ def gen_msg( "::pb_jelly::Message::deserialize(&mut val, &mut vals)?;" ) self.write( - "self.%s.push(val);" % field.name + "self.%s.push(val);" + % escape_name(field.name) ) with block(self, "_ =>"): self.write( @@ -1333,7 +1353,10 @@ def gen_msg( ) if typ.is_repeated(): - self.write("self.%s.push(val);" % field.name) + self.write( + "self.%s.push(val);" + % escape_name(field.name) + ) else: field_val = ( "Box::new(val)" if typ.is_boxed() else "val" @@ -1344,7 +1367,7 @@ def gen_msg( self.write( "self.%s = %s;" % ( - typ.oneof.name, + escape_name(typ.oneof.name), typ.oneof_val(name, field_val), ) ) @@ -1359,17 +1382,17 @@ def gen_msg( elif typ.is_nullable(): self.write( "self.%s = Some(%s);" - % (field.name, field_val) + % (escape_name(field.name), field_val) ) elif field.name in err_if_default_field_names: self.write( "%s = Some(%s);" - % (field.name, field_val) + % (escape_name(field.name), field_val) ) else: self.write( "self.%s = %s;" - % (field.name, field_val) + % (escape_name(field.name), field_val) ) with block(self, "_ =>"): if preserve_unrecognized: @@ -1381,15 +1404,17 @@ def gen_msg( for oneof in oneof_decls: if not oneof_nullable(oneof): with block(self, "match oneof_" + oneof.name): - self.write("Some(v) => self.%s = v," % oneof.name) + self.write( + "Some(v) => self.%s = v," % escape_name(oneof.name) + ) self.write( "None => return Err(::std::io::Error::new(::std::io::ErrorKind::InvalidInput, \"missing value for non-nullable oneof '%s' while parsing message %s.%s\"))," % (oneof.name, self.proto_file.package, msg_type.name) ) for field_name in err_if_default_field_names: - with block(self, "match " + field_name): - self.write("Some(v) => self.%s = v," % field_name) + with block(self, "match %s" % escape_name(field_name)): + self.write("Some(v) => self.%s = v," % escape_name(field_name)) self.write( "None => return Err(::std::io::Error::new(::std::io::ErrorKind::InvalidInput, \"err_if_default_or_unknown '%s' had no value while parsing message %s.%s\"))," % (field_name, self.proto_file.package, msg_type.name) @@ -1433,7 +1458,10 @@ def gen_msg( ) > 1 or oneof_nullable(typ.oneof): # Only useful to generate this logic if there is more than one # possible value for this oneof. - with block(self, "match self.%s" % typ.oneof.name): + with block( + self, + "match self.%s" % escape_name(typ.oneof.name), + ): self.write( "%s => ()," % typ.oneof_val(name, "_") ) @@ -1443,7 +1471,7 @@ def gen_msg( self.write( "self.%s = %s;" % ( - typ.oneof.name, + escape_name(typ.oneof.name), typ.oneof_val( name, "::std::default::Default::default()", @@ -1460,7 +1488,7 @@ def gen_msg( "if let %s = self.%s" % ( typ.oneof_val(name, "ref mut val"), - typ.oneof.name, + escape_name(typ.oneof.name), ), ): if typ.is_boxed(): @@ -1479,22 +1507,22 @@ def gen_msg( elif typ.is_nullable() and typ.is_boxed(): self.write( "::pb_jelly::reflection::FieldMut::Value(self.%s.get_or_insert_with(::std::default::Default::default).as_mut())" - % field.name + % escape_name(field.name) ) elif typ.is_boxed(): self.write( "::pb_jelly::reflection::FieldMut::Value(self.%s.as_mut())" - % field.name + % escape_name(field.name) ) elif typ.is_nullable(): self.write( "::pb_jelly::reflection::FieldMut::Value(self.%s.get_or_insert_with(::std::default::Default::default))" - % field.name + % escape_name(field.name) ) else: self.write( "::pb_jelly::reflection::FieldMut::Value(&mut self.%s)" - % field.name + % escape_name(field.name) ) with block(self, "_ =>"): self.write('panic!("unknown field name given")') @@ -1566,6 +1594,7 @@ def rust_name(self, other_crate: Text, other_mod_parts: List[Text]) -> Text: return "_".join(self.path + [self.typ.name]) mod_parts = self.mod_parts + ["_".join(self.path + [self.typ.name])] + mod_parts = [escape_name(part) for part in mod_parts] if other_crate != self.crate: # Different crate. Insert crate name in fully qualified module. mod_parts.insert(0, "::" + self.crate) @@ -1782,7 +1811,10 @@ def mod_tree_dfs( filename = mod_prefix_path + "/mod.rs" content = "\n".join( ["// @" + "generated, do not edit", ""] - + ["pub mod %s;" % mod for mod in sorted(sub_mod_tree.keys())] + + [ + "pub mod %s;" % escape_name(mod) + for mod in sorted(sub_mod_tree.keys()) + ] + [""] ) yield filename, content @@ -1795,7 +1827,7 @@ def mod_tree_dfs( crate_mod_tree: ModTree = mod_tree[crate] for mod_name, child_mod_tree in sorted(crate_mod_tree.items()): - librs.write("pub mod %s;" % mod_name) + librs.write("pub mod %s;" % escape_name(mod_name)) for res in mod_tree_dfs(crate + "/src/" + mod_name, child_mod_tree): yield res @@ -1886,11 +1918,7 @@ def crate_from_proto_filename( filename = proto_filename.replace(self.prefix_to_clear, "").replace( ".proto", "" ) - mod_parts_unsanitized = filename.split("/") - mod_parts = [ - mod + "_" if mod in RESERVED_KEYWORDS else mod - for mod in mod_parts_unsanitized - ] + mod_parts = filename.split("/") # Each proto module will become its own crate. We append "_proto" to the crate name # to disambiguate the top level crate names. if self.crate_per_dir: diff --git a/pb-test/gen/pb-jelly/proto_pbtest/src/lib.rs.expected b/pb-test/gen/pb-jelly/proto_pbtest/src/lib.rs.expected index aebfc6f..a6f5407 100644 --- a/pb-test/gen/pb-jelly/proto_pbtest/src/lib.rs.expected +++ b/pb-test/gen/pb-jelly/proto_pbtest/src/lib.rs.expected @@ -25,6 +25,7 @@ extern crate lazy_static; pub mod bench; +pub mod r#mod; pub mod pbtest2; pub mod pbtest3; pub mod servicepb; diff --git a/pb-test/gen/pb-jelly/proto_pbtest/src/mod/mod.rs.expected b/pb-test/gen/pb-jelly/proto_pbtest/src/mod/mod.rs.expected new file mode 100644 index 0000000..31adfb7 --- /dev/null +++ b/pb-test/gen/pb-jelly/proto_pbtest/src/mod/mod.rs.expected @@ -0,0 +1,3 @@ +// @generated, do not edit + +pub mod r#struct; diff --git a/pb-test/gen/pb-jelly/proto_pbtest/src/mod/struct.rs.expected b/pb-test/gen/pb-jelly/proto_pbtest/src/mod/struct.rs.expected new file mode 100644 index 0000000..e8b133e --- /dev/null +++ b/pb-test/gen/pb-jelly/proto_pbtest/src/mod/struct.rs.expected @@ -0,0 +1,61 @@ +// @generated, do not edit +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Message { +} +impl ::std::default::Default for Message { + fn default() -> Self { + Message { + } + } +} +lazy_static! { + pub static ref Message_default: Message = Message::default(); +} +impl ::pb_jelly::Message for Message { + fn descriptor(&self) -> ::std::option::Option<::pb_jelly::MessageDescriptor> { + Some(::pb_jelly::MessageDescriptor { + name: "Message", + full_name: "pbtest.mod.Message", + fields: &[ + ], + oneofs: &[ + ], + }) + } + fn compute_size(&self) -> usize { + 0 + } + fn compute_grpc_slices_size(&self) -> usize { + 0 + } + fn serialize(&self, w: &mut W) -> ::std::io::Result<()> { + Ok(()) + } + fn deserialize(&mut self, mut buf: &mut B) -> ::std::io::Result<()> { + while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? { + match field_number { + _ => { + ::pb_jelly::skip(typ, &mut buf)?; + } + } + } + Ok(()) + } +} +impl ::pb_jelly::Reflection for Message { + fn which_one_of(&self, oneof_name: &str) -> ::std::option::Option<&'static str> { + match oneof_name { + _ => { + panic!("unknown oneof name given"); + } + } + } + fn get_field_mut(&mut self, field_name: &str) -> ::pb_jelly::reflection::FieldMut<'_> { + match field_name { + _ => { + panic!("unknown field name given") + } + } + } +} + diff --git a/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest2.rs.expected b/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest2.rs.expected index 8f31405..f5a7549 100644 --- a/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest2.rs.expected +++ b/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest2.rs.expected @@ -2685,7 +2685,7 @@ pub struct TestMessage { pub optional_foreign_message_boxed: ::std::option::Option<::std::boxed::Box>, pub optional_foreign_message_nonnullable: ForeignMessage, /// Use some rust reserved keywords - pub type_: ::std::option::Option, + pub r#type: ::std::option::Option, pub oneof_int: ::std::option::Option, pub oneof_foreign: ::std::option::Option, pub oneof_zero: ::std::option::Option, @@ -2693,7 +2693,7 @@ pub struct TestMessage { pub oneof_unset: ::std::option::Option, pub oneof_primitives: ::std::option::Option, pub oneof_empty_field: TestMessage_OneofEmptyField, - pub mod_: ::std::option::Option, + pub r#mod: ::std::option::Option, } #[derive(Clone, Debug, PartialEq)] pub enum TestMessage_OneofInt { @@ -3094,14 +3094,14 @@ impl TestMessage { pub fn get_optional_foreign_message_boxed(&self) -> &ForeignMessage { self.optional_foreign_message_boxed.as_ref().map(::std::ops::Deref::deref).unwrap_or(&ForeignMessage_default) } - pub fn has_type_(&self) -> bool { - self.type_.is_some() + pub fn has_type(&self) -> bool { + self.r#type.is_some() } - pub fn set_type_(&mut self, v: bool) { - self.type_ = Some(v); + pub fn set_type(&mut self, v: bool) { + self.r#type = Some(v); } - pub fn get_type_(&self) -> bool { - self.type_.unwrap_or(false) + pub fn get_type(&self) -> bool { + self.r#type.unwrap_or(false) } } impl ::std::default::Default for TestMessage { @@ -3141,7 +3141,7 @@ impl ::std::default::Default for TestMessage { repeated_foreign_enum: ::std::default::Default::default(), optional_foreign_message_boxed: ::std::default::Default::default(), optional_foreign_message_nonnullable: ::std::default::Default::default(), - type_: ::std::default::Default::default(), + r#type: ::std::default::Default::default(), oneof_int: None, oneof_foreign: None, oneof_zero: None, @@ -3149,7 +3149,7 @@ impl ::std::default::Default for TestMessage { oneof_unset: None, oneof_primitives: None, oneof_empty_field: TestMessage_OneofEmptyField::A, - mod_: None, + r#mod: None, } } } @@ -3604,8 +3604,8 @@ impl ::pb_jelly::Message for TestMessage { oneof_index: Some(6), }, ::pb_jelly::FieldDescriptor { - name: "type_", - full_name: "pbtest.TestMessage.type_", + name: "type", + full_name: "pbtest.TestMessage.type", index: 49, number: 73, typ: ::pb_jelly::wire_format::Type::Varint, @@ -3613,8 +3613,8 @@ impl ::pb_jelly::Message for TestMessage { oneof_index: None, }, ::pb_jelly::FieldDescriptor { - name: "loop_", - full_name: "pbtest.TestMessage.loop_", + name: "loop", + full_name: "pbtest.TestMessage.loop", index: 50, number: 74, typ: ::pb_jelly::wire_format::Type::Varint, @@ -3622,8 +3622,8 @@ impl ::pb_jelly::Message for TestMessage { oneof_index: Some(7), }, ::pb_jelly::FieldDescriptor { - name: "unsafe_", - full_name: "pbtest.TestMessage.unsafe_", + name: "unsafe", + full_name: "pbtest.TestMessage.unsafe", index: 51, number: 75, typ: ::pb_jelly::wire_format::Type::Varint, @@ -3654,7 +3654,7 @@ impl ::pb_jelly::Message for TestMessage { name: "oneof_empty_field", }, ::pb_jelly::OneofDescriptor { - name: "mod_", + name: "mod", }, ], }) @@ -4023,27 +4023,27 @@ impl ::pb_jelly::Message for TestMessage { c_size += l; } size += c_size; - let mut type__size = 0; - for val in &self.type_ { + let mut type_size = 0; + for val in &self.r#type { let l = ::pb_jelly::Message::compute_size(val); - type__size += ::pb_jelly::wire_format::serialized_length(73); - type__size += l; + type_size += ::pb_jelly::wire_format::serialized_length(73); + type_size += l; } - size += type__size; - let mut loop__size = 0; - if let Some(TestMessage_Mod::Loop(ref val)) = self.mod_ { + size += type_size; + let mut loop_size = 0; + if let Some(TestMessage_Mod::Loop(ref val)) = self.r#mod { let l = ::pb_jelly::Message::compute_size(val); - loop__size += ::pb_jelly::wire_format::serialized_length(74); - loop__size += l; + loop_size += ::pb_jelly::wire_format::serialized_length(74); + loop_size += l; } - size += loop__size; - let mut unsafe__size = 0; - if let Some(TestMessage_Mod::Unsafe(ref val)) = self.mod_ { + size += loop_size; + let mut unsafe_size = 0; + if let Some(TestMessage_Mod::Unsafe(ref val)) = self.r#mod { let l = ::pb_jelly::Message::compute_size(val); - unsafe__size += ::pb_jelly::wire_format::serialized_length(75); - unsafe__size += l; + unsafe_size += ::pb_jelly::wire_format::serialized_length(75); + unsafe_size += l; } - size += unsafe__size; + size += unsafe_size; size } fn compute_grpc_slices_size(&self) -> usize { @@ -4199,13 +4199,13 @@ impl ::pb_jelly::Message for TestMessage { if let TestMessage_OneofEmptyField::C(ref val) = self.oneof_empty_field { size += ::pb_jelly::Message::compute_grpc_slices_size(val); } - for val in &self.type_ { + for val in &self.r#type { size += ::pb_jelly::Message::compute_grpc_slices_size(val); } - if let Some(TestMessage_Mod::Loop(ref val)) = self.mod_ { + if let Some(TestMessage_Mod::Loop(ref val)) = self.r#mod { size += ::pb_jelly::Message::compute_grpc_slices_size(val); } - if let Some(TestMessage_Mod::Unsafe(ref val)) = self.mod_ { + if let Some(TestMessage_Mod::Unsafe(ref val)) = self.r#mod { size += ::pb_jelly::Message::compute_grpc_slices_size(val); } size @@ -4441,15 +4441,15 @@ impl ::pb_jelly::Message for TestMessage { ::pb_jelly::wire_format::write(72, ::pb_jelly::wire_format::Type::Varint, w)?; ::pb_jelly::Message::serialize(val, w)?; } - for val in &self.type_ { + for val in &self.r#type { ::pb_jelly::wire_format::write(73, ::pb_jelly::wire_format::Type::Varint, w)?; ::pb_jelly::Message::serialize(val, w)?; } - if let Some(TestMessage_Mod::Loop(ref val)) = self.mod_ { + if let Some(TestMessage_Mod::Loop(ref val)) = self.r#mod { ::pb_jelly::wire_format::write(74, ::pb_jelly::wire_format::Type::Varint, w)?; ::pb_jelly::Message::serialize(val, w)?; } - if let Some(TestMessage_Mod::Unsafe(ref val)) = self.mod_ { + if let Some(TestMessage_Mod::Unsafe(ref val)) = self.r#mod { ::pb_jelly::wire_format::write(75, ::pb_jelly::wire_format::Type::Varint, w)?; ::pb_jelly::Message::serialize(val, w)?; } @@ -4956,19 +4956,19 @@ impl ::pb_jelly::Message for TestMessage { ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::Varint, "TestMessage", 73)?; let mut val: bool = ::std::default::Default::default(); ::pb_jelly::Message::deserialize(&mut val, buf)?; - self.type_ = Some(val); + self.r#type = Some(val); } 74 => { ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::Varint, "TestMessage", 74)?; let mut val: i32 = ::std::default::Default::default(); ::pb_jelly::Message::deserialize(&mut val, buf)?; - self.mod_ = Some(TestMessage_Mod::Loop(val)); + self.r#mod = Some(TestMessage_Mod::Loop(val)); } 75 => { ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::Varint, "TestMessage", 75)?; let mut val: i32 = ::std::default::Default::default(); ::pb_jelly::Message::deserialize(&mut val, buf)?; - self.mod_ = Some(TestMessage_Mod::Unsafe(val)); + self.r#mod = Some(TestMessage_Mod::Unsafe(val)); } _ => { ::pb_jelly::skip(typ, &mut buf)?; @@ -5053,12 +5053,12 @@ impl ::pb_jelly::Reflection for TestMessage { } None } - "mod_" => { - if let Some(TestMessage_Mod::Loop(ref val)) = self.mod_ { - return Some("loop_"); + "mod" => { + if let Some(TestMessage_Mod::Loop(ref val)) = self.r#mod { + return Some("loop"); } - if let Some(TestMessage_Mod::Unsafe(ref val)) = self.mod_ { - return Some("unsafe_"); + if let Some(TestMessage_Mod::Unsafe(ref val)) = self.r#mod { + return Some("unsafe"); } None } @@ -5345,29 +5345,29 @@ impl ::pb_jelly::Reflection for TestMessage { } unreachable!() } - "type_" => { - ::pb_jelly::reflection::FieldMut::Value(self.type_.get_or_insert_with(::std::default::Default::default)) + "type" => { + ::pb_jelly::reflection::FieldMut::Value(self.r#type.get_or_insert_with(::std::default::Default::default)) } - "loop_" => { - match self.mod_ { + "loop" => { + match self.r#mod { Some(TestMessage_Mod::Loop(_)) => (), _ => { - self.mod_ = Some(TestMessage_Mod::Loop(::std::default::Default::default())); + self.r#mod = Some(TestMessage_Mod::Loop(::std::default::Default::default())); }, } - if let Some(TestMessage_Mod::Loop(ref mut val)) = self.mod_ { + if let Some(TestMessage_Mod::Loop(ref mut val)) = self.r#mod { return ::pb_jelly::reflection::FieldMut::Value(val); } unreachable!() } - "unsafe_" => { - match self.mod_ { + "unsafe" => { + match self.r#mod { Some(TestMessage_Mod::Unsafe(_)) => (), _ => { - self.mod_ = Some(TestMessage_Mod::Unsafe(::std::default::Default::default())); + self.r#mod = Some(TestMessage_Mod::Unsafe(::std::default::Default::default())); }, } - if let Some(TestMessage_Mod::Unsafe(ref mut val)) = self.mod_ { + if let Some(TestMessage_Mod::Unsafe(ref mut val)) = self.r#mod { return ::pb_jelly::reflection::FieldMut::Value(val); } unreachable!() diff --git a/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest3.rs.expected b/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest3.rs.expected index d643a03..4a80285 100644 --- a/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest3.rs.expected +++ b/pb-test/gen/pb-jelly/proto_pbtest/src/pbtest3.rs.expected @@ -9374,3 +9374,319 @@ impl ::pb_jelly::Reflection for RecursiveOneof { } } +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct MentionsKeywordPath { + pub message: ::std::option::Option, +} +impl ::std::default::Default for MentionsKeywordPath { + fn default() -> Self { + MentionsKeywordPath { + message: ::std::default::Default::default(), + } + } +} +lazy_static! { + pub static ref MentionsKeywordPath_default: MentionsKeywordPath = MentionsKeywordPath::default(); +} +impl ::pb_jelly::Message for MentionsKeywordPath { + fn descriptor(&self) -> ::std::option::Option<::pb_jelly::MessageDescriptor> { + Some(::pb_jelly::MessageDescriptor { + name: "MentionsKeywordPath", + full_name: "pbtest.MentionsKeywordPath", + fields: &[ + ::pb_jelly::FieldDescriptor { + name: "message", + full_name: "pbtest.MentionsKeywordPath.message", + index: 0, + number: 1, + typ: ::pb_jelly::wire_format::Type::LengthDelimited, + label: ::pb_jelly::Label::Optional, + oneof_index: None, + }, + ], + oneofs: &[ + ], + }) + } + fn compute_size(&self) -> usize { + let mut size = 0; + let mut message_size = 0; + for val in &self.message { + let l = ::pb_jelly::Message::compute_size(val); + message_size += ::pb_jelly::wire_format::serialized_length(1); + message_size += ::pb_jelly::varint::serialized_length(l as u64); + message_size += l; + } + size += message_size; + size + } + fn compute_grpc_slices_size(&self) -> usize { + let mut size = 0; + for val in &self.message { + size += ::pb_jelly::Message::compute_grpc_slices_size(val); + } + size + } + fn serialize(&self, w: &mut W) -> ::std::io::Result<()> { + for val in &self.message { + ::pb_jelly::wire_format::write(1, ::pb_jelly::wire_format::Type::LengthDelimited, w)?; + let l = ::pb_jelly::Message::compute_size(val); + ::pb_jelly::varint::write(l as u64, w)?; + ::pb_jelly::Message::serialize(val, w)?; + } + Ok(()) + } + fn deserialize(&mut self, mut buf: &mut B) -> ::std::io::Result<()> { + while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? { + match field_number { + 1 => { + ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::LengthDelimited, "MentionsKeywordPath", 1)?; + let len = ::pb_jelly::varint::ensure_read(&mut buf)?; + let mut next = ::pb_jelly::ensure_split(buf, len as usize)?; + let mut val: super::r#mod::r#struct::Message = ::std::default::Default::default(); + ::pb_jelly::Message::deserialize(&mut val, &mut next)?; + self.message = Some(val); + } + _ => { + ::pb_jelly::skip(typ, &mut buf)?; + } + } + } + Ok(()) + } +} +impl ::pb_jelly::Reflection for MentionsKeywordPath { + fn which_one_of(&self, oneof_name: &str) -> ::std::option::Option<&'static str> { + match oneof_name { + _ => { + panic!("unknown oneof name given"); + } + } + } + fn get_field_mut(&mut self, field_name: &str) -> ::pb_jelly::reflection::FieldMut<'_> { + match field_name { + "message" => { + ::pb_jelly::reflection::FieldMut::Value(self.message.get_or_insert_with(::std::default::Default::default)) + } + _ => { + panic!("unknown field name given") + } + } + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct NonNullableOneofKeyword { + pub r#async: NonNullableOneofKeyword_Async, +} +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum NonNullableOneofKeyword_Async { + A(i64), +} +impl ::std::default::Default for NonNullableOneofKeyword { + fn default() -> Self { + NonNullableOneofKeyword { + r#async: NonNullableOneofKeyword_Async::A(::std::default::Default::default()), + } + } +} +lazy_static! { + pub static ref NonNullableOneofKeyword_default: NonNullableOneofKeyword = NonNullableOneofKeyword::default(); +} +impl ::pb_jelly::Message for NonNullableOneofKeyword { + fn descriptor(&self) -> ::std::option::Option<::pb_jelly::MessageDescriptor> { + Some(::pb_jelly::MessageDescriptor { + name: "NonNullableOneofKeyword", + full_name: "pbtest.NonNullableOneofKeyword", + fields: &[ + ::pb_jelly::FieldDescriptor { + name: "a", + full_name: "pbtest.NonNullableOneofKeyword.a", + index: 0, + number: 1, + typ: ::pb_jelly::wire_format::Type::Varint, + label: ::pb_jelly::Label::Optional, + oneof_index: Some(0), + }, + ], + oneofs: &[ + ::pb_jelly::OneofDescriptor { + name: "async", + }, + ], + }) + } + fn compute_size(&self) -> usize { + let mut size = 0; + let mut a_size = 0; + if let NonNullableOneofKeyword_Async::A(ref val) = self.r#async { + let l = ::pb_jelly::Message::compute_size(val); + a_size += ::pb_jelly::wire_format::serialized_length(1); + a_size += l; + } + size += a_size; + size + } + fn compute_grpc_slices_size(&self) -> usize { + let mut size = 0; + if let NonNullableOneofKeyword_Async::A(ref val) = self.r#async { + size += ::pb_jelly::Message::compute_grpc_slices_size(val); + } + size + } + fn serialize(&self, w: &mut W) -> ::std::io::Result<()> { + if let NonNullableOneofKeyword_Async::A(ref val) = self.r#async { + ::pb_jelly::wire_format::write(1, ::pb_jelly::wire_format::Type::Varint, w)?; + ::pb_jelly::Message::serialize(val, w)?; + } + Ok(()) + } + fn deserialize(&mut self, mut buf: &mut B) -> ::std::io::Result<()> { + let mut oneof_async: ::std::option::Option = None; + while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? { + match field_number { + 1 => { + ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::Varint, "NonNullableOneofKeyword", 1)?; + let mut val: i64 = ::std::default::Default::default(); + ::pb_jelly::Message::deserialize(&mut val, buf)?; + oneof_async = Some(NonNullableOneofKeyword_Async::A(val)); + } + _ => { + ::pb_jelly::skip(typ, &mut buf)?; + } + } + } + match oneof_async { + Some(v) => self.r#async = v, + None => return Err(::std::io::Error::new(::std::io::ErrorKind::InvalidInput, "missing value for non-nullable oneof 'async' while parsing message pbtest.NonNullableOneofKeyword")), + } + Ok(()) + } +} +impl ::pb_jelly::Reflection for NonNullableOneofKeyword { + fn which_one_of(&self, oneof_name: &str) -> ::std::option::Option<&'static str> { + match oneof_name { + "async" => { + if let NonNullableOneofKeyword_Async::A(ref val) = self.r#async { + return Some("a"); + } + None + } + _ => { + panic!("unknown oneof name given"); + } + } + } + fn get_field_mut(&mut self, field_name: &str) -> ::pb_jelly::reflection::FieldMut<'_> { + match field_name { + "a" => { + if let NonNullableOneofKeyword_Async::A(ref mut val) = self.r#async { + return ::pb_jelly::reflection::FieldMut::Value(val); + } + unreachable!() + } + _ => { + panic!("unknown field name given") + } + } + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct NonNullableEnumKeyword { + pub r#enum: TestMessage3_NestedMessage_NonNullableEnum, +} +impl ::std::default::Default for NonNullableEnumKeyword { + fn default() -> Self { + NonNullableEnumKeyword { + r#enum: ::std::default::Default::default(), + } + } +} +lazy_static! { + pub static ref NonNullableEnumKeyword_default: NonNullableEnumKeyword = NonNullableEnumKeyword::default(); +} +impl ::pb_jelly::Message for NonNullableEnumKeyword { + fn descriptor(&self) -> ::std::option::Option<::pb_jelly::MessageDescriptor> { + Some(::pb_jelly::MessageDescriptor { + name: "NonNullableEnumKeyword", + full_name: "pbtest.NonNullableEnumKeyword", + fields: &[ + ::pb_jelly::FieldDescriptor { + name: "enum", + full_name: "pbtest.NonNullableEnumKeyword.enum", + index: 0, + number: 1, + typ: ::pb_jelly::wire_format::Type::Varint, + label: ::pb_jelly::Label::Optional, + oneof_index: None, + }, + ], + oneofs: &[ + ], + }) + } + fn compute_size(&self) -> usize { + let mut size = 0; + let mut enum_size = 0; + let val = &self.r#enum; + let l = ::pb_jelly::Message::compute_size(val); + enum_size += ::pb_jelly::wire_format::serialized_length(1); + enum_size += l; + size += enum_size; + size + } + fn compute_grpc_slices_size(&self) -> usize { + let mut size = 0; + let val = &self.r#enum; + size += ::pb_jelly::Message::compute_grpc_slices_size(val); + size + } + fn serialize(&self, w: &mut W) -> ::std::io::Result<()> { + let val = &self.r#enum; + ::pb_jelly::wire_format::write(1, ::pb_jelly::wire_format::Type::Varint, w)?; + ::pb_jelly::Message::serialize(val, w)?; + Ok(()) + } + fn deserialize(&mut self, mut buf: &mut B) -> ::std::io::Result<()> { + let mut r#enum: ::std::option::Option = None; + while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? { + match field_number { + 1 => { + ::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::Varint, "NonNullableEnumKeyword", 1)?; + let mut val: TestMessage3_NestedMessage_NonNullableEnum = ::std::default::Default::default(); + ::pb_jelly::Message::deserialize(&mut val, buf)?; + r#enum = Some(val); + } + _ => { + ::pb_jelly::skip(typ, &mut buf)?; + } + } + } + match r#enum { + Some(v) => self.r#enum = v, + None => return Err(::std::io::Error::new(::std::io::ErrorKind::InvalidInput, "err_if_default_or_unknown 'enum' had no value while parsing message pbtest.NonNullableEnumKeyword")), + } + Ok(()) + } +} +impl ::pb_jelly::Reflection for NonNullableEnumKeyword { + fn which_one_of(&self, oneof_name: &str) -> ::std::option::Option<&'static str> { + match oneof_name { + _ => { + panic!("unknown oneof name given"); + } + } + } + fn get_field_mut(&mut self, field_name: &str) -> ::pb_jelly::reflection::FieldMut<'_> { + match field_name { + "enum" => { + ::pb_jelly::reflection::FieldMut::Value(&mut self.r#enum) + } + _ => { + panic!("unknown field name given") + } + } + } +} + diff --git a/pb-test/proto/packages/pbtest/mod/struct.proto b/pb-test/proto/packages/pbtest/mod/struct.proto new file mode 100644 index 0000000..038067f --- /dev/null +++ b/pb-test/proto/packages/pbtest/mod/struct.proto @@ -0,0 +1,5 @@ +syntax="proto3"; + +package pbtest.mod; + +message Message {} \ No newline at end of file diff --git a/pb-test/proto/packages/pbtest/pbtest3.proto b/pb-test/proto/packages/pbtest/pbtest3.proto index 9ddfb98..39448fb 100644 --- a/pb-test/proto/packages/pbtest/pbtest3.proto +++ b/pb-test/proto/packages/pbtest/pbtest3.proto @@ -2,6 +2,7 @@ syntax="proto3"; import "google/protobuf/empty.proto"; import "pbtest/pbtest2.proto"; +import "pbtest/mod/struct.proto"; import "rust/extensions.proto"; package pbtest; @@ -368,3 +369,18 @@ message RecursiveOneof { ForeignMessage3 boxed = 5 [(rust.box_it) = true]; } } + +message MentionsKeywordPath { + pbtest.mod.Message message = 1; +} + +message NonNullableOneofKeyword { + oneof async { + option (rust.nullable) = false; + int64 a = 1; + } +} + +message NonNullableEnumKeyword { + TestMessage3.NestedMessage.NonNullableEnum enum = 1; +} diff --git a/pb-test/src/pbtest.rs b/pb-test/src/pbtest.rs index 879989d..fa837b7 100644 --- a/pb-test/src/pbtest.rs +++ b/pb-test/src/pbtest.rs @@ -178,9 +178,9 @@ fn all_fields() { expected.oneof_empty_field = TestMessage_OneofEmptyField::C(33); expected.oneof_empty_field = TestMessage_OneofEmptyField::B; expected.oneof_empty_field = TestMessage_OneofEmptyField::A; - expected.type_ = Some(false); - expected.mod_ = Some(TestMessage_Mod::Unsafe(3)); - expected.mod_ = Some(TestMessage_Mod::Loop(3)); + expected.r#type = Some(false); + expected.r#mod = Some(TestMessage_Mod::Unsafe(3)); + expected.r#mod = Some(TestMessage_Mod::Loop(3)); succeeds(&buf[..], expected) } diff --git a/pb-test/src/verify_generated_files.rs b/pb-test/src/verify_generated_files.rs index 8a8d2d6..893744e 100644 --- a/pb-test/src/verify_generated_files.rs +++ b/pb-test/src/verify_generated_files.rs @@ -23,7 +23,7 @@ fn verify_generated_files() { // Assert the correct number of pb-test generated files // Developers - please change this number if the change is intentional - assert_eq!(proto_files.len(), 13); + assert_eq!(proto_files.len(), 15); // Assert contents of the generated files for proto_file in proto_files {