@@ -378,6 +378,7 @@ MergeTarget newEmptyTargetForField(
378378 static class BuilderAdapter implements MergeTarget {
379379
380380 private final Message .Builder builder ;
381+ private boolean hasNestedBuilders = true ;
381382
382383 @ Override
383384 public Descriptors .Descriptor getDescriptorForType () {
@@ -393,13 +394,30 @@ public Object getField(Descriptors.FieldDescriptor field) {
393394 return builder .getField (field );
394395 }
395396
397+ private Message .Builder getFieldBuilder (Descriptors .FieldDescriptor field ) {
398+ if (hasNestedBuilders ) {
399+ try {
400+ return builder .getFieldBuilder (field );
401+ } catch (UnsupportedOperationException e ) {
402+ hasNestedBuilders = false ;
403+ }
404+ }
405+ return null ;
406+ }
407+
396408 @ Override
397409 public boolean hasField (Descriptors .FieldDescriptor field ) {
398410 return builder .hasField (field );
399411 }
400412
401413 @ Override
402414 public MergeTarget setField (Descriptors .FieldDescriptor field , Object value ) {
415+ if (!field .isRepeated () && value instanceof MessageLite .Builder ) {
416+ if (value != getFieldBuilder (field )) {
417+ builder .setField (field , ((MessageLite .Builder ) value ).buildPartial ());
418+ }
419+ return this ;
420+ }
403421 builder .setField (field , value );
404422 return this ;
405423 }
@@ -413,12 +431,18 @@ public MergeTarget clearField(Descriptors.FieldDescriptor field) {
413431 @ Override
414432 public MergeTarget setRepeatedField (
415433 Descriptors .FieldDescriptor field , int index , Object value ) {
434+ if (value instanceof MessageLite .Builder ) {
435+ value = ((MessageLite .Builder ) value ).buildPartial ();
436+ }
416437 builder .setRepeatedField (field , index , value );
417438 return this ;
418439 }
419440
420441 @ Override
421442 public MergeTarget addRepeatedField (Descriptors .FieldDescriptor field , Object value ) {
443+ if (value instanceof MessageLite .Builder ) {
444+ value = ((MessageLite .Builder ) value ).buildPartial ();
445+ }
422446 builder .addRepeatedField (field , value );
423447 return this ;
424448 }
@@ -536,11 +560,19 @@ public void mergeGroup(
536560 Message defaultInstance )
537561 throws IOException {
538562 if (!field .isRepeated ()) {
563+ Message .Builder subBuilder ;
539564 if (hasField (field )) {
540- input .readGroup (field .getNumber (), builder .getFieldBuilder (field ), extensionRegistry );
541- return ;
565+ subBuilder = getFieldBuilder (field );
566+ if (subBuilder != null ) {
567+ input .readGroup (field .getNumber (), subBuilder , extensionRegistry );
568+ return ;
569+ } else {
570+ subBuilder = newMessageFieldInstance (field , defaultInstance );
571+ subBuilder .mergeFrom ((Message ) getField (field ));
572+ }
573+ } else {
574+ subBuilder = newMessageFieldInstance (field , defaultInstance );
542575 }
543- Message .Builder subBuilder = newMessageFieldInstance (field , defaultInstance );
544576 input .readGroup (field .getNumber (), subBuilder , extensionRegistry );
545577 Object unused = setField (field , subBuilder .buildPartial ());
546578 } else {
@@ -558,11 +590,19 @@ public void mergeMessage(
558590 Message defaultInstance )
559591 throws IOException {
560592 if (!field .isRepeated ()) {
593+ Message .Builder subBuilder ;
561594 if (hasField (field )) {
562- input .readMessage (builder .getFieldBuilder (field ), extensionRegistry );
563- return ;
595+ subBuilder = getFieldBuilder (field );
596+ if (subBuilder != null ) {
597+ input .readMessage (subBuilder , extensionRegistry );
598+ return ;
599+ } else {
600+ subBuilder = newMessageFieldInstance (field , defaultInstance );
601+ subBuilder .mergeFrom ((Message ) getField (field ));
602+ }
603+ } else {
604+ subBuilder = newMessageFieldInstance (field , defaultInstance );
564605 }
565- Message .Builder subBuilder = newMessageFieldInstance (field , defaultInstance );
566606 input .readMessage (subBuilder , extensionRegistry );
567607 Object unused = setField (field , subBuilder .buildPartial ());
568608 } else {
@@ -586,11 +626,14 @@ private Message.Builder newMessageFieldInstance(
586626 public MergeTarget newMergeTargetForField (
587627 Descriptors .FieldDescriptor field , Message defaultInstance ) {
588628 Message .Builder subBuilder ;
589- if (defaultInstance != null ) {
590- subBuilder = defaultInstance .newBuilderForType ();
591- } else {
592- subBuilder = builder .newBuilderForField (field );
629+ if (!field .isRepeated () && hasField (field )) {
630+ subBuilder = getFieldBuilder (field );
631+ if (subBuilder != null ) {
632+ return new BuilderAdapter (subBuilder );
633+ }
593634 }
635+
636+ subBuilder = newMessageFieldInstance (field , defaultInstance );
594637 if (!field .isRepeated ()) {
595638 Message originalMessage = (Message ) getField (field );
596639 if (originalMessage != null ) {
@@ -626,7 +669,7 @@ public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor d
626669
627670 @ Override
628671 public Object finish () {
629- return builder . buildPartial () ;
672+ return builder ;
630673 }
631674 }
632675
0 commit comments