From c44f05312a8956426ae527df28c47cb4f6bc5cd7 Mon Sep 17 00:00:00 2001 From: kbullinger Date: Wed, 2 Oct 2024 17:30:09 -0400 Subject: [PATCH] add support for group in oneof; add field_number to unknown_fields instead of tag --- protobuf-codegen/src/gen/field/mod.rs | 41 +++++++++++++++++++++++---- protobuf-codegen/src/gen/oneof.rs | 15 +++++++++- protobuf/src/rt/unknown_or_group.rs | 2 +- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 9ab9270b4..e657ddd58 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -970,13 +970,42 @@ impl<'a> FieldGen<'a> { } else { typed }; + let variant_path = o.variant_path(&self.proto_field.message.scope.rust_path_to_file()); + if o.elem.proto_type() == Type::TYPE_GROUP { + let proto_path = protobuf_crate_path(&self.customize); + w.write_line(&format!( + "let end_tag = {proto_path}::rt::set_wire_type_to_end_group(tag);" + )); + let value_type = &self + .elem() + .rust_storage_elem_type( + &self + .proto_field + .message + .scope + .file_and_mod(self.customize.clone()), + ) + .to_code(&self.customize); - w.write_line(&format!( - "self.{} = ::std::option::Option::Some({}({}));", - o.oneof_field_name, - o.variant_path(&self.proto_field.message.scope.rust_path_to_file()), - maybe_boxed.value - )); + w.write_line(&format!( + "let mut {} = {}::default();", + o.oneof_field_name, value_type, + )); + w.write_line(&format!( + "{}.merge_delimited(is, end_tag)?;", + o.oneof_field_name, + )); + + w.write_line(&format!( + "self.{} = ::std::option::Option::Some({}({}));", + o.oneof_field_name, variant_path, o.oneof_field_name, + )); + } else { + w.write_line(&format!( + "self.{} = ::std::option::Option::Some({}({}));", + o.oneof_field_name, variant_path, maybe_boxed.value + )); + } }) } diff --git a/protobuf-codegen/src/gen/oneof.rs b/protobuf-codegen/src/gen/oneof.rs index e1bd33901..73b217627 100644 --- a/protobuf-codegen/src/gen/oneof.rs +++ b/protobuf-codegen/src/gen/oneof.rs @@ -223,6 +223,19 @@ impl<'a> OneofGen<'a> { .collect() } + pub fn variants(&'a self) -> impl Iterator> { + self.oneof.variants().into_iter().map(|v| { + let field = self + .message + .fields + .iter() + .filter(|f| f.proto_field.name() == v.field.name()) + .next() + .expect(&format!("field not found by name: {}", v.field.name())); + OneofVariantGen::parse(self, v, field, self.message.root_scope) + }) + } + pub fn full_storage_type(&self) -> RustType { RustType::Option(Box::new(RustType::Oneof( self.type_name_relative( @@ -262,7 +275,7 @@ impl<'a> OneofGen<'a> { } 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() { + for variant in self.variants() { write_protoc_insertion_point_for_oneof_field( w, &self.customize.for_children, diff --git a/protobuf/src/rt/unknown_or_group.rs b/protobuf/src/rt/unknown_or_group.rs index cf9d35f00..e43ae9721 100644 --- a/protobuf/src/rt/unknown_or_group.rs +++ b/protobuf/src/rt/unknown_or_group.rs @@ -76,7 +76,7 @@ pub fn read_unknown( ) -> crate::Result<()> { let (field_number, wire_type) = Tag::new(tag)?.unpack(); let unknown = is.read_unknown_with_tag_unpacked(field_number, wire_type)?; - unknown_fields.add_value(tag, unknown); + unknown_fields.add_value(field_number, unknown); Ok(()) }