From 4dad9c40f5c250e3eed6472d4c68a21c2db2406b Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 15 Oct 2025 12:38:24 -0700 Subject: [PATCH] Make placeholder messages extendable for the full message_set range because we don't know their schema. This allows message set extensions with high numbers to be built dynamically with unknown dependencies. PiperOrigin-RevId: 819870793 --- .../java/com/google/protobuf/Descriptors.java | 12 ++++++--- .../com/google/protobuf/DescriptorsTest.java | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index 46c14200b115c..e064f5992f824 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -1150,7 +1150,13 @@ public EnumDescriptor findEnumTypeByName(final String name) { DescriptorProto.newBuilder() .setName(name) .addExtensionRange( - DescriptorProto.ExtensionRange.newBuilder().setStart(1).setEnd(536870912).build()) + DescriptorProto.ExtensionRange.newBuilder() + .setStart(1) + // 2^31 - 1, which is the largest possible extension for messages that set + // message_set_wire_format = true. Since this is a placeholder and we don't + // have a schema, this is safest setting. + .setEnd(2147483647) + .build()) .build(); this.fullName = fullname; @@ -1165,8 +1171,8 @@ public EnumDescriptor findEnumTypeByName(final String name) { // Create a placeholder FileDescriptor to hold this message. this.parent = new FileDescriptor(packageName, this); - extensionRangeLowerBounds = new int[] {1}; - extensionRangeUpperBounds = new int[] {536870912}; + extensionRangeLowerBounds = new int[] {this.proto.getExtensionRange(0).getStart()}; + extensionRangeUpperBounds = new int[] {this.proto.getExtensionRange(0).getEnd()}; placeholder = true; } diff --git a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java index a0fcf9b1faf96..5cb204b26bc22 100644 --- a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -988,6 +988,31 @@ public void testUnknownFieldsAllowed() throws Exception { .isTrue(); } + @Test + public void testUnknownMessageSetExtension() throws Exception { + FileDescriptorProto fooProto = + FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addDependency("message_set.proto") + .addExtension( + FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_INT32) + .setExtendee("MessageSet") + .setName("bar") + .setNumber(2147476052)) + .build(); + + FileDescriptor foo = + Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0], true); + FieldDescriptor field = foo.findExtensionByName("bar"); + + assertThat(field.isExtension()).isTrue(); + assertThat(field.getNumber()).isEqualTo(2147476052); + assertThat(field.getContainingType().isPlaceholder()).isTrue(); + assertThat(field.getContainingType().getFullName()).isEqualTo("MessageSet"); + } + @Test public void testHiddenDependency() throws Exception { FileDescriptorProto barProto =