1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import com.google.protobuf.Descriptors.FieldDescriptor;
34 
35 import java.io.IOException;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.TreeMap;
40 
41 /**
42  * Reflection utility methods shared by both mutable and immutable messages.
43  *
44  * @author liujisi@google.com (Pherl Liu)
45  */
46 class MessageReflection {
47 
writeMessageTo(Message message, CodedOutputStream output, boolean alwaysWriteRequiredFields)48   static void writeMessageTo(Message message, CodedOutputStream output,
49       boolean alwaysWriteRequiredFields)
50       throws IOException {
51     final boolean isMessageSet =
52         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
53 
54     Map<FieldDescriptor, Object> fields = message.getAllFields();
55     if (alwaysWriteRequiredFields) {
56       fields = new TreeMap<FieldDescriptor, Object>(fields);
57       for (final FieldDescriptor field :
58           message.getDescriptorForType().getFields()) {
59         if (field.isRequired() && !fields.containsKey(field)) {
60           fields.put(field, message.getField(field));
61         }
62       }
63     }
64     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
65         fields.entrySet()) {
66       final Descriptors.FieldDescriptor field = entry.getKey();
67       final Object value = entry.getValue();
68       if (isMessageSet && field.isExtension() &&
69           field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
70           !field.isRepeated()) {
71         output.writeMessageSetExtension(field.getNumber(), (Message) value);
72       } else {
73         FieldSet.writeField(field, value, output);
74       }
75     }
76 
77     final UnknownFieldSet unknownFields = message.getUnknownFields();
78     if (isMessageSet) {
79       unknownFields.writeAsMessageSetTo(output);
80     } else {
81       unknownFields.writeTo(output);
82     }
83   }
84 
getSerializedSize(Message message)85   static int getSerializedSize(Message message) {
86     int size = 0;
87     final boolean isMessageSet =
88         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
89 
90     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
91         message.getAllFields().entrySet()) {
92       final Descriptors.FieldDescriptor field = entry.getKey();
93       final Object value = entry.getValue();
94       if (isMessageSet && field.isExtension() &&
95           field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
96           !field.isRepeated()) {
97         size += CodedOutputStream.computeMessageSetExtensionSize(
98             field.getNumber(), (Message) value);
99       } else {
100         size += FieldSet.computeFieldSize(field, value);
101       }
102     }
103 
104     final UnknownFieldSet unknownFields = message.getUnknownFields();
105     if (isMessageSet) {
106       size += unknownFields.getSerializedSizeAsMessageSet();
107     } else {
108       size += unknownFields.getSerializedSize();
109     }
110     return size;
111   }
112 
delimitWithCommas(List<String> parts)113   static String delimitWithCommas(List<String> parts) {
114     StringBuilder result = new StringBuilder();
115     for (String part : parts) {
116       if (result.length() > 0) {
117         result.append(", ");
118       }
119       result.append(part);
120     }
121     return result.toString();
122   }
123 
124   @SuppressWarnings("unchecked")
isInitialized(MessageOrBuilder message)125   static boolean isInitialized(MessageOrBuilder message) {
126     // Check that all required fields are present.
127     for (final Descriptors.FieldDescriptor field : message
128         .getDescriptorForType()
129         .getFields()) {
130       if (field.isRequired()) {
131         if (!message.hasField(field)) {
132           return false;
133         }
134       }
135     }
136 
137     // Check that embedded messages are initialized.
138     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
139         message.getAllFields().entrySet()) {
140       final Descriptors.FieldDescriptor field = entry.getKey();
141       if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
142         if (field.isRepeated()) {
143           for (final Message element
144               : (List<Message>) entry.getValue()) {
145             if (!element.isInitialized()) {
146               return false;
147             }
148           }
149         } else {
150           if (!((Message) entry.getValue()).isInitialized()) {
151             return false;
152           }
153         }
154       }
155     }
156 
157     return true;
158   }
159 
subMessagePrefix(final String prefix, final Descriptors.FieldDescriptor field, final int index)160   private static String subMessagePrefix(final String prefix,
161       final Descriptors.FieldDescriptor field,
162       final int index) {
163     final StringBuilder result = new StringBuilder(prefix);
164     if (field.isExtension()) {
165       result.append('(')
166           .append(field.getFullName())
167           .append(')');
168     } else {
169       result.append(field.getName());
170     }
171     if (index != -1) {
172       result.append('[')
173           .append(index)
174           .append(']');
175     }
176     result.append('.');
177     return result.toString();
178   }
179 
findMissingFields(final MessageOrBuilder message, final String prefix, final List<String> results)180   private static void findMissingFields(final MessageOrBuilder message,
181       final String prefix,
182       final List<String> results) {
183     for (final Descriptors.FieldDescriptor field :
184         message.getDescriptorForType().getFields()) {
185       if (field.isRequired() && !message.hasField(field)) {
186         results.add(prefix + field.getName());
187       }
188     }
189 
190     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
191         message.getAllFields().entrySet()) {
192       final Descriptors.FieldDescriptor field = entry.getKey();
193       final Object value = entry.getValue();
194 
195       if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
196         if (field.isRepeated()) {
197           int i = 0;
198           for (final Object element : (List) value) {
199             findMissingFields((MessageOrBuilder) element,
200                 subMessagePrefix(prefix, field, i++),
201                 results);
202           }
203         } else {
204           if (message.hasField(field)) {
205             findMissingFields((MessageOrBuilder) value,
206                 subMessagePrefix(prefix, field, -1),
207                 results);
208           }
209         }
210       }
211     }
212   }
213 
214   /**
215    * Populates {@code this.missingFields} with the full "path" of each missing
216    * required field in the given message.
217    */
findMissingFields( final MessageOrBuilder message)218   static List<String> findMissingFields(
219       final MessageOrBuilder message) {
220     final List<String> results = new ArrayList<String>();
221     findMissingFields(message, "", results);
222     return results;
223   }
224 
225   static interface MergeTarget {
226     enum ContainerType {
227       MESSAGE, EXTENSION_SET
228     }
229 
230     /**
231      * Returns the descriptor for the target.
232      */
getDescriptorForType()233     public Descriptors.Descriptor getDescriptorForType();
234 
getContainerType()235     public ContainerType getContainerType();
236 
findExtensionByName( ExtensionRegistry registry, String name)237     public ExtensionRegistry.ExtensionInfo findExtensionByName(
238         ExtensionRegistry registry, String name);
239 
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)240     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
241         ExtensionRegistry registry, Descriptors.Descriptor containingType,
242         int fieldNumber);
243 
244     /**
245      * Obtains the value of the given field, or the default value if it is not
246      * set.  For primitive fields, the boxed primitive value is returned. For
247      * enum fields, the EnumValueDescriptor for the value is returned. For
248      * embedded message fields, the sub-message is returned.  For repeated
249      * fields, a java.util.List is returned.
250      */
getField(Descriptors.FieldDescriptor field)251     public Object getField(Descriptors.FieldDescriptor field);
252 
253     /**
254      * Returns true if the given field is set.  This is exactly equivalent to
255      * calling the generated "has" accessor method corresponding to the field.
256      *
257      * @throws IllegalArgumentException The field is a repeated field, or {@code
258      *     field.getContainingType() != getDescriptorForType()}.
259      */
hasField(Descriptors.FieldDescriptor field)260     boolean hasField(Descriptors.FieldDescriptor field);
261 
262     /**
263      * Sets a field to the given value.  The value must be of the correct type
264      * for this field, i.e. the same type that
265      * {@link Message#getField(Descriptors.FieldDescriptor)}
266      * would return.
267      */
setField(Descriptors.FieldDescriptor field, Object value)268     MergeTarget setField(Descriptors.FieldDescriptor field, Object value);
269 
270     /**
271      * Clears the field.  This is exactly equivalent to calling the generated
272      * "clear" accessor method corresponding to the field.
273      */
clearField(Descriptors.FieldDescriptor field)274     MergeTarget clearField(Descriptors.FieldDescriptor field);
275 
276     /**
277      * Sets an element of a repeated field to the given value.  The value must
278      * be of the correct type for this field, i.e. the same type that {@link
279      * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return.
280      *
281      * @throws IllegalArgumentException The field is not a repeated field, or
282      *                                  {@code field.getContainingType() !=
283      *                                  getDescriptorForType()}.
284      */
setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value)285     MergeTarget setRepeatedField(Descriptors.FieldDescriptor field,
286         int index, Object value);
287 
288     /**
289      * Like {@code setRepeatedField}, but appends the value as a new element.
290      *
291      * @throws IllegalArgumentException The field is not a repeated field, or
292      *                                  {@code field.getContainingType() !=
293      *                                  getDescriptorForType()}.
294      */
addRepeatedField(Descriptors.FieldDescriptor field, Object value)295     MergeTarget addRepeatedField(Descriptors.FieldDescriptor field,
296         Object value);
297 
298     /**
299      * Returns true if the given oneof is set.
300      *
301      * @throws IllegalArgumentException if
302      *           {@code oneof.getContainingType() != getDescriptorForType()}.
303      */
hasOneof(Descriptors.OneofDescriptor oneof)304     boolean hasOneof(Descriptors.OneofDescriptor oneof);
305 
306     /**
307      * Clears the oneof.  This is exactly equivalent to calling the generated
308      * "clear" accessor method corresponding to the oneof.
309      */
clearOneof(Descriptors.OneofDescriptor oneof)310     MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);
311 
312     /**
313      * Obtains the FieldDescriptor if the given oneof is set. Returns null
314      * if no field is set.
315      */
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)316     Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);
317 
318     /**
319      * Parse the input stream into a sub field group defined based on either
320      * FieldDescriptor or the default instance.
321      */
parseGroup(CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)322     Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry,
323         Descriptors.FieldDescriptor descriptor, Message defaultInstance)
324         throws IOException;
325 
326     /**
327      * Parse the input stream into a sub field message defined based on either
328      * FieldDescriptor or the default instance.
329      */
parseMessage(CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)330     Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry,
331         Descriptors.FieldDescriptor descriptor, Message defaultInstance)
332         throws IOException;
333 
334     /**
335      * Parse from a ByteString into a sub field message defined based on either
336      * FieldDescriptor or the default instance.  There isn't a varint indicating
337      * the length of the message at the beginning of the input ByteString.
338      */
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance)339     Object parseMessageFromBytes(
340         ByteString bytes, ExtensionRegistryLite registry,
341         Descriptors.FieldDescriptor descriptor, Message defaultInstance)
342         throws IOException;
343 
344     /**
345      * Read a primitive field from input. Note that builders and mutable
346      * messages may use different Java types to represent a primtive field.
347      */
readPrimitiveField( CodedInputStream input, WireFormat.FieldType type, boolean checkUtf8)348     Object readPrimitiveField(
349         CodedInputStream input, WireFormat.FieldType type,
350         boolean checkUtf8) throws IOException;
351 
352     /**
353      * Returns a new merge target for a sub-field. When defaultInstance is
354      * provided, it indicates the descriptor is for an extension type, and
355      * implementations should create a new instance from the defaultInstance
356      * prototype directly.
357      */
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)358     MergeTarget newMergeTargetForField(
359         Descriptors.FieldDescriptor descriptor,
360         Message defaultInstance);
361 
362     /**
363      * Finishes the merge and returns the underlying object.
364      */
finish()365     Object finish();
366   }
367 
368   static class BuilderAdapter implements MergeTarget {
369 
370     private final Message.Builder builder;
371 
getDescriptorForType()372     public Descriptors.Descriptor getDescriptorForType() {
373       return builder.getDescriptorForType();
374     }
375 
BuilderAdapter(Message.Builder builder)376     public BuilderAdapter(Message.Builder builder) {
377       this.builder = builder;
378     }
379 
getField(Descriptors.FieldDescriptor field)380     public Object getField(Descriptors.FieldDescriptor field) {
381       return builder.getField(field);
382     }
383 
384     @Override
hasField(Descriptors.FieldDescriptor field)385     public boolean hasField(Descriptors.FieldDescriptor field) {
386       return builder.hasField(field);
387     }
388 
setField(Descriptors.FieldDescriptor field, Object value)389     public MergeTarget setField(Descriptors.FieldDescriptor field,
390         Object value) {
391       builder.setField(field, value);
392       return this;
393     }
394 
clearField(Descriptors.FieldDescriptor field)395     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
396       builder.clearField(field);
397       return this;
398     }
399 
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)400     public MergeTarget setRepeatedField(
401         Descriptors.FieldDescriptor field, int index, Object value) {
402       builder.setRepeatedField(field, index, value);
403       return this;
404     }
405 
addRepeatedField( Descriptors.FieldDescriptor field, Object value)406     public MergeTarget addRepeatedField(
407         Descriptors.FieldDescriptor field, Object value) {
408       builder.addRepeatedField(field, value);
409       return this;
410     }
411 
412     @Override
hasOneof(Descriptors.OneofDescriptor oneof)413     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
414       return builder.hasOneof(oneof);
415     }
416 
417     @Override
clearOneof(Descriptors.OneofDescriptor oneof)418     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
419       builder.clearOneof(oneof);
420       return this;
421     }
422 
423     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)424     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
425       return builder.getOneofFieldDescriptor(oneof);
426     }
427 
getContainerType()428     public ContainerType getContainerType() {
429       return ContainerType.MESSAGE;
430     }
431 
findExtensionByName( ExtensionRegistry registry, String name)432     public ExtensionRegistry.ExtensionInfo findExtensionByName(
433         ExtensionRegistry registry, String name) {
434       return registry.findImmutableExtensionByName(name);
435     }
436 
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)437     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
438         ExtensionRegistry registry, Descriptors.Descriptor containingType,
439         int fieldNumber) {
440       return registry.findImmutableExtensionByNumber(containingType,
441           fieldNumber);
442     }
443 
parseGroup(CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)444     public Object parseGroup(CodedInputStream input,
445         ExtensionRegistryLite extensionRegistry,
446         Descriptors.FieldDescriptor field, Message defaultInstance)
447         throws IOException {
448       Message.Builder subBuilder;
449       // When default instance is not null. The field is an extension field.
450       if (defaultInstance != null) {
451         subBuilder = defaultInstance.newBuilderForType();
452       } else {
453         subBuilder = builder.newBuilderForField(field);
454       }
455       if (!field.isRepeated()) {
456         Message originalMessage = (Message) getField(field);
457         if (originalMessage != null) {
458           subBuilder.mergeFrom(originalMessage);
459         }
460       }
461       input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
462       return subBuilder.buildPartial();
463     }
464 
parseMessage(CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)465     public Object parseMessage(CodedInputStream input,
466         ExtensionRegistryLite extensionRegistry,
467         Descriptors.FieldDescriptor field, Message defaultInstance)
468         throws IOException {
469       Message.Builder subBuilder;
470       // When default instance is not null. The field is an extension field.
471       if (defaultInstance != null) {
472         subBuilder = defaultInstance.newBuilderForType();
473       } else {
474         subBuilder = builder.newBuilderForField(field);
475       }
476       if (!field.isRepeated()) {
477         Message originalMessage = (Message) getField(field);
478         if (originalMessage != null) {
479           subBuilder.mergeFrom(originalMessage);
480         }
481       }
482       input.readMessage(subBuilder, extensionRegistry);
483       return subBuilder.buildPartial();
484     }
485 
parseMessageFromBytes(ByteString bytes, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)486     public Object parseMessageFromBytes(ByteString bytes,
487         ExtensionRegistryLite extensionRegistry,
488         Descriptors.FieldDescriptor field, Message defaultInstance)
489         throws IOException {
490       Message.Builder subBuilder;
491       // When default instance is not null. The field is an extension field.
492       if (defaultInstance != null) {
493         subBuilder = defaultInstance.newBuilderForType();
494       } else {
495         subBuilder = builder.newBuilderForField(field);
496       }
497       if (!field.isRepeated()) {
498         Message originalMessage = (Message) getField(field);
499         if (originalMessage != null) {
500           subBuilder.mergeFrom(originalMessage);
501         }
502       }
503       subBuilder.mergeFrom(bytes, extensionRegistry);
504       return subBuilder.buildPartial();
505     }
506 
newMergeTargetForField(Descriptors.FieldDescriptor field, Message defaultInstance)507     public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
508         Message defaultInstance) {
509       if (defaultInstance != null) {
510         return new BuilderAdapter(
511             defaultInstance.newBuilderForType());
512       } else {
513         return new BuilderAdapter(builder.newBuilderForField(field));
514       }
515     }
516 
readPrimitiveField( CodedInputStream input, WireFormat.FieldType type, boolean checkUtf8)517     public Object readPrimitiveField(
518         CodedInputStream input, WireFormat.FieldType type,
519         boolean checkUtf8) throws IOException {
520       return FieldSet.readPrimitiveField(input, type, checkUtf8);
521     }
522 
finish()523     public Object finish() {
524       return builder.buildPartial();
525     }
526   }
527 
528 
529   static class ExtensionAdapter implements MergeTarget {
530 
531     private final FieldSet<Descriptors.FieldDescriptor> extensions;
532 
ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions)533     ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
534       this.extensions = extensions;
535     }
536 
getDescriptorForType()537     public Descriptors.Descriptor getDescriptorForType() {
538       throw new UnsupportedOperationException(
539           "getDescriptorForType() called on FieldSet object");
540     }
541 
getField(Descriptors.FieldDescriptor field)542     public Object getField(Descriptors.FieldDescriptor field) {
543       return extensions.getField(field);
544     }
545 
hasField(Descriptors.FieldDescriptor field)546     public boolean hasField(Descriptors.FieldDescriptor field) {
547       return extensions.hasField(field);
548     }
549 
setField(Descriptors.FieldDescriptor field, Object value)550     public MergeTarget setField(Descriptors.FieldDescriptor field,
551         Object value) {
552       extensions.setField(field, value);
553       return this;
554     }
555 
clearField(Descriptors.FieldDescriptor field)556     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
557       extensions.clearField(field);
558       return this;
559     }
560 
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)561     public MergeTarget setRepeatedField(
562         Descriptors.FieldDescriptor field, int index, Object value) {
563       extensions.setRepeatedField(field, index, value);
564       return this;
565     }
566 
addRepeatedField( Descriptors.FieldDescriptor field, Object value)567     public MergeTarget addRepeatedField(
568         Descriptors.FieldDescriptor field, Object value) {
569       extensions.addRepeatedField(field, value);
570       return this;
571     }
572 
573     @Override
hasOneof(Descriptors.OneofDescriptor oneof)574     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
575       return false;
576     }
577 
578     @Override
clearOneof(Descriptors.OneofDescriptor oneof)579     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
580       // Nothing to clear.
581       return this;
582     }
583 
584     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)585     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
586       return null;
587     }
588 
getContainerType()589     public ContainerType getContainerType() {
590       return ContainerType.EXTENSION_SET;
591     }
592 
findExtensionByName( ExtensionRegistry registry, String name)593     public ExtensionRegistry.ExtensionInfo findExtensionByName(
594         ExtensionRegistry registry, String name) {
595       return registry.findImmutableExtensionByName(name);
596     }
597 
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)598     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
599         ExtensionRegistry registry, Descriptors.Descriptor containingType,
600         int fieldNumber) {
601       return registry.findImmutableExtensionByNumber(containingType,
602           fieldNumber);
603     }
604 
parseGroup(CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)605     public Object parseGroup(CodedInputStream input,
606         ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
607         Message defaultInstance) throws IOException {
608       Message.Builder subBuilder =
609           defaultInstance.newBuilderForType();
610       if (!field.isRepeated()) {
611         Message originalMessage = (Message) getField(field);
612         if (originalMessage != null) {
613           subBuilder.mergeFrom(originalMessage);
614         }
615       }
616       input.readGroup(field.getNumber(), subBuilder, registry);
617       return subBuilder.buildPartial();
618     }
619 
parseMessage(CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)620     public Object parseMessage(CodedInputStream input,
621         ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
622         Message defaultInstance) throws IOException {
623       Message.Builder subBuilder =
624           defaultInstance.newBuilderForType();
625       if (!field.isRepeated()) {
626         Message originalMessage = (Message) getField(field);
627         if (originalMessage != null) {
628           subBuilder.mergeFrom(originalMessage);
629         }
630       }
631       input.readMessage(subBuilder, registry);
632       return subBuilder.buildPartial();
633     }
634 
parseMessageFromBytes(ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)635     public Object parseMessageFromBytes(ByteString bytes,
636         ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
637         Message defaultInstance) throws IOException {
638       Message.Builder subBuilder =  defaultInstance.newBuilderForType();
639       if (!field.isRepeated()) {
640         Message originalMessage = (Message) getField(field);
641         if (originalMessage != null) {
642           subBuilder.mergeFrom(originalMessage);
643         }
644       }
645       subBuilder.mergeFrom(bytes, registry);
646       return subBuilder.buildPartial();
647     }
648 
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)649     public MergeTarget newMergeTargetForField(
650         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
651       throw new UnsupportedOperationException(
652           "newMergeTargetForField() called on FieldSet object");
653     }
654 
readPrimitiveField( CodedInputStream input, WireFormat.FieldType type, boolean checkUtf8)655     public Object readPrimitiveField(
656         CodedInputStream input, WireFormat.FieldType type,
657         boolean checkUtf8) throws IOException {
658       return FieldSet.readPrimitiveField(input, type, checkUtf8);
659     }
660 
finish()661     public Object finish() {
662       throw new UnsupportedOperationException(
663           "finish() called on FieldSet object");
664     }
665   }
666 
667   /**
668    * Parses a single field into MergeTarget. The target can be Message.Builder,
669    * FieldSet or MutableMessage.
670    *
671    * Package-private because it is used by GeneratedMessage.ExtendableMessage.
672    *
673    * @param tag The tag, which should have already been read.
674    * @return {@code true} unless the tag is an end-group tag.
675    */
mergeFieldFrom( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target, int tag)676   static boolean mergeFieldFrom(
677       CodedInputStream input,
678       UnknownFieldSet.Builder unknownFields,
679       ExtensionRegistryLite extensionRegistry,
680       Descriptors.Descriptor type,
681       MergeTarget target,
682       int tag) throws IOException {
683     if (type.getOptions().getMessageSetWireFormat() &&
684         tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
685       mergeMessageSetExtensionFromCodedStream(
686           input, unknownFields, extensionRegistry, type, target);
687       return true;
688     }
689 
690     final int wireType = WireFormat.getTagWireType(tag);
691     final int fieldNumber = WireFormat.getTagFieldNumber(tag);
692 
693     final Descriptors.FieldDescriptor field;
694     Message defaultInstance = null;
695 
696     if (type.isExtensionNumber(fieldNumber)) {
697       // extensionRegistry may be either ExtensionRegistry or
698       // ExtensionRegistryLite.  Since the type we are parsing is a full
699       // message, only a full ExtensionRegistry could possibly contain
700       // extensions of it.  Otherwise we will treat the registry as if it
701       // were empty.
702       if (extensionRegistry instanceof ExtensionRegistry) {
703         final ExtensionRegistry.ExtensionInfo extension =
704             target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
705                 type, fieldNumber);
706         if (extension == null) {
707           field = null;
708         } else {
709           field = extension.descriptor;
710           defaultInstance = extension.defaultInstance;
711           if (defaultInstance == null &&
712               field.getJavaType()
713                   == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
714             throw new IllegalStateException(
715                 "Message-typed extension lacked default instance: " +
716                     field.getFullName());
717           }
718         }
719       } else {
720         field = null;
721       }
722     } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
723       field = type.findFieldByNumber(fieldNumber);
724     } else {
725       field = null;
726     }
727 
728     boolean unknown = false;
729     boolean packed = false;
730     if (field == null) {
731       unknown = true;  // Unknown field.
732     } else if (wireType == FieldSet.getWireFormatForFieldType(
733         field.getLiteType(),
734         false  /* isPacked */)) {
735       packed = false;
736     } else if (field.isPackable() &&
737         wireType == FieldSet.getWireFormatForFieldType(
738             field.getLiteType(),
739             true  /* isPacked */)) {
740       packed = true;
741     } else {
742       unknown = true;  // Unknown wire type.
743     }
744 
745     if (unknown) {  // Unknown field or wrong wire type.  Skip.
746       return unknownFields.mergeFieldFrom(tag, input);
747     }
748 
749     if (packed) {
750       final int length = input.readRawVarint32();
751       final int limit = input.pushLimit(length);
752       if (field.getLiteType() == WireFormat.FieldType.ENUM) {
753         while (input.getBytesUntilLimit() > 0) {
754           final int rawValue = input.readEnum();
755           final Object value = field.getEnumType().findValueByNumber(rawValue);
756           if (value == null) {
757             // If the number isn't recognized as a valid value for this
758             // enum, drop it (don't even add it to unknownFields).
759             return true;
760           }
761           target.addRepeatedField(field, value);
762         }
763       } else {
764         while (input.getBytesUntilLimit() > 0) {
765           final Object value =
766               target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
767           target.addRepeatedField(field, value);
768         }
769       }
770       input.popLimit(limit);
771     } else {
772       final Object value;
773       switch (field.getType()) {
774         case GROUP: {
775           value = target
776               .parseGroup(input, extensionRegistry, field, defaultInstance);
777           break;
778         }
779         case MESSAGE: {
780           value = target
781               .parseMessage(input, extensionRegistry, field, defaultInstance);
782           break;
783         }
784         case ENUM:
785           final int rawValue = input.readEnum();
786           value = field.getEnumType().findValueByNumber(rawValue);
787           // If the number isn't recognized as a valid value for this enum,
788           // drop it.
789           if (value == null) {
790             unknownFields.mergeVarintField(fieldNumber, rawValue);
791             return true;
792           }
793           break;
794         default:
795           value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
796           break;
797       }
798 
799       if (field.isRepeated()) {
800         target.addRepeatedField(field, value);
801       } else {
802         target.setField(field, value);
803       }
804     }
805 
806     return true;
807   }
808 
809   /**
810    * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into
811    * MergeTarget.
812    */
mergeMessageSetExtensionFromCodedStream( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target)813   private static void mergeMessageSetExtensionFromCodedStream(
814       CodedInputStream input,
815       UnknownFieldSet.Builder unknownFields,
816       ExtensionRegistryLite extensionRegistry,
817       Descriptors.Descriptor type,
818       MergeTarget target) throws IOException {
819 
820     // The wire format for MessageSet is:
821     //   message MessageSet {
822     //     repeated group Item = 1 {
823     //       required int32 typeId = 2;
824     //       required bytes message = 3;
825     //     }
826     //   }
827     // "typeId" is the extension's field number.  The extension can only be
828     // a message type, where "message" contains the encoded bytes of that
829     // message.
830     //
831     // In practice, we will probably never see a MessageSet item in which
832     // the message appears before the type ID, or where either field does not
833     // appear exactly once.  However, in theory such cases are valid, so we
834     // should be prepared to accept them.
835 
836     int typeId = 0;
837     ByteString rawBytes = null; // If we encounter "message" before "typeId"
838     ExtensionRegistry.ExtensionInfo extension = null;
839 
840     // Read bytes from input, if we get it's type first then parse it eagerly,
841     // otherwise we store the raw bytes in a local variable.
842     while (true) {
843       final int tag = input.readTag();
844       if (tag == 0) {
845         break;
846       }
847 
848       if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
849         typeId = input.readUInt32();
850         if (typeId != 0) {
851           // extensionRegistry may be either ExtensionRegistry or
852           // ExtensionRegistryLite. Since the type we are parsing is a full
853           // message, only a full ExtensionRegistry could possibly contain
854           // extensions of it. Otherwise we will treat the registry as if it
855           // were empty.
856           if (extensionRegistry instanceof ExtensionRegistry) {
857             extension = target.findExtensionByNumber(
858                 (ExtensionRegistry) extensionRegistry, type, typeId);
859           }
860         }
861 
862       } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
863         if (typeId != 0) {
864           if (extension != null &&
865               ExtensionRegistryLite.isEagerlyParseMessageSets()) {
866             // We already know the type, so we can parse directly from the
867             // input with no copying.  Hooray!
868             eagerlyMergeMessageSetExtension(
869                 input, extension, extensionRegistry, target);
870             rawBytes = null;
871             continue;
872           }
873         }
874         // We haven't seen a type ID yet or we want parse message lazily.
875         rawBytes = input.readBytes();
876 
877       } else { // Unknown tag. Skip it.
878         if (!input.skipField(tag)) {
879           break; // End of group
880         }
881       }
882     }
883     input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
884 
885     // Process the raw bytes.
886     if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
887       if (extension != null) { // We known the type
888         mergeMessageSetExtensionFromBytes(
889             rawBytes, extension, extensionRegistry, target);
890       } else { // We don't know how to parse this. Ignore it.
891         if (rawBytes != null) {
892           unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
893               .addLengthDelimited(rawBytes).build());
894         }
895       }
896     }
897   }
898 
mergeMessageSetExtensionFromBytes( ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)899   private static void mergeMessageSetExtensionFromBytes(
900       ByteString rawBytes,
901       ExtensionRegistry.ExtensionInfo extension,
902       ExtensionRegistryLite extensionRegistry,
903       MergeTarget target) throws IOException {
904 
905     Descriptors.FieldDescriptor field = extension.descriptor;
906     boolean hasOriginalValue = target.hasField(field);
907 
908     if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
909       // If the field already exists, we just parse the field.
910       Object value = target.parseMessageFromBytes(
911           rawBytes, extensionRegistry,field, extension.defaultInstance);
912       target.setField(field, value);
913     } else {
914       // Use LazyField to load MessageSet lazily.
915       LazyField lazyField = new LazyField(
916           extension.defaultInstance, extensionRegistry, rawBytes);
917       target.setField(field, lazyField);
918     }
919   }
920 
eagerlyMergeMessageSetExtension( CodedInputStream input, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)921   private static void eagerlyMergeMessageSetExtension(
922       CodedInputStream input,
923       ExtensionRegistry.ExtensionInfo extension,
924       ExtensionRegistryLite extensionRegistry,
925       MergeTarget target) throws IOException {
926     Descriptors.FieldDescriptor field = extension.descriptor;
927     Object value = target.parseMessage(input, extensionRegistry, field,
928                                        extension.defaultInstance);
929     target.setField(field, value);
930   }
931 }
932