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