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