• 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   static class BuilderAdapter implements MergeTarget {
370 
371     private final Message.Builder builder;
372 
373     @Override
getDescriptorForType()374     public Descriptors.Descriptor getDescriptorForType() {
375       return builder.getDescriptorForType();
376     }
377 
BuilderAdapter(Message.Builder builder)378     public BuilderAdapter(Message.Builder builder) {
379       this.builder = builder;
380     }
381 
382     @Override
getField(Descriptors.FieldDescriptor field)383     public Object getField(Descriptors.FieldDescriptor field) {
384       return builder.getField(field);
385     }
386 
387     @Override
hasField(Descriptors.FieldDescriptor field)388     public boolean hasField(Descriptors.FieldDescriptor field) {
389       return builder.hasField(field);
390     }
391 
392     @Override
setField(Descriptors.FieldDescriptor field, Object value)393     public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
394       builder.setField(field, value);
395       return this;
396     }
397 
398     @Override
clearField(Descriptors.FieldDescriptor field)399     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
400       builder.clearField(field);
401       return this;
402     }
403 
404     @Override
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)405     public MergeTarget setRepeatedField(
406         Descriptors.FieldDescriptor field, int index, Object value) {
407       builder.setRepeatedField(field, index, value);
408       return this;
409     }
410 
411     @Override
addRepeatedField(Descriptors.FieldDescriptor field, Object value)412     public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
413       builder.addRepeatedField(field, value);
414       return this;
415     }
416 
417     @Override
hasOneof(Descriptors.OneofDescriptor oneof)418     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
419       return builder.hasOneof(oneof);
420     }
421 
422     @Override
clearOneof(Descriptors.OneofDescriptor oneof)423     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
424       builder.clearOneof(oneof);
425       return this;
426     }
427 
428     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)429     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
430       return builder.getOneofFieldDescriptor(oneof);
431     }
432 
433     @Override
getContainerType()434     public ContainerType getContainerType() {
435       return ContainerType.MESSAGE;
436     }
437 
438     @Override
findExtensionByName( ExtensionRegistry registry, String name)439     public ExtensionRegistry.ExtensionInfo findExtensionByName(
440         ExtensionRegistry registry, String name) {
441       return registry.findImmutableExtensionByName(name);
442     }
443 
444     @Override
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)445     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
446         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
447       return registry.findImmutableExtensionByNumber(containingType,
448           fieldNumber);
449     }
450 
451     @Override
parseGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)452     public Object parseGroup(
453         CodedInputStream input,
454         ExtensionRegistryLite extensionRegistry,
455         Descriptors.FieldDescriptor field,
456         Message defaultInstance)
457         throws IOException {
458       Message.Builder subBuilder;
459       // When default instance is not null. The field is an extension field.
460       if (defaultInstance != null) {
461         subBuilder = defaultInstance.newBuilderForType();
462       } else {
463         subBuilder = builder.newBuilderForField(field);
464       }
465       if (!field.isRepeated()) {
466         Message originalMessage = (Message) getField(field);
467         if (originalMessage != null) {
468           subBuilder.mergeFrom(originalMessage);
469         }
470       }
471       input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
472       return subBuilder.buildPartial();
473     }
474 
475     @Override
parseMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)476     public Object parseMessage(
477         CodedInputStream input,
478         ExtensionRegistryLite extensionRegistry,
479         Descriptors.FieldDescriptor field,
480         Message defaultInstance)
481         throws IOException {
482       Message.Builder subBuilder;
483       // When default instance is not null. The field is an extension field.
484       if (defaultInstance != null) {
485         subBuilder = defaultInstance.newBuilderForType();
486       } else {
487         subBuilder = builder.newBuilderForField(field);
488       }
489       if (!field.isRepeated()) {
490         Message originalMessage = (Message) getField(field);
491         if (originalMessage != null) {
492           subBuilder.mergeFrom(originalMessage);
493         }
494       }
495       input.readMessage(subBuilder, extensionRegistry);
496       return subBuilder.buildPartial();
497     }
498 
499     @Override
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)500     public Object parseMessageFromBytes(
501         ByteString bytes,
502         ExtensionRegistryLite extensionRegistry,
503         Descriptors.FieldDescriptor field,
504         Message defaultInstance)
505         throws IOException {
506       Message.Builder subBuilder;
507       // When default instance is not null. The field is an extension field.
508       if (defaultInstance != null) {
509         subBuilder = defaultInstance.newBuilderForType();
510       } else {
511         subBuilder = builder.newBuilderForField(field);
512       }
513       if (!field.isRepeated()) {
514         Message originalMessage = (Message) getField(field);
515         if (originalMessage != null) {
516           subBuilder.mergeFrom(originalMessage);
517         }
518       }
519       subBuilder.mergeFrom(bytes, extensionRegistry);
520       return subBuilder.buildPartial();
521     }
522 
523     @Override
newMergeTargetForField( Descriptors.FieldDescriptor field, Message defaultInstance)524     public MergeTarget newMergeTargetForField(
525         Descriptors.FieldDescriptor field, Message defaultInstance) {
526       if (defaultInstance != null) {
527         return new BuilderAdapter(
528             defaultInstance.newBuilderForType());
529       } else {
530         return new BuilderAdapter(builder.newBuilderForField(field));
531       }
532     }
533 
534     @Override
getUtf8Validation(Descriptors.FieldDescriptor descriptor)535     public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
536       if (descriptor.needsUtf8Check()) {
537         return WireFormat.Utf8Validation.STRICT;
538       }
539       // TODO(liujisi): support lazy strings for repeated fields.
540       if (!descriptor.isRepeated()
541           && builder instanceof GeneratedMessage.Builder) {
542         return WireFormat.Utf8Validation.LAZY;
543       }
544       return WireFormat.Utf8Validation.LOOSE;
545     }
546 
547     @Override
finish()548     public Object finish() {
549       return builder.buildPartial();
550     }
551   }
552 
553 
554   static class ExtensionAdapter implements MergeTarget {
555 
556     private final FieldSet<Descriptors.FieldDescriptor> extensions;
557 
ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions)558     ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
559       this.extensions = extensions;
560     }
561 
562     @Override
getDescriptorForType()563     public Descriptors.Descriptor getDescriptorForType() {
564       throw new UnsupportedOperationException(
565           "getDescriptorForType() called on FieldSet object");
566     }
567 
568     @Override
getField(Descriptors.FieldDescriptor field)569     public Object getField(Descriptors.FieldDescriptor field) {
570       return extensions.getField(field);
571     }
572 
573     @Override
hasField(Descriptors.FieldDescriptor field)574     public boolean hasField(Descriptors.FieldDescriptor field) {
575       return extensions.hasField(field);
576     }
577 
578     @Override
setField(Descriptors.FieldDescriptor field, Object value)579     public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
580       extensions.setField(field, value);
581       return this;
582     }
583 
584     @Override
clearField(Descriptors.FieldDescriptor field)585     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
586       extensions.clearField(field);
587       return this;
588     }
589 
590     @Override
setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)591     public MergeTarget setRepeatedField(
592         Descriptors.FieldDescriptor field, int index, Object value) {
593       extensions.setRepeatedField(field, index, value);
594       return this;
595     }
596 
597     @Override
addRepeatedField(Descriptors.FieldDescriptor field, Object value)598     public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
599       extensions.addRepeatedField(field, value);
600       return this;
601     }
602 
603     @Override
hasOneof(Descriptors.OneofDescriptor oneof)604     public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
605       return false;
606     }
607 
608     @Override
clearOneof(Descriptors.OneofDescriptor oneof)609     public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
610       // Nothing to clear.
611       return this;
612     }
613 
614     @Override
getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)615     public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
616       return null;
617     }
618 
619     @Override
getContainerType()620     public ContainerType getContainerType() {
621       return ContainerType.EXTENSION_SET;
622     }
623 
624     @Override
findExtensionByName( ExtensionRegistry registry, String name)625     public ExtensionRegistry.ExtensionInfo findExtensionByName(
626         ExtensionRegistry registry, String name) {
627       return registry.findImmutableExtensionByName(name);
628     }
629 
630     @Override
findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)631     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
632         ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
633       return registry.findImmutableExtensionByNumber(containingType,
634           fieldNumber);
635     }
636 
637     @Override
parseGroup( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)638     public Object parseGroup(
639         CodedInputStream input,
640         ExtensionRegistryLite registry,
641         Descriptors.FieldDescriptor field,
642         Message defaultInstance)
643         throws IOException {
644       Message.Builder subBuilder =
645           defaultInstance.newBuilderForType();
646       if (!field.isRepeated()) {
647         Message originalMessage = (Message) getField(field);
648         if (originalMessage != null) {
649           subBuilder.mergeFrom(originalMessage);
650         }
651       }
652       input.readGroup(field.getNumber(), subBuilder, registry);
653       return subBuilder.buildPartial();
654     }
655 
656     @Override
parseMessage( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)657     public Object parseMessage(
658         CodedInputStream input,
659         ExtensionRegistryLite registry,
660         Descriptors.FieldDescriptor field,
661         Message defaultInstance)
662         throws IOException {
663       Message.Builder subBuilder =
664           defaultInstance.newBuilderForType();
665       if (!field.isRepeated()) {
666         Message originalMessage = (Message) getField(field);
667         if (originalMessage != null) {
668           subBuilder.mergeFrom(originalMessage);
669         }
670       }
671       input.readMessage(subBuilder, registry);
672       return subBuilder.buildPartial();
673     }
674 
675     @Override
parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)676     public Object parseMessageFromBytes(
677         ByteString bytes,
678         ExtensionRegistryLite registry,
679         Descriptors.FieldDescriptor field,
680         Message defaultInstance)
681         throws IOException {
682       Message.Builder subBuilder =  defaultInstance.newBuilderForType();
683       if (!field.isRepeated()) {
684         Message originalMessage = (Message) getField(field);
685         if (originalMessage != null) {
686           subBuilder.mergeFrom(originalMessage);
687         }
688       }
689       subBuilder.mergeFrom(bytes, registry);
690       return subBuilder.buildPartial();
691     }
692 
693     @Override
newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)694     public MergeTarget newMergeTargetForField(
695         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
696       throw new UnsupportedOperationException(
697           "newMergeTargetForField() called on FieldSet object");
698     }
699 
700     @Override
getUtf8Validation(Descriptors.FieldDescriptor descriptor)701     public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
702       if (descriptor.needsUtf8Check()) {
703         return WireFormat.Utf8Validation.STRICT;
704       }
705       // TODO(liujisi): support lazy strings for ExtesnsionSet.
706       return WireFormat.Utf8Validation.LOOSE;
707     }
708 
709     @Override
finish()710     public Object finish() {
711       throw new UnsupportedOperationException(
712           "finish() called on FieldSet object");
713     }
714   }
715 
716   /**
717    * Parses a single field into MergeTarget. The target can be Message.Builder,
718    * FieldSet or MutableMessage.
719    *
720    * Package-private because it is used by GeneratedMessage.ExtendableMessage.
721    *
722    * @param tag The tag, which should have already been read.
723    * @return {@code true} unless the tag is an end-group tag.
724    */
mergeFieldFrom( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target, int tag)725   static boolean mergeFieldFrom(
726       CodedInputStream input,
727       UnknownFieldSet.Builder unknownFields,
728       ExtensionRegistryLite extensionRegistry,
729       Descriptors.Descriptor type,
730       MergeTarget target,
731       int tag) throws IOException {
732     if (type.getOptions().getMessageSetWireFormat() &&
733         tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
734       mergeMessageSetExtensionFromCodedStream(
735           input, unknownFields, extensionRegistry, type, target);
736       return true;
737     }
738 
739     final int wireType = WireFormat.getTagWireType(tag);
740     final int fieldNumber = WireFormat.getTagFieldNumber(tag);
741 
742     final Descriptors.FieldDescriptor field;
743     Message defaultInstance = null;
744 
745     if (type.isExtensionNumber(fieldNumber)) {
746       // extensionRegistry may be either ExtensionRegistry or
747       // ExtensionRegistryLite.  Since the type we are parsing is a full
748       // message, only a full ExtensionRegistry could possibly contain
749       // extensions of it.  Otherwise we will treat the registry as if it
750       // were empty.
751       if (extensionRegistry instanceof ExtensionRegistry) {
752         final ExtensionRegistry.ExtensionInfo extension =
753             target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
754                 type, fieldNumber);
755         if (extension == null) {
756           field = null;
757         } else {
758           field = extension.descriptor;
759           defaultInstance = extension.defaultInstance;
760           if (defaultInstance == null &&
761               field.getJavaType()
762                   == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
763             throw new IllegalStateException(
764                 "Message-typed extension lacked default instance: " +
765                     field.getFullName());
766           }
767         }
768       } else {
769         field = null;
770       }
771     } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
772       field = type.findFieldByNumber(fieldNumber);
773     } else {
774       field = null;
775     }
776 
777     boolean unknown = false;
778     boolean packed = false;
779     if (field == null) {
780       unknown = true;  // Unknown field.
781     } else if (wireType == FieldSet.getWireFormatForFieldType(
782         field.getLiteType(),
783         false  /* isPacked */)) {
784       packed = false;
785     } else if (field.isPackable() &&
786         wireType == FieldSet.getWireFormatForFieldType(
787             field.getLiteType(),
788             true  /* isPacked */)) {
789       packed = true;
790     } else {
791       unknown = true;  // Unknown wire type.
792     }
793 
794     if (unknown) {  // Unknown field or wrong wire type.  Skip.
795       return unknownFields.mergeFieldFrom(tag, input);
796     }
797 
798     if (packed) {
799       final int length = input.readRawVarint32();
800       final int limit = input.pushLimit(length);
801       if (field.getLiteType() == WireFormat.FieldType.ENUM) {
802         while (input.getBytesUntilLimit() > 0) {
803           final int rawValue = input.readEnum();
804           if (field.getFile().supportsUnknownEnumValue()) {
805             target.addRepeatedField(field,
806                 field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue));
807           } else {
808             final Object value = field.getEnumType().findValueByNumber(rawValue);
809             if (value == null) {
810               // If the number isn't recognized as a valid value for this
811               // enum, drop it (don't even add it to unknownFields).
812               return true;
813             }
814             target.addRepeatedField(field, value);
815           }
816         }
817       } else {
818         while (input.getBytesUntilLimit() > 0) {
819           final Object value = WireFormat.readPrimitiveField(
820               input, field.getLiteType(), target.getUtf8Validation(field));
821           target.addRepeatedField(field, value);
822         }
823       }
824       input.popLimit(limit);
825     } else {
826       final Object value;
827       switch (field.getType()) {
828         case GROUP: {
829           value = target
830               .parseGroup(input, extensionRegistry, field, defaultInstance);
831           break;
832         }
833         case MESSAGE: {
834           value = target
835               .parseMessage(input, extensionRegistry, field, defaultInstance);
836           break;
837         }
838         case ENUM:
839           final int rawValue = input.readEnum();
840           if (field.getFile().supportsUnknownEnumValue()) {
841             value = field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue);
842           } else {
843             value = field.getEnumType().findValueByNumber(rawValue);
844             // If the number isn't recognized as a valid value for this enum,
845             // drop it.
846             if (value == null) {
847               unknownFields.mergeVarintField(fieldNumber, rawValue);
848               return true;
849             }
850           }
851           break;
852         default:
853           value = WireFormat.readPrimitiveField(
854               input, field.getLiteType(), target.getUtf8Validation(field));
855           break;
856       }
857 
858       if (field.isRepeated()) {
859         target.addRepeatedField(field, value);
860       } else {
861         target.setField(field, value);
862       }
863     }
864 
865     return true;
866   }
867 
868   /**
869    * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into
870    * MergeTarget.
871    */
mergeMessageSetExtensionFromCodedStream( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target)872   private static void mergeMessageSetExtensionFromCodedStream(
873       CodedInputStream input,
874       UnknownFieldSet.Builder unknownFields,
875       ExtensionRegistryLite extensionRegistry,
876       Descriptors.Descriptor type,
877       MergeTarget target) throws IOException {
878 
879     // The wire format for MessageSet is:
880     //   message MessageSet {
881     //     repeated group Item = 1 {
882     //       required int32 typeId = 2;
883     //       required bytes message = 3;
884     //     }
885     //   }
886     // "typeId" is the extension's field number.  The extension can only be
887     // a message type, where "message" contains the encoded bytes of that
888     // message.
889     //
890     // In practice, we will probably never see a MessageSet item in which
891     // the message appears before the type ID, or where either field does not
892     // appear exactly once.  However, in theory such cases are valid, so we
893     // should be prepared to accept them.
894 
895     int typeId = 0;
896     ByteString rawBytes = null; // If we encounter "message" before "typeId"
897     ExtensionRegistry.ExtensionInfo extension = null;
898 
899     // Read bytes from input, if we get it's type first then parse it eagerly,
900     // otherwise we store the raw bytes in a local variable.
901     while (true) {
902       final int tag = input.readTag();
903       if (tag == 0) {
904         break;
905       }
906 
907       if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
908         typeId = input.readUInt32();
909         if (typeId != 0) {
910           // extensionRegistry may be either ExtensionRegistry or
911           // ExtensionRegistryLite. Since the type we are parsing is a full
912           // message, only a full ExtensionRegistry could possibly contain
913           // extensions of it. Otherwise we will treat the registry as if it
914           // were empty.
915           if (extensionRegistry instanceof ExtensionRegistry) {
916             extension = target.findExtensionByNumber(
917                 (ExtensionRegistry) extensionRegistry, type, typeId);
918           }
919         }
920 
921       } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
922         if (typeId != 0) {
923           if (extension != null &&
924               ExtensionRegistryLite.isEagerlyParseMessageSets()) {
925             // We already know the type, so we can parse directly from the
926             // input with no copying.  Hooray!
927             eagerlyMergeMessageSetExtension(
928                 input, extension, extensionRegistry, target);
929             rawBytes = null;
930             continue;
931           }
932         }
933         // We haven't seen a type ID yet or we want parse message lazily.
934         rawBytes = input.readBytes();
935 
936       } else { // Unknown tag. Skip it.
937         if (!input.skipField(tag)) {
938           break; // End of group
939         }
940       }
941     }
942     input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
943 
944     // Process the raw bytes.
945     if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
946       if (extension != null) { // We known the type
947         mergeMessageSetExtensionFromBytes(
948             rawBytes, extension, extensionRegistry, target);
949       } else { // We don't know how to parse this. Ignore it.
950         if (rawBytes != null) {
951           unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
952               .addLengthDelimited(rawBytes).build());
953         }
954       }
955     }
956   }
957 
mergeMessageSetExtensionFromBytes( ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)958   private static void mergeMessageSetExtensionFromBytes(
959       ByteString rawBytes,
960       ExtensionRegistry.ExtensionInfo extension,
961       ExtensionRegistryLite extensionRegistry,
962       MergeTarget target) throws IOException {
963 
964     Descriptors.FieldDescriptor field = extension.descriptor;
965     boolean hasOriginalValue = target.hasField(field);
966 
967     if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
968       // If the field already exists, we just parse the field.
969       Object value = target.parseMessageFromBytes(
970           rawBytes, extensionRegistry,field, extension.defaultInstance);
971       target.setField(field, value);
972     } else {
973       // Use LazyField to load MessageSet lazily.
974       LazyField lazyField = new LazyField(
975           extension.defaultInstance, extensionRegistry, rawBytes);
976       target.setField(field, lazyField);
977     }
978   }
979 
eagerlyMergeMessageSetExtension( CodedInputStream input, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)980   private static void eagerlyMergeMessageSetExtension(
981       CodedInputStream input,
982       ExtensionRegistry.ExtensionInfo extension,
983       ExtensionRegistryLite extensionRegistry,
984       MergeTarget target) throws IOException {
985     Descriptors.FieldDescriptor field = extension.descriptor;
986     Object value = target.parseMessage(input, extensionRegistry, field,
987                                        extension.defaultInstance);
988     target.setField(field, value);
989   }
990 }
991