• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import com.google.protobuf.Descriptors.Descriptor;
11 import com.google.protobuf.Descriptors.FieldDescriptor;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.TreeMap;
17 
18 /**
19  * Reflection utility methods shared by both mutable and immutable messages.
20  *
21  * @author liujisi@google.com (Pherl Liu)
22  */
23 class MessageReflection {
24 
writeMessageTo( Message message, Map<FieldDescriptor, Object> fields, CodedOutputStream output, boolean alwaysWriteRequiredFields)25   static void writeMessageTo(
26       Message message,
27       Map<FieldDescriptor, Object> fields,
28       CodedOutputStream output,
29       boolean alwaysWriteRequiredFields)
30       throws IOException {
31     final boolean isMessageSet =
32         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
33     if (alwaysWriteRequiredFields) {
34       fields = new TreeMap<FieldDescriptor, Object>(fields);
35       for (final FieldDescriptor field : message.getDescriptorForType().getFields()) {
36         if (field.isRequired() && !fields.containsKey(field)) {
37           fields.put(field, message.getField(field));
38         }
39       }
40     }
41     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : fields.entrySet()) {
42       final Descriptors.FieldDescriptor field = entry.getKey();
43       final Object value = entry.getValue();
44       if (isMessageSet
45           && field.isExtension()
46           && field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE
47           && !field.isRepeated()) {
48         output.writeMessageSetExtension(field.getNumber(), (Message) value);
49       } else {
50         FieldSet.writeField(field, value, output);
51       }
52     }
53 
54     final UnknownFieldSet unknownFields = message.getUnknownFields();
55     if (isMessageSet) {
56       unknownFields.writeAsMessageSetTo(output);
57     } else {
58       unknownFields.writeTo(output);
59     }
60   }
61 
getSerializedSize(Message message, Map<FieldDescriptor, Object> fields)62   static int getSerializedSize(Message message, Map<FieldDescriptor, Object> fields) {
63     int size = 0;
64     final boolean isMessageSet =
65         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
66 
67     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : fields.entrySet()) {
68       final Descriptors.FieldDescriptor field = entry.getKey();
69       final Object value = entry.getValue();
70       if (isMessageSet
71           && field.isExtension()
72           && field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE
73           && !field.isRepeated()) {
74         size +=
75             CodedOutputStream.computeMessageSetExtensionSize(field.getNumber(), (Message) value);
76       } else {
77         size += FieldSet.computeFieldSize(field, value);
78       }
79     }
80 
81     final UnknownFieldSet unknownFields = message.getUnknownFields();
82     if (isMessageSet) {
83       size += unknownFields.getSerializedSizeAsMessageSet();
84     } else {
85       size += unknownFields.getSerializedSize();
86     }
87     return size;
88   }
89 
delimitWithCommas(List<String> parts)90   static String delimitWithCommas(List<String> parts) {
91     StringBuilder result = new StringBuilder();
92     for (String part : parts) {
93       if (result.length() > 0) {
94         result.append(", ");
95       }
96       result.append(part);
97     }
98     return result.toString();
99   }
100 
101   @SuppressWarnings("unchecked")
isInitialized(MessageOrBuilder message)102   static boolean isInitialized(MessageOrBuilder message) {
103     // Check that all required fields are present.
104     for (final Descriptors.FieldDescriptor field : message.getDescriptorForType().getFields()) {
105       if (field.isRequired()) {
106         if (!message.hasField(field)) {
107           return false;
108         }
109       }
110     }
111 
112     // Check that embedded messages are initialized.
113     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
114         message.getAllFields().entrySet()) {
115       final Descriptors.FieldDescriptor field = entry.getKey();
116       if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
117         if (field.isRepeated()) {
118           for (final Message element : (List<Message>) entry.getValue()) {
119             if (!element.isInitialized()) {
120               return false;
121             }
122           }
123         } else {
124           if (!((Message) entry.getValue()).isInitialized()) {
125             return false;
126           }
127         }
128       }
129     }
130 
131     return true;
132   }
133 
subMessagePrefix( final String prefix, final Descriptors.FieldDescriptor field, final int index)134   private static String subMessagePrefix(
135       final String prefix, final Descriptors.FieldDescriptor field, final int index) {
136     final StringBuilder result = new StringBuilder(prefix);
137     if (field.isExtension()) {
138       result.append('(').append(field.getFullName()).append(')');
139     } else {
140       result.append(field.getName());
141     }
142     if (index != -1) {
143       result.append('[').append(index).append(']');
144     }
145     result.append('.');
146     return result.toString();
147   }
148 
findMissingFields( final MessageOrBuilder message, final String prefix, final List<String> results)149   private static void findMissingFields(
150       final MessageOrBuilder message, final String prefix, final List<String> results) {
151     for (final Descriptors.FieldDescriptor field : message.getDescriptorForType().getFields()) {
152       if (field.isRequired() && !message.hasField(field)) {
153         results.add(prefix + field.getName());
154       }
155     }
156 
157     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
158         message.getAllFields().entrySet()) {
159       final Descriptors.FieldDescriptor field = entry.getKey();
160       final Object value = entry.getValue();
161 
162       if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
163         if (field.isRepeated()) {
164           int i = 0;
165           for (final Object element : (List) value) {
166             findMissingFields(
167                 (MessageOrBuilder) element, subMessagePrefix(prefix, field, i++), results);
168           }
169         } else {
170           if (message.hasField(field)) {
171             findMissingFields(
172                 (MessageOrBuilder) value, subMessagePrefix(prefix, field, -1), results);
173           }
174         }
175       }
176     }
177   }
178 
179   /**
180    * Populates {@code this.missingFields} with the full "path" of each missing required field in the
181    * given message.
182    */
findMissingFields(final MessageOrBuilder message)183   static List<String> findMissingFields(final MessageOrBuilder message) {
184     final List<String> results = new ArrayList<String>();
185     findMissingFields(message, "", results);
186     return results;
187   }
188 
189   static interface MergeTarget {
190     enum ContainerType {
191       MESSAGE,
192       EXTENSION_SET
193     }
194 
195     /** Returns the descriptor for the target. */
getDescriptorForType()196     public Descriptors.Descriptor getDescriptorForType();
197 
getContainerType()198     public ContainerType getContainerType();
199 
findExtensionByName( ExtensionRegistry registry, String name)200     public ExtensionRegistry.ExtensionInfo findExtensionByName(
201         ExtensionRegistry registry, String name);
202 
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)203     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
204         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber);
205 
206     /**
207      * Obtains the value of the given field, or the default value if it is not set. For primitive
208      * fields, the boxed primitive value is returned. For enum fields, the EnumValueDescriptor for
209      * the value is returned. For embedded message fields, the sub-message is returned. For repeated
210      * fields, a java.util.List is returned.
211      */
getField(Descriptors.FieldDescriptor field)212     public Object getField(Descriptors.FieldDescriptor field);
213 
214     /**
215      * Returns true if the given field is set. This is exactly equivalent to calling the generated
216      * "has" accessor method corresponding to the field.
217      *
218      * @throws IllegalArgumentException The field is a repeated field, or {@code
219      *     field.getContainingType() != getDescriptorForType()}.
220      */
hasField(Descriptors.FieldDescriptor field)221     boolean hasField(Descriptors.FieldDescriptor field);
222 
223     /**
224      * Sets a field to the given value. The value must be of the correct type for this field, i.e.
225      * the same type that {@link Message#getField(Descriptors.FieldDescriptor)} would return.
226      */
setField(Descriptors.FieldDescriptor field, Object value)227     MergeTarget setField(Descriptors.FieldDescriptor field, Object value);
228 
229     /**
230      * Clears the field. This is exactly equivalent to calling the generated "clear" accessor method
231      * corresponding to the field.
232      */
clearField(Descriptors.FieldDescriptor field)233     MergeTarget clearField(Descriptors.FieldDescriptor field);
234 
235     /**
236      * Sets an element of a repeated field to the given value. The value must be of the correct type
237      * for this field, i.e. the same type that {@link
238      * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return.
239      *
240      * @throws IllegalArgumentException The field is not a repeated field, or {@code
241      *     field.getContainingType() != getDescriptorForType()}.
242      */
setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value)243     MergeTarget setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value);
244 
245     /**
246      * Like {@code setRepeatedField}, but appends the value as a new element.
247      *
248      * @throws IllegalArgumentException The field is not a repeated field, or {@code
249      *     field.getContainingType() != getDescriptorForType()}.
250      */
addRepeatedField(Descriptors.FieldDescriptor field, Object value)251     MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value);
252 
253     /**
254      * Returns true if the given oneof is set.
255      *
256      * @throws IllegalArgumentException if {@code oneof.getContainingType() !=
257      *     getDescriptorForType()}.
258      */
hasOneof(Descriptors.OneofDescriptor oneof)259     boolean hasOneof(Descriptors.OneofDescriptor oneof);
260 
261     /**
262      * Clears the oneof. This is exactly equivalent to calling the generated "clear" accessor method
263      * corresponding to the oneof.
264      */
clearOneof(Descriptors.OneofDescriptor oneof)265     MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);
266 
267     /** Obtains the FieldDescriptor if the given oneof is set. Returns null if no field is set. */
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)268     Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);
269 
270     /**
271      * Parse the input stream into a sub field group defined based on either FieldDescriptor or the
272      * default instance.
273      */
parseGroup( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)274     Object parseGroup(
275         CodedInputStream input,
276         ExtensionRegistryLite registry,
277         Descriptors.FieldDescriptor descriptor,
278         Message defaultInstance)
279         throws IOException;
280 
281     /**
282      * Parse the input stream into a sub field message defined based on either FieldDescriptor or
283      * the default instance.
284      */
parseMessage( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)285     Object parseMessage(
286         CodedInputStream input,
287         ExtensionRegistryLite registry,
288         Descriptors.FieldDescriptor descriptor,
289         Message defaultInstance)
290         throws IOException;
291 
292     /**
293      * Parse from a ByteString into a sub field message defined based on either FieldDescriptor or
294      * the default instance. There isn't a varint indicating the length of the message at the
295      * beginning of the input ByteString.
296      */
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)297     Object parseMessageFromBytes(
298         ByteString bytes,
299         ExtensionRegistryLite registry,
300         Descriptors.FieldDescriptor descriptor,
301         Message defaultInstance)
302         throws IOException;
303 
304     /**
305      * Read the given group field from the wire, merging with the existing field if it is already
306      * present.
307      *
308      * <p>For extensions, defaultInstance must be specified. For regular fields, defaultInstance can
309      * be null.
310      */
mergeGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)311     void mergeGroup(
312         CodedInputStream input,
313         ExtensionRegistryLite extensionRegistry,
314         FieldDescriptor field,
315         Message defaultInstance)
316         throws IOException;
317 
318     /**
319      * Read the given message field from the wire, merging with the existing field if it is already
320      * present.
321      *
322      * <p>For extensions, defaultInstance must be specified. For regular fields, defaultInstance can
323      * be null.
324      */
mergeMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)325     void mergeMessage(
326         CodedInputStream input,
327         ExtensionRegistryLite extensionRegistry,
328         FieldDescriptor field,
329         Message defaultInstance)
330         throws IOException;
331 
332     /** Returns the UTF8 validation level for the field. */
getUtf8Validation(Descriptors.FieldDescriptor descriptor)333     WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor);
334 
335     /**
336      * Returns a new merge target for a sub-field. When defaultInstance is provided, it indicates
337      * the descriptor is for an extension type, and implementations should create a new instance
338      * from the defaultInstance prototype directly.
339      */
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)340     MergeTarget newMergeTargetForField(
341         Descriptors.FieldDescriptor descriptor, Message defaultInstance);
342 
343     /**
344      * Returns an empty merge target for a sub-field. When defaultInstance is provided, it indicates
345      * the descriptor is for an extension type, and implementations should create a new instance
346      * from the defaultInstance prototype directly.
347      */
newEmptyTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)348     MergeTarget newEmptyTargetForField(
349         Descriptors.FieldDescriptor descriptor, Message defaultInstance);
350 
351     /** Finishes the merge and returns the underlying object. */
finish()352     Object finish();
353   }
354 
355   static class BuilderAdapter implements MergeTarget {
356 
357     private final Message.Builder builder;
358     private boolean hasNestedBuilders = true;
359 
360     @Override
getDescriptorForType()361     public Descriptors.Descriptor getDescriptorForType() {
362       return builder.getDescriptorForType();
363     }
364 
BuilderAdapter(Message.Builder builder)365     public BuilderAdapter(Message.Builder builder) {
366       this.builder = builder;
367     }
368 
369     @Override
getField(Descriptors.FieldDescriptor field)370     public Object getField(Descriptors.FieldDescriptor field) {
371       return builder.getField(field);
372     }
373 
getFieldBuilder(Descriptors.FieldDescriptor field)374     private Message.Builder getFieldBuilder(Descriptors.FieldDescriptor field) {
375       if (hasNestedBuilders) {
376         try {
377           return builder.getFieldBuilder(field);
378         } catch (UnsupportedOperationException e) {
379           hasNestedBuilders = false;
380         }
381       }
382       return null;
383     }
384 
385     @Override
hasField(Descriptors.FieldDescriptor field)386     public boolean hasField(Descriptors.FieldDescriptor field) {
387       return builder.hasField(field);
388     }
389 
390     @Override
setField(Descriptors.FieldDescriptor field, Object value)391     public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
392       if (!field.isRepeated() && value instanceof MessageLite.Builder) {
393         if (value != getFieldBuilder(field)) {
394           builder.setField(field, ((MessageLite.Builder) value).buildPartial());
395         }
396         return this;
397       }
398       builder.setField(field, value);
399       return this;
400     }
401 
402     @Override
clearField(Descriptors.FieldDescriptor field)403     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
404       builder.clearField(field);
405       return this;
406     }
407 
408     @Override
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)409     public MergeTarget setRepeatedField(
410         Descriptors.FieldDescriptor field, int index, Object value) {
411       if (value instanceof MessageLite.Builder) {
412         value = ((MessageLite.Builder) value).buildPartial();
413       }
414       builder.setRepeatedField(field, index, value);
415       return this;
416     }
417 
418     @Override
addRepeatedField(Descriptors.FieldDescriptor field, Object value)419     public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
420       if (value instanceof MessageLite.Builder) {
421         value = ((MessageLite.Builder) value).buildPartial();
422       }
423       builder.addRepeatedField(field, value);
424       return this;
425     }
426 
427     @Override
hasOneof(Descriptors.OneofDescriptor oneof)428     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
429       return builder.hasOneof(oneof);
430     }
431 
432     @Override
clearOneof(Descriptors.OneofDescriptor oneof)433     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
434       builder.clearOneof(oneof);
435       return this;
436     }
437 
438     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)439     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
440       return builder.getOneofFieldDescriptor(oneof);
441     }
442 
443     @Override
getContainerType()444     public ContainerType getContainerType() {
445       return ContainerType.MESSAGE;
446     }
447 
448     @Override
findExtensionByName( ExtensionRegistry registry, String name)449     public ExtensionRegistry.ExtensionInfo findExtensionByName(
450         ExtensionRegistry registry, String name) {
451       return registry.findImmutableExtensionByName(name);
452     }
453 
454     @Override
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)455     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
456         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
457       return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
458     }
459 
460     @Override
parseGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)461     public Object parseGroup(
462         CodedInputStream input,
463         ExtensionRegistryLite extensionRegistry,
464         Descriptors.FieldDescriptor field,
465         Message defaultInstance)
466         throws IOException {
467       Message.Builder subBuilder;
468       // When default instance is not null. The field is an extension field.
469       if (defaultInstance != null) {
470         subBuilder = defaultInstance.newBuilderForType();
471       } else {
472         subBuilder = builder.newBuilderForField(field);
473       }
474       if (!field.isRepeated()) {
475         Message originalMessage = (Message) getField(field);
476         if (originalMessage != null) {
477           subBuilder.mergeFrom(originalMessage);
478         }
479       }
480       input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
481       return subBuilder.buildPartial();
482     }
483 
484     @Override
parseMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)485     public Object parseMessage(
486         CodedInputStream input,
487         ExtensionRegistryLite extensionRegistry,
488         Descriptors.FieldDescriptor field,
489         Message defaultInstance)
490         throws IOException {
491       Message.Builder subBuilder;
492       // When default instance is not null. The field is an extension field.
493       if (defaultInstance != null) {
494         subBuilder = defaultInstance.newBuilderForType();
495       } else {
496         subBuilder = builder.newBuilderForField(field);
497       }
498       if (!field.isRepeated()) {
499         Message originalMessage = (Message) getField(field);
500         if (originalMessage != null) {
501           subBuilder.mergeFrom(originalMessage);
502         }
503       }
504       input.readMessage(subBuilder, extensionRegistry);
505       return subBuilder.buildPartial();
506     }
507 
508     @Override
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)509     public Object parseMessageFromBytes(
510         ByteString bytes,
511         ExtensionRegistryLite extensionRegistry,
512         Descriptors.FieldDescriptor field,
513         Message defaultInstance)
514         throws IOException {
515       Message.Builder subBuilder;
516       // When default instance is not null. The field is an extension field.
517       if (defaultInstance != null) {
518         subBuilder = defaultInstance.newBuilderForType();
519       } else {
520         subBuilder = builder.newBuilderForField(field);
521       }
522       if (!field.isRepeated()) {
523         Message originalMessage = (Message) getField(field);
524         if (originalMessage != null) {
525           subBuilder.mergeFrom(originalMessage);
526         }
527       }
528       subBuilder.mergeFrom(bytes, extensionRegistry);
529       return subBuilder.buildPartial();
530     }
531 
532     @Override
mergeGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)533     public void mergeGroup(
534         CodedInputStream input,
535         ExtensionRegistryLite extensionRegistry,
536         FieldDescriptor field,
537         Message defaultInstance)
538         throws IOException {
539       if (!field.isRepeated()) {
540         Message.Builder subBuilder;
541         if (hasField(field)) {
542           subBuilder = getFieldBuilder(field);
543           if (subBuilder != null) {
544             input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
545             return;
546           } else {
547             subBuilder = newMessageFieldInstance(field, defaultInstance);
548             subBuilder.mergeFrom((Message) getField(field));
549           }
550         } else {
551           subBuilder = newMessageFieldInstance(field, defaultInstance);
552         }
553         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
554         Object unused = setField(field, subBuilder.buildPartial());
555       } else {
556         Message.Builder subBuilder = newMessageFieldInstance(field, defaultInstance);
557         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
558         Object unused = addRepeatedField(field, subBuilder.buildPartial());
559       }
560     }
561 
562     @Override
mergeMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)563     public void mergeMessage(
564         CodedInputStream input,
565         ExtensionRegistryLite extensionRegistry,
566         Descriptors.FieldDescriptor field,
567         Message defaultInstance)
568         throws IOException {
569       if (!field.isRepeated()) {
570         Message.Builder subBuilder;
571         if (hasField(field)) {
572           subBuilder = getFieldBuilder(field);
573           if (subBuilder != null) {
574             input.readMessage(subBuilder, extensionRegistry);
575             return;
576           } else {
577             subBuilder = newMessageFieldInstance(field, defaultInstance);
578             subBuilder.mergeFrom((Message) getField(field));
579           }
580         } else {
581           subBuilder = newMessageFieldInstance(field, defaultInstance);
582         }
583         input.readMessage(subBuilder, extensionRegistry);
584         Object unused = setField(field, subBuilder.buildPartial());
585       } else {
586         Message.Builder subBuilder = newMessageFieldInstance(field, defaultInstance);
587         input.readMessage(subBuilder, extensionRegistry);
588         Object unused = addRepeatedField(field, subBuilder.buildPartial());
589       }
590     }
591 
newMessageFieldInstance( FieldDescriptor field, Message defaultInstance)592     private Message.Builder newMessageFieldInstance(
593         FieldDescriptor field, Message defaultInstance) {
594       // When default instance is not null. The field is an extension field.
595       if (defaultInstance != null) {
596         return defaultInstance.newBuilderForType();
597       } else {
598         return builder.newBuilderForField(field);
599       }
600     }
601 
602     @Override
newMergeTargetForField( Descriptors.FieldDescriptor field, Message defaultInstance)603     public MergeTarget newMergeTargetForField(
604         Descriptors.FieldDescriptor field, Message defaultInstance) {
605       Message.Builder subBuilder;
606       if (!field.isRepeated() && hasField(field)) {
607         subBuilder = getFieldBuilder(field);
608         if (subBuilder != null) {
609           return new BuilderAdapter(subBuilder);
610         }
611       }
612 
613       subBuilder = newMessageFieldInstance(field, defaultInstance);
614       if (!field.isRepeated()) {
615         Message originalMessage = (Message) getField(field);
616         if (originalMessage != null) {
617           subBuilder.mergeFrom(originalMessage);
618         }
619       }
620       return new BuilderAdapter(subBuilder);
621     }
622 
623     @Override
newEmptyTargetForField( Descriptors.FieldDescriptor field, Message defaultInstance)624     public MergeTarget newEmptyTargetForField(
625         Descriptors.FieldDescriptor field, Message defaultInstance) {
626       Message.Builder subBuilder;
627       if (defaultInstance != null) {
628         subBuilder = defaultInstance.newBuilderForType();
629       } else {
630         subBuilder = builder.newBuilderForField(field);
631       }
632       return new BuilderAdapter(subBuilder);
633     }
634 
635     @Override
getUtf8Validation(Descriptors.FieldDescriptor descriptor)636     public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
637       if (descriptor.needsUtf8Check()) {
638         return WireFormat.Utf8Validation.STRICT;
639       }
640       // TODO: support lazy strings for repeated fields.
641       if (!descriptor.isRepeated() && builder instanceof GeneratedMessage.Builder) {
642         return WireFormat.Utf8Validation.LAZY;
643       }
644       return WireFormat.Utf8Validation.LOOSE;
645     }
646 
647     @Override
finish()648     public Object finish() {
649       return builder;
650     }
651   }
652 
653   static class ExtensionAdapter implements MergeTarget {
654 
655     private final FieldSet<Descriptors.FieldDescriptor> extensions;
656 
ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions)657     ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
658       this.extensions = extensions;
659     }
660 
661     @Override
getDescriptorForType()662     public Descriptors.Descriptor getDescriptorForType() {
663       throw new UnsupportedOperationException("getDescriptorForType() called on FieldSet object");
664     }
665 
666     @Override
getField(Descriptors.FieldDescriptor field)667     public Object getField(Descriptors.FieldDescriptor field) {
668       return extensions.getField(field);
669     }
670 
671     @Override
hasField(Descriptors.FieldDescriptor field)672     public boolean hasField(Descriptors.FieldDescriptor field) {
673       return extensions.hasField(field);
674     }
675 
676     @Override
setField(Descriptors.FieldDescriptor field, Object value)677     public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
678       extensions.setField(field, value);
679       return this;
680     }
681 
682     @Override
clearField(Descriptors.FieldDescriptor field)683     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
684       extensions.clearField(field);
685       return this;
686     }
687 
688     @Override
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)689     public MergeTarget setRepeatedField(
690         Descriptors.FieldDescriptor field, int index, Object value) {
691       extensions.setRepeatedField(field, index, value);
692       return this;
693     }
694 
695     @Override
addRepeatedField(Descriptors.FieldDescriptor field, Object value)696     public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
697       extensions.addRepeatedField(field, value);
698       return this;
699     }
700 
701     @Override
hasOneof(Descriptors.OneofDescriptor oneof)702     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
703       return false;
704     }
705 
706     @Override
clearOneof(Descriptors.OneofDescriptor oneof)707     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
708       // Nothing to clear.
709       return this;
710     }
711 
712     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)713     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
714       return null;
715     }
716 
717     @Override
getContainerType()718     public ContainerType getContainerType() {
719       return ContainerType.EXTENSION_SET;
720     }
721 
722     @Override
findExtensionByName( ExtensionRegistry registry, String name)723     public ExtensionRegistry.ExtensionInfo findExtensionByName(
724         ExtensionRegistry registry, String name) {
725       return registry.findImmutableExtensionByName(name);
726     }
727 
728     @Override
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)729     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
730         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
731       return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
732     }
733 
734     @Override
parseGroup( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)735     public Object parseGroup(
736         CodedInputStream input,
737         ExtensionRegistryLite registry,
738         Descriptors.FieldDescriptor field,
739         Message defaultInstance)
740         throws IOException {
741       Message.Builder subBuilder = defaultInstance.newBuilderForType();
742       if (!field.isRepeated()) {
743         Message originalMessage = (Message) getField(field);
744         if (originalMessage != null) {
745           subBuilder.mergeFrom(originalMessage);
746         }
747       }
748       input.readGroup(field.getNumber(), subBuilder, registry);
749       return subBuilder.buildPartial();
750     }
751 
752     @Override
parseMessage( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)753     public Object parseMessage(
754         CodedInputStream input,
755         ExtensionRegistryLite registry,
756         Descriptors.FieldDescriptor field,
757         Message defaultInstance)
758         throws IOException {
759       Message.Builder subBuilder = defaultInstance.newBuilderForType();
760       if (!field.isRepeated()) {
761         Message originalMessage = (Message) getField(field);
762         if (originalMessage != null) {
763           subBuilder.mergeFrom(originalMessage);
764         }
765       }
766       input.readMessage(subBuilder, registry);
767       return subBuilder.buildPartial();
768     }
769 
770     @Override
mergeGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)771     public void mergeGroup(
772         CodedInputStream input,
773         ExtensionRegistryLite extensionRegistry,
774         FieldDescriptor field,
775         Message defaultInstance)
776         throws IOException {
777       if (!field.isRepeated()) {
778         if (hasField(field)) {
779           MessageLite.Builder current = ((MessageLite) getField(field)).toBuilder();
780           input.readGroup(field.getNumber(), current, extensionRegistry);
781           Object unused = setField(field, current.buildPartial());
782           return;
783         }
784         Message.Builder subBuilder = defaultInstance.newBuilderForType();
785         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
786         Object unused = setField(field, subBuilder.buildPartial());
787       } else {
788         Message.Builder subBuilder = defaultInstance.newBuilderForType();
789         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
790         Object unused = addRepeatedField(field, subBuilder.buildPartial());
791       }
792     }
793 
794     @Override
mergeMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)795     public void mergeMessage(
796         CodedInputStream input,
797         ExtensionRegistryLite extensionRegistry,
798         FieldDescriptor field,
799         Message defaultInstance)
800         throws IOException {
801       if (!field.isRepeated()) {
802         if (hasField(field)) {
803           MessageLite.Builder current = ((MessageLite) getField(field)).toBuilder();
804           input.readMessage(current, extensionRegistry);
805           Object unused = setField(field, current.buildPartial());
806           return;
807         }
808         Message.Builder subBuilder = defaultInstance.newBuilderForType();
809         input.readMessage(subBuilder, extensionRegistry);
810         Object unused = setField(field, subBuilder.buildPartial());
811       } else {
812         Message.Builder subBuilder = defaultInstance.newBuilderForType();
813         input.readMessage(subBuilder, extensionRegistry);
814         Object unused = addRepeatedField(field, subBuilder.buildPartial());
815       }
816     }
817 
818     @Override
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)819     public Object parseMessageFromBytes(
820         ByteString bytes,
821         ExtensionRegistryLite registry,
822         Descriptors.FieldDescriptor field,
823         Message defaultInstance)
824         throws IOException {
825       Message.Builder subBuilder = defaultInstance.newBuilderForType();
826       if (!field.isRepeated()) {
827         Message originalMessage = (Message) getField(field);
828         if (originalMessage != null) {
829           subBuilder.mergeFrom(originalMessage);
830         }
831       }
832       subBuilder.mergeFrom(bytes, registry);
833       return subBuilder.buildPartial();
834     }
835 
836     @Override
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)837     public MergeTarget newMergeTargetForField(
838         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
839       throw new UnsupportedOperationException("newMergeTargetForField() called on FieldSet object");
840     }
841 
842     @Override
newEmptyTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)843     public MergeTarget newEmptyTargetForField(
844         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
845       throw new UnsupportedOperationException("newEmptyTargetForField() called on FieldSet object");
846     }
847 
848     @Override
getUtf8Validation(Descriptors.FieldDescriptor descriptor)849     public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
850       if (descriptor.needsUtf8Check()) {
851         return WireFormat.Utf8Validation.STRICT;
852       }
853       // TODO: support lazy strings for ExtesnsionSet.
854       return WireFormat.Utf8Validation.LOOSE;
855     }
856 
857     @Override
finish()858     public Object finish() {
859       throw new UnsupportedOperationException("finish() called on FieldSet object");
860     }
861   }
862 
863   static class ExtensionBuilderAdapter implements MergeTarget {
864 
865     private final FieldSet.Builder<Descriptors.FieldDescriptor> extensions;
866 
ExtensionBuilderAdapter(FieldSet.Builder<Descriptors.FieldDescriptor> extensions)867     ExtensionBuilderAdapter(FieldSet.Builder<Descriptors.FieldDescriptor> extensions) {
868       this.extensions = extensions;
869     }
870 
871     @Override
getDescriptorForType()872     public Descriptors.Descriptor getDescriptorForType() {
873       throw new UnsupportedOperationException("getDescriptorForType() called on FieldSet object");
874     }
875 
876     @Override
getField(Descriptors.FieldDescriptor field)877     public Object getField(Descriptors.FieldDescriptor field) {
878       return extensions.getField(field);
879     }
880 
881     @Override
hasField(Descriptors.FieldDescriptor field)882     public boolean hasField(Descriptors.FieldDescriptor field) {
883       return extensions.hasField(field);
884     }
885 
886     @Override
887     @CanIgnoreReturnValue
setField(Descriptors.FieldDescriptor field, Object value)888     public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
889       extensions.setField(field, value);
890       return this;
891     }
892 
893     @Override
894     @CanIgnoreReturnValue
clearField(Descriptors.FieldDescriptor field)895     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
896       extensions.clearField(field);
897       return this;
898     }
899 
900     @Override
901     @CanIgnoreReturnValue
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)902     public MergeTarget setRepeatedField(
903         Descriptors.FieldDescriptor field, int index, Object value) {
904       extensions.setRepeatedField(field, index, value);
905       return this;
906     }
907 
908     @Override
909     @CanIgnoreReturnValue
addRepeatedField(Descriptors.FieldDescriptor field, Object value)910     public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
911       extensions.addRepeatedField(field, value);
912       return this;
913     }
914 
915     @Override
hasOneof(Descriptors.OneofDescriptor oneof)916     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
917       return false;
918     }
919 
920     @Override
921     @CanIgnoreReturnValue
clearOneof(Descriptors.OneofDescriptor oneof)922     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
923       // Nothing to clear.
924       return this;
925     }
926 
927     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)928     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
929       return null;
930     }
931 
932     @Override
getContainerType()933     public ContainerType getContainerType() {
934       return ContainerType.EXTENSION_SET;
935     }
936 
937     @Override
findExtensionByName( ExtensionRegistry registry, String name)938     public ExtensionRegistry.ExtensionInfo findExtensionByName(
939         ExtensionRegistry registry, String name) {
940       return registry.findImmutableExtensionByName(name);
941     }
942 
943     @Override
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)944     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
945         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
946       return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
947     }
948 
949     @Override
parseGroup( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)950     public Object parseGroup(
951         CodedInputStream input,
952         ExtensionRegistryLite registry,
953         Descriptors.FieldDescriptor field,
954         Message defaultInstance)
955         throws IOException {
956       Message.Builder subBuilder = defaultInstance.newBuilderForType();
957       if (!field.isRepeated()) {
958         Message originalMessage = (Message) getField(field);
959         if (originalMessage != null) {
960           subBuilder.mergeFrom(originalMessage);
961         }
962       }
963       input.readGroup(field.getNumber(), subBuilder, registry);
964       return subBuilder.buildPartial();
965     }
966 
967     @Override
parseMessage( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)968     public Object parseMessage(
969         CodedInputStream input,
970         ExtensionRegistryLite registry,
971         Descriptors.FieldDescriptor field,
972         Message defaultInstance)
973         throws IOException {
974       Message.Builder subBuilder = defaultInstance.newBuilderForType();
975       if (!field.isRepeated()) {
976         Message originalMessage = (Message) getField(field);
977         if (originalMessage != null) {
978           subBuilder.mergeFrom(originalMessage);
979         }
980       }
981       input.readMessage(subBuilder, registry);
982       return subBuilder.buildPartial();
983     }
984 
985     @Override
mergeGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)986     public void mergeGroup(
987         CodedInputStream input,
988         ExtensionRegistryLite extensionRegistry,
989         FieldDescriptor field,
990         Message defaultInstance)
991         throws IOException {
992       if (!field.isRepeated()) {
993         if (hasField(field)) {
994           Object fieldOrBuilder = extensions.getFieldAllowBuilders(field);
995           MessageLite.Builder subBuilder;
996           if (fieldOrBuilder instanceof MessageLite.Builder) {
997             subBuilder = (MessageLite.Builder) fieldOrBuilder;
998           } else {
999             subBuilder = ((MessageLite) fieldOrBuilder).toBuilder();
1000             extensions.setField(field, subBuilder);
1001           }
1002           input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
1003           return;
1004         }
1005         Message.Builder subBuilder = defaultInstance.newBuilderForType();
1006         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
1007         Object unused = setField(field, subBuilder);
1008       } else {
1009         Message.Builder subBuilder = defaultInstance.newBuilderForType();
1010         input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
1011         Object unused = addRepeatedField(field, subBuilder.buildPartial());
1012       }
1013     }
1014 
1015     @Override
mergeMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, FieldDescriptor field, Message defaultInstance)1016     public void mergeMessage(
1017         CodedInputStream input,
1018         ExtensionRegistryLite extensionRegistry,
1019         FieldDescriptor field,
1020         Message defaultInstance)
1021         throws IOException {
1022       if (!field.isRepeated()) {
1023         if (hasField(field)) {
1024           Object fieldOrBuilder = extensions.getFieldAllowBuilders(field);
1025           MessageLite.Builder subBuilder;
1026           if (fieldOrBuilder instanceof MessageLite.Builder) {
1027             subBuilder = (MessageLite.Builder) fieldOrBuilder;
1028           } else {
1029             subBuilder = ((MessageLite) fieldOrBuilder).toBuilder();
1030             extensions.setField(field, subBuilder);
1031           }
1032           input.readMessage(subBuilder, extensionRegistry);
1033           return;
1034         }
1035         Message.Builder subBuilder = defaultInstance.newBuilderForType();
1036         input.readMessage(subBuilder, extensionRegistry);
1037         Object unused = setField(field, subBuilder);
1038       } else {
1039         Message.Builder subBuilder = defaultInstance.newBuilderForType();
1040         input.readMessage(subBuilder, extensionRegistry);
1041         Object unused = addRepeatedField(field, subBuilder.buildPartial());
1042       }
1043     }
1044 
1045     @Override
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)1046     public Object parseMessageFromBytes(
1047         ByteString bytes,
1048         ExtensionRegistryLite registry,
1049         Descriptors.FieldDescriptor field,
1050         Message defaultInstance)
1051         throws IOException {
1052       Message.Builder subBuilder = defaultInstance.newBuilderForType();
1053       if (!field.isRepeated()) {
1054         Message originalMessage = (Message) getField(field);
1055         if (originalMessage != null) {
1056           subBuilder.mergeFrom(originalMessage);
1057         }
1058       }
1059       subBuilder.mergeFrom(bytes, registry);
1060       return subBuilder.buildPartial();
1061     }
1062 
1063     @Override
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)1064     public MergeTarget newMergeTargetForField(
1065         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
1066       throw new UnsupportedOperationException("newMergeTargetForField() called on FieldSet object");
1067     }
1068 
1069     @Override
newEmptyTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)1070     public MergeTarget newEmptyTargetForField(
1071         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
1072       throw new UnsupportedOperationException("newEmptyTargetForField() called on FieldSet object");
1073     }
1074 
1075     @Override
getUtf8Validation(Descriptors.FieldDescriptor descriptor)1076     public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
1077       if (descriptor.needsUtf8Check()) {
1078         return WireFormat.Utf8Validation.STRICT;
1079       }
1080       // TODO: support lazy strings for ExtesnsionSet.
1081       return WireFormat.Utf8Validation.LOOSE;
1082     }
1083 
1084     @Override
finish()1085     public Object finish() {
1086       throw new UnsupportedOperationException("finish() called on FieldSet object");
1087     }
1088   }
1089 
1090   /**
1091    * Parses a single field into MergeTarget. The target can be Message.Builder, FieldSet or
1092    * MutableMessage.
1093    *
1094    * <p>Package-private because it is used by GeneratedMessage.ExtendableMessage.
1095    *
1096    * @param tag The tag, which should have already been read.
1097    * @param unknownFields If not null, unknown fields will be merged to this {@link
1098    *     UnknownFieldSet}, otherwise unknown fields will be discarded.
1099    * @return {@code true} unless the tag is an end-group tag.
1100    */
mergeFieldFrom( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target, int tag)1101   static boolean mergeFieldFrom(
1102       CodedInputStream input,
1103       UnknownFieldSet.Builder unknownFields,
1104       ExtensionRegistryLite extensionRegistry,
1105       Descriptors.Descriptor type,
1106       MergeTarget target,
1107       int tag)
1108       throws IOException {
1109     if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
1110       mergeMessageSetExtensionFromCodedStream(
1111           input, unknownFields, extensionRegistry, type, target);
1112       return true;
1113     }
1114 
1115     final int wireType = WireFormat.getTagWireType(tag);
1116     final int fieldNumber = WireFormat.getTagFieldNumber(tag);
1117 
1118     final Descriptors.FieldDescriptor field;
1119     Message defaultInstance = null;
1120 
1121     if (type.isExtensionNumber(fieldNumber)) {
1122       // extensionRegistry may be either ExtensionRegistry or
1123       // ExtensionRegistryLite.  Since the type we are parsing is a full
1124       // message, only a full ExtensionRegistry could possibly contain
1125       // extensions of it.  Otherwise we will treat the registry as if it
1126       // were empty.
1127       if (extensionRegistry instanceof ExtensionRegistry) {
1128         final ExtensionRegistry.ExtensionInfo extension =
1129             target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, type, fieldNumber);
1130         if (extension == null) {
1131           field = null;
1132         } else {
1133           field = extension.descriptor;
1134           defaultInstance = extension.defaultInstance;
1135           if (defaultInstance == null
1136               && field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
1137             throw new IllegalStateException(
1138                 "Message-typed extension lacked default instance: " + field.getFullName());
1139           }
1140         }
1141       } else {
1142         field = null;
1143       }
1144     } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
1145       field = type.findFieldByNumber(fieldNumber);
1146     } else {
1147       field = null;
1148     }
1149 
1150     boolean unknown = false;
1151     boolean packed = false;
1152     if (field == null) {
1153       unknown = true; // Unknown field.
1154     } else if (wireType
1155         == FieldSet.getWireFormatForFieldType(field.getLiteType(), /* isPacked= */ false)) {
1156       packed = false;
1157     } else if (field.isPackable()
1158         && wireType
1159             == FieldSet.getWireFormatForFieldType(field.getLiteType(), /* isPacked= */ true)) {
1160       packed = true;
1161     } else {
1162       unknown = true; // Unknown wire type.
1163     }
1164 
1165     if (unknown) { // Unknown field or wrong wire type.  Skip.
1166       if (unknownFields != null) {
1167         return unknownFields.mergeFieldFrom(tag, input);
1168       } else {
1169         return input.skipField(tag);
1170       }
1171     }
1172 
1173     if (packed) {
1174       final int length = input.readRawVarint32();
1175       final int limit = input.pushLimit(length);
1176       if (field.getLiteType() == WireFormat.FieldType.ENUM) {
1177         while (input.getBytesUntilLimit() > 0) {
1178           final int rawValue = input.readEnum();
1179           if (field.legacyEnumFieldTreatedAsClosed()) {
1180             final Object value = field.getEnumType().findValueByNumber(rawValue);
1181             // If the number isn't recognized as a valid value for this enum,
1182             // add it to the unknown fields.
1183             if (value == null) {
1184               if (unknownFields != null) {
1185                 unknownFields.mergeVarintField(fieldNumber, rawValue);
1186               }
1187             } else {
1188               target.addRepeatedField(field, value);
1189             }
1190           } else {
1191             target.addRepeatedField(
1192                 field, field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue));
1193           }
1194         }
1195       } else {
1196         while (input.getBytesUntilLimit() > 0) {
1197           final Object value =
1198               WireFormat.readPrimitiveField(
1199                   input, field.getLiteType(), target.getUtf8Validation(field));
1200           target.addRepeatedField(field, value);
1201         }
1202       }
1203       input.popLimit(limit);
1204     } else {
1205       final Object value;
1206       switch (field.getType()) {
1207         case GROUP:
1208           {
1209             target.mergeGroup(input, extensionRegistry, field, defaultInstance);
1210             return true;
1211           }
1212         case MESSAGE:
1213           {
1214             target.mergeMessage(input, extensionRegistry, field, defaultInstance);
1215             return true;
1216           }
1217         case ENUM:
1218           final int rawValue = input.readEnum();
1219           if (field.legacyEnumFieldTreatedAsClosed()) {
1220             value = field.getEnumType().findValueByNumber(rawValue);
1221             // If the number isn't recognized as a valid value for this enum,
1222             // add it to the unknown fields.
1223             if (value == null) {
1224               if (unknownFields != null) {
1225                 unknownFields.mergeVarintField(fieldNumber, rawValue);
1226               }
1227               return true;
1228             }
1229           } else {
1230             value = field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue);
1231           }
1232           break;
1233         default:
1234           value =
1235               WireFormat.readPrimitiveField(
1236                   input, field.getLiteType(), target.getUtf8Validation(field));
1237           break;
1238       }
1239 
1240       if (field.isRepeated()) {
1241         target.addRepeatedField(field, value);
1242       } else {
1243         target.setField(field, value);
1244       }
1245     }
1246 
1247     return true;
1248   }
1249 
1250   /** Read a message from the given input stream into the provided target and UnknownFieldSet. */
mergeMessageFrom( Message.Builder target, UnknownFieldSet.Builder unknownFields, CodedInputStream input, ExtensionRegistryLite extensionRegistry)1251   static void mergeMessageFrom(
1252       Message.Builder target,
1253       UnknownFieldSet.Builder unknownFields,
1254       CodedInputStream input,
1255       ExtensionRegistryLite extensionRegistry)
1256       throws IOException {
1257     BuilderAdapter builderAdapter = new BuilderAdapter(target);
1258     Descriptor descriptorForType = target.getDescriptorForType();
1259     while (true) {
1260       final int tag = input.readTag();
1261       if (tag == 0) {
1262         break;
1263       }
1264 
1265       if (!mergeFieldFrom(
1266           input, unknownFields, extensionRegistry, descriptorForType, builderAdapter, tag)) {
1267         // end group tag
1268         break;
1269       }
1270     }
1271   }
1272 
1273   /** Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into MergeTarget. */
mergeMessageSetExtensionFromCodedStream( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target)1274   private static void mergeMessageSetExtensionFromCodedStream(
1275       CodedInputStream input,
1276       UnknownFieldSet.Builder unknownFields,
1277       ExtensionRegistryLite extensionRegistry,
1278       Descriptors.Descriptor type,
1279       MergeTarget target)
1280       throws IOException {
1281 
1282     // The wire format for MessageSet is:
1283     //   message MessageSet {
1284     //     repeated group Item = 1 {
1285     //       required uint32 typeId = 2;
1286     //       required bytes message = 3;
1287     //     }
1288     //   }
1289     // "typeId" is the extension's field number.  The extension can only be
1290     // a message type, where "message" contains the encoded bytes of that
1291     // message.
1292     //
1293     // In practice, we will probably never see a MessageSet item in which
1294     // the message appears before the type ID, or where either field does not
1295     // appear exactly once.  However, in theory such cases are valid, so we
1296     // should be prepared to accept them.
1297 
1298     int typeId = 0;
1299     ByteString rawBytes = null; // If we encounter "message" before "typeId"
1300     ExtensionRegistry.ExtensionInfo extension = null;
1301 
1302     // Read bytes from input, if we get it's type first then parse it eagerly,
1303     // otherwise we store the raw bytes in a local variable.
1304     while (true) {
1305       final int tag = input.readTag();
1306       if (tag == 0) {
1307         break;
1308       }
1309 
1310       if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
1311         typeId = input.readUInt32();
1312         if (typeId != 0) {
1313           // extensionRegistry may be either ExtensionRegistry or
1314           // ExtensionRegistryLite. Since the type we are parsing is a full
1315           // message, only a full ExtensionRegistry could possibly contain
1316           // extensions of it. Otherwise we will treat the registry as if it
1317           // were empty.
1318           if (extensionRegistry instanceof ExtensionRegistry) {
1319             extension =
1320                 target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, type, typeId);
1321           }
1322         }
1323 
1324       } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
1325         if (typeId != 0) {
1326           if (extension != null && ExtensionRegistryLite.isEagerlyParseMessageSets()) {
1327             // We already know the type, so we can parse directly from the
1328             // input with no copying.  Hooray!
1329             eagerlyMergeMessageSetExtension(input, extension, extensionRegistry, target);
1330             rawBytes = null;
1331             continue;
1332           }
1333         }
1334         // We haven't seen a type ID yet or we want parse message lazily.
1335         rawBytes = input.readBytes();
1336 
1337       } else { // Unknown tag. Skip it.
1338         if (!input.skipField(tag)) {
1339           break; // End of group
1340         }
1341       }
1342     }
1343     input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
1344 
1345     // Process the raw bytes.
1346     if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
1347       if (extension != null) { // We known the type
1348         mergeMessageSetExtensionFromBytes(rawBytes, extension, extensionRegistry, target);
1349       } else { // We don't know how to parse this. Ignore it.
1350         if (rawBytes != null && unknownFields != null) {
1351           unknownFields.mergeField(
1352               typeId, UnknownFieldSet.Field.newBuilder().addLengthDelimited(rawBytes).build());
1353         }
1354       }
1355     }
1356   }
1357 
mergeMessageSetExtensionFromBytes( ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)1358   private static void mergeMessageSetExtensionFromBytes(
1359       ByteString rawBytes,
1360       ExtensionRegistry.ExtensionInfo extension,
1361       ExtensionRegistryLite extensionRegistry,
1362       MergeTarget target)
1363       throws IOException {
1364 
1365     Descriptors.FieldDescriptor field = extension.descriptor;
1366     boolean hasOriginalValue = target.hasField(field);
1367 
1368     if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
1369       // If the field already exists, we just parse the field.
1370       Object value =
1371           target.parseMessageFromBytes(
1372               rawBytes, extensionRegistry, field, extension.defaultInstance);
1373       target.setField(field, value);
1374     } else {
1375       // Use LazyField to load MessageSet lazily.
1376       LazyField lazyField = new LazyField(extension.defaultInstance, extensionRegistry, rawBytes);
1377       target.setField(field, lazyField);
1378     }
1379   }
1380 
eagerlyMergeMessageSetExtension( CodedInputStream input, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)1381   private static void eagerlyMergeMessageSetExtension(
1382       CodedInputStream input,
1383       ExtensionRegistry.ExtensionInfo extension,
1384       ExtensionRegistryLite extensionRegistry,
1385       MergeTarget target)
1386       throws IOException {
1387     Descriptors.FieldDescriptor field = extension.descriptor;
1388     Object value = target.parseMessage(input, extensionRegistry, field, extension.defaultInstance);
1389     target.setField(field, value);
1390   }
1391 }
1392