From 12453371e173736190110434227b6ebe88881efa Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 28 Sep 2022 13:22:55 -0700 Subject: [PATCH] Fixing merge issues --- .../com/google/protobuf/DynamicMessage.java | 3 +- .../google/protobuf/MessageReflection.java | 40 ++++++++++++++++--- .../compiler/java/java_message_builder.cc | 4 +- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java index 76d444e61148..51e6b0c27c1f 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -418,10 +418,11 @@ public DynamicMessage buildPartial() { } } + fields.makeImmutable(); DynamicMessage result = new DynamicMessage( type, - fields.buildPartial(), + fields, java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields); return result; diff --git a/java/core/src/main/java/com/google/protobuf/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java index 99615b3056e8..7cae5727afbf 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageReflection.java +++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java @@ -378,6 +378,7 @@ MergeTarget newEmptyTargetForField( static class BuilderAdapter implements MergeTarget { private final Message.Builder builder; + private boolean hasNestedBuilders = true; @Override public Descriptors.Descriptor getDescriptorForType() { @@ -393,6 +394,17 @@ public Object getField(Descriptors.FieldDescriptor field) { return builder.getField(field); } + private Message.Builder getFieldBuilder(Descriptors.FieldDescriptor field) { + if (hasNestedBuilders) { + try { + return builder.getFieldBuilder(field); + } catch (UnsupportedOperationException e) { + hasNestedBuilders = false; + } + } + return null; + } + @Override public boolean hasField(Descriptors.FieldDescriptor field) { return builder.hasField(field); @@ -536,11 +548,19 @@ public void mergeGroup( Message defaultInstance) throws IOException { if (!field.isRepeated()) { + Message.Builder subBuilder; if (hasField(field)) { - input.readGroup(field.getNumber(), builder.getFieldBuilder(field), extensionRegistry); - return; + subBuilder = getFieldBuilder(field); + if (subBuilder != null) { + input.readGroup(field.getNumber(), subBuilder, extensionRegistry); + return; + } else { + subBuilder = newMessageFieldInstance(field, defaultInstance); + subBuilder.mergeFrom((Message) getField(field)); + } + } else { + subBuilder = newMessageFieldInstance(field, defaultInstance); } - Message.Builder subBuilder = newMessageFieldInstance(field, defaultInstance); input.readGroup(field.getNumber(), subBuilder, extensionRegistry); Object unused = setField(field, subBuilder.buildPartial()); } else { @@ -558,11 +578,19 @@ public void mergeMessage( Message defaultInstance) throws IOException { if (!field.isRepeated()) { + Message.Builder subBuilder; if (hasField(field)) { - input.readMessage(builder.getFieldBuilder(field), extensionRegistry); - return; + subBuilder = getFieldBuilder(field); + if (subBuilder != null) { + input.readMessage(subBuilder, extensionRegistry); + return; + } else { + subBuilder = newMessageFieldInstance(field, defaultInstance); + subBuilder.mergeFrom((Message) getField(field)); + } + } else { + subBuilder = newMessageFieldInstance(field, defaultInstance); } - Message.Builder subBuilder = newMessageFieldInstance(field, defaultInstance); input.readMessage(subBuilder, extensionRegistry); Object unused = setField(field, subBuilder.buildPartial()); } else { diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index 72adc52d75ed..24ea648c79f3 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -673,7 +673,7 @@ void MessageBuilderGenerator::GenerateBuilderFieldParsingCase( io::Printer* printer, const FieldDescriptor* field) { uint32_t tag = WireFormatLite::MakeTag( field->number(), WireFormat::WireTypeForFieldType(field->type())); - std::string tagString = absl::StrCat(static_cast(tag)); + std::string tagString = StrCat(static_cast(tag)); printer->Print("case $tag$: {\n", "tag", tagString); printer->Indent(); @@ -692,7 +692,7 @@ void MessageBuilderGenerator::GenerateBuilderPackedFieldParsingCase( // packed version of this field regardless of field->options().packed(). uint32_t tag = WireFormatLite::MakeTag( field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - std::string tagString = absl::StrCat(static_cast(tag)); + std::string tagString = StrCat(static_cast(tag)); printer->Print("case $tag$: {\n", "tag", tagString); printer->Indent();