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