Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request modifies ProtoSchemaConverter.java to add nested enum wrapper types to the rootProtoSchema instead of the local resultProto, and adds a corresponding test case convertSharedEnums in ProtoSchemaConverterTest.java. Feedback on this change warns that hoisting all enum wrappers to the root schema can cause name collisions and a DescriptorValidationException if multiple distinct enums share the same short name in different nested messages. It is recommended to ensure unique naming for hoisted wrappers to prevent this issue.
| rootProtoSchema.addNestedType( | ||
| DescriptorProto.newBuilder() | ||
| .setName(enclosingTypeName) | ||
| .addEnumType(enumType.toBuilder().setName(enumName)) |
There was a problem hiding this comment.
Hoisting all enum wrappers to the root schema (rootProtoSchema) can introduce name collisions if the input schema contains multiple distinct enums with the same short name (e.g., Status or Type) defined in different nested messages or packages.
Previously, these wrappers were added to resultProto (the local message descriptor), which kept them isolated within their respective parent message namespaces (e.g., Root.First.Status_E and Root.Second.Status_E). By hoisting them all to rootProtoSchema, they will now all be added directly to the root message with the same name (e.g., Root.Status_E), leading to a DescriptorValidationException due to duplicate nested type names.
To prevent this, consider making the hoisted wrapper name unique (for example, by prefixing it with the path of the enclosing message) or only hoisting enums when they are actually shared across different messages, while ensuring unique naming at the root. It would also be beneficial to add a test case in ProtoSchemaConverterTest.java that exercises multiple same-named enums in different nested messages to ensure they do not collide.
17c0382 to
2b1d22a
Compare
Fixes #13786
ProtoSchemaConverterputs the synthetic<Enum>_Ewrapper for an enum on whichever message is being converted when the enum is first seen (resultProto). Message types, though, are hoisted to the schema root. When two messages share one enum, the second message's field points at<Enum>_E.<Enum>, which only exists nested inside the first message, so building the descriptor fails with"<Enum>_E.<Enum>" is not defined.This adds the wrapper to
rootProtoSchemainstead, next to the hoisted message types, so every reference resolves no matter which message reached the enum first. It is a one-line change in the v1 converter.The new
convertSharedEnumstest covers the issue's layout and a few variations: sibling order, a deeper first reference, root references before and after the nested ones, and a second enum with the same value names, to check the wrappers stay separate. Against the original converter it fails with the error from the issue, and it passes with the fix. The existing exact-output tests only use enums on the top-level message, whereresultProtois the root, so their expected output does not change.The deprecated
v1beta2converter has the same pattern. I left it alone to keep this to the supported API, but I can apply the same change there if you want.