diff --git a/prost-build/src/code_generator.rs b/prost-build/src/code_generator.rs index 7fa181765..1ab19ee41 100644 --- a/prost-build/src/code_generator.rs +++ b/prost-build/src/code_generator.rs @@ -367,7 +367,7 @@ impl<'a> CodeGenerator<'a> { let repeated = field.label == Some(Label::Repeated as i32); let deprecated = self.deprecated(&field); let optional = self.optional(&field); - let boxed = self.boxed(&field, fq_message_name); + let boxed = self.boxed(&field, fq_message_name, None); let ty = self.resolve_type(&field, fq_message_name); debug!( @@ -576,9 +576,9 @@ impl<'a> CodeGenerator<'a> { self.path.pop(); self.path.pop(); - let oneof_name = format!("{}.{}", fq_message_name, oneof.name()); - self.append_type_attributes(&oneof_name); - self.append_enum_attributes(&oneof_name); + let fq_oneof_name = format!("{}.{}", fq_message_name, oneof.name()); + self.append_type_attributes(&fq_oneof_name); + self.append_enum_attributes(&fq_oneof_name); self.push_indent(); self.buf .push_str("#[allow(clippy::derive_partial_eq_without_eq)]\n"); @@ -595,8 +595,6 @@ impl<'a> CodeGenerator<'a> { self.path.push(2); self.depth += 1; for (field, idx) in fields { - let type_ = field.r#type(); - self.path.push(idx as i32); self.append_doc(fq_message_name, Some(field.name())); self.path.pop(); @@ -608,20 +606,12 @@ impl<'a> CodeGenerator<'a> { ty_tag, field.number() )); - self.append_field_attributes(&oneof_name, field.name()); + self.append_field_attributes(&fq_oneof_name, field.name()); self.push_indent(); let ty = self.resolve_type(&field, fq_message_name); - let boxed = ((type_ == Type::Message || type_ == Type::Group) - && self - .message_graph - .is_nested(field.type_name(), fq_message_name)) - || (self - .config - .boxed - .get_first_field(&oneof_name, field.name()) - .is_some()); + let boxed = self.boxed(&field, fq_message_name, Some(oneof.name())); debug!( " oneof: {:?}, type: {:?}, boxed: {}", @@ -1026,18 +1016,31 @@ impl<'a> CodeGenerator<'a> { } } - fn boxed(&self, field: &FieldDescriptorProto, fq_message_name: &str) -> bool { + fn boxed( + &self, + field: &FieldDescriptorProto, + fq_message_name: &str, + oneof: Option<&str>, + ) -> bool { + if field.label == Some(Label::Repeated as i32) { + return false; + } let fd_type = field.r#type(); - field.label != Some(Label::Repeated as i32) - && ((fd_type == Type::Message || fd_type == Type::Group) - && self - .message_graph - .is_nested(field.type_name(), fq_message_name)) - || (self - .config - .boxed - .get_first_field(fq_message_name, field.name()) - .is_some()) + if (fd_type == Type::Message || fd_type == Type::Group) + && self + .message_graph + .is_nested(field.type_name(), fq_message_name) + { + return true; + } + let config_path = match oneof { + None => Cow::Borrowed(fq_message_name), + Some(ooname) => Cow::Owned(format!("{fq_message_name}.{ooname}")), + }; + self.config + .boxed + .get_first_field(&config_path, field.name()) + .is_some() } /// Returns `true` if the field options includes the `deprecated` option.