Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      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.Descriptor;
     34 import com.google.protobuf.Descriptors.EnumValueDescriptor;
     35 import com.google.protobuf.Descriptors.FieldDescriptor;
     36 
     37 import java.io.IOException;
     38 import java.lang.reflect.Method;
     39 import java.lang.reflect.InvocationTargetException;
     40 import java.util.ArrayList;
     41 import java.util.Collections;
     42 import java.util.Iterator;
     43 import java.util.List;
     44 import java.util.Map;
     45 import java.util.TreeMap;
     46 
     47 /**
     48  * All generated protocol message classes extend this class.  This class
     49  * implements most of the Message and Builder interfaces using Java reflection.
     50  * Users can ignore this class and pretend that generated messages implement
     51  * the Message interface directly.
     52  *
     53  * @author kenton (at) google.com Kenton Varda
     54  */
     55 public abstract class GeneratedMessage extends AbstractMessage {
     56   protected GeneratedMessage() {}
     57 
     58   private UnknownFieldSet unknownFields = UnknownFieldSet.getDefaultInstance();
     59 
     60   /**
     61    * Get the FieldAccessorTable for this type.  We can't have the message
     62    * class pass this in to the constructor because of bootstrapping trouble
     63    * with DescriptorProtos.
     64    */
     65   protected abstract FieldAccessorTable internalGetFieldAccessorTable();
     66 
     67   public Descriptor getDescriptorForType() {
     68     return internalGetFieldAccessorTable().descriptor;
     69   }
     70 
     71   /** Internal helper which returns a mutable map. */
     72   private Map<FieldDescriptor, Object> getAllFieldsMutable() {
     73     final TreeMap<FieldDescriptor, Object> result =
     74       new TreeMap<FieldDescriptor, Object>();
     75     final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
     76     for (final FieldDescriptor field : descriptor.getFields()) {
     77       if (field.isRepeated()) {
     78         final List value = (List) getField(field);
     79         if (!value.isEmpty()) {
     80           result.put(field, value);
     81         }
     82       } else {
     83         if (hasField(field)) {
     84           result.put(field, getField(field));
     85         }
     86       }
     87     }
     88     return result;
     89   }
     90 
     91   @Override
     92   public boolean isInitialized() {
     93     for (final FieldDescriptor field : getDescriptorForType().getFields()) {
     94       // Check that all required fields are present.
     95       if (field.isRequired()) {
     96         if (!hasField(field)) {
     97           return false;
     98         }
     99       }
    100       // Check that embedded messages are initialized.
    101       if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
    102         if (field.isRepeated()) {
    103           @SuppressWarnings("unchecked") final
    104           List<Message> messageList = (List<Message>) getField(field);
    105           for (final Message element : messageList) {
    106             if (!element.isInitialized()) {
    107               return false;
    108             }
    109           }
    110         } else {
    111           if (hasField(field) && !((Message) getField(field)).isInitialized()) {
    112             return false;
    113           }
    114         }
    115       }
    116     }
    117 
    118     return true;
    119   }
    120 
    121   public Map<FieldDescriptor, Object> getAllFields() {
    122     return Collections.unmodifiableMap(getAllFieldsMutable());
    123   }
    124 
    125   public boolean hasField(final FieldDescriptor field) {
    126     return internalGetFieldAccessorTable().getField(field).has(this);
    127   }
    128 
    129   public Object getField(final FieldDescriptor field) {
    130     return internalGetFieldAccessorTable().getField(field).get(this);
    131   }
    132 
    133   public int getRepeatedFieldCount(final FieldDescriptor field) {
    134     return internalGetFieldAccessorTable().getField(field)
    135       .getRepeatedCount(this);
    136   }
    137 
    138   public Object getRepeatedField(final FieldDescriptor field, final int index) {
    139     return internalGetFieldAccessorTable().getField(field)
    140       .getRepeated(this, index);
    141   }
    142 
    143   public final UnknownFieldSet getUnknownFields() {
    144     return unknownFields;
    145   }
    146 
    147   @SuppressWarnings("unchecked")
    148   public abstract static class Builder <BuilderType extends Builder>
    149       extends AbstractMessage.Builder<BuilderType> {
    150     protected Builder() {}
    151 
    152     // This is implemented here only to work around an apparent bug in the
    153     // Java compiler and/or build system.  See bug #1898463.  The mere presence
    154     // of this dummy clone() implementation makes it go away.
    155     @Override
    156     public BuilderType clone() {
    157       throw new UnsupportedOperationException(
    158           "This is supposed to be overridden by subclasses.");
    159     }
    160 
    161     /**
    162      * Get the message being built.  We don't just pass this to the
    163      * constructor because it becomes null when build() is called.
    164      */
    165     protected abstract GeneratedMessage internalGetResult();
    166 
    167     /**
    168      * Get the FieldAccessorTable for this type.  We can't have the message
    169      * class pass this in to the constructor because of bootstrapping trouble
    170      * with DescriptorProtos.
    171      */
    172     private FieldAccessorTable internalGetFieldAccessorTable() {
    173       return internalGetResult().internalGetFieldAccessorTable();
    174     }
    175 
    176     public Descriptor getDescriptorForType() {
    177       return internalGetFieldAccessorTable().descriptor;
    178     }
    179 
    180     public Map<FieldDescriptor, Object> getAllFields() {
    181       return internalGetResult().getAllFields();
    182     }
    183 
    184     public Message.Builder newBuilderForField(
    185         final FieldDescriptor field) {
    186       return internalGetFieldAccessorTable().getField(field).newBuilder();
    187     }
    188 
    189     public boolean hasField(final FieldDescriptor field) {
    190       return internalGetResult().hasField(field);
    191     }
    192 
    193     public Object getField(final FieldDescriptor field) {
    194       if (field.isRepeated()) {
    195         // The underlying list object is still modifiable at this point.
    196         // Make sure not to expose the modifiable list to the caller.
    197         return Collections.unmodifiableList(
    198           (List) internalGetResult().getField(field));
    199       } else {
    200         return internalGetResult().getField(field);
    201       }
    202     }
    203 
    204     public BuilderType setField(final FieldDescriptor field,
    205                                 final Object value) {
    206       internalGetFieldAccessorTable().getField(field).set(this, value);
    207       return (BuilderType) this;
    208     }
    209 
    210     public BuilderType clearField(final FieldDescriptor field) {
    211       internalGetFieldAccessorTable().getField(field).clear(this);
    212       return (BuilderType) this;
    213     }
    214 
    215     public int getRepeatedFieldCount(final FieldDescriptor field) {
    216       return internalGetResult().getRepeatedFieldCount(field);
    217     }
    218 
    219     public Object getRepeatedField(final FieldDescriptor field,
    220                                    final int index) {
    221       return internalGetResult().getRepeatedField(field, index);
    222     }
    223 
    224     public BuilderType setRepeatedField(final FieldDescriptor field,
    225                                         final int index, final Object value) {
    226       internalGetFieldAccessorTable().getField(field)
    227         .setRepeated(this, index, value);
    228       return (BuilderType) this;
    229     }
    230 
    231     public BuilderType addRepeatedField(final FieldDescriptor field,
    232                                         final Object value) {
    233       internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
    234       return (BuilderType) this;
    235     }
    236 
    237     public final UnknownFieldSet getUnknownFields() {
    238       return internalGetResult().unknownFields;
    239     }
    240 
    241     public final BuilderType setUnknownFields(
    242         final UnknownFieldSet unknownFields) {
    243       internalGetResult().unknownFields = unknownFields;
    244       return (BuilderType) this;
    245     }
    246 
    247     @Override
    248     public final BuilderType mergeUnknownFields(
    249         final UnknownFieldSet unknownFields) {
    250       final GeneratedMessage result = internalGetResult();
    251       result.unknownFields =
    252         UnknownFieldSet.newBuilder(result.unknownFields)
    253                        .mergeFrom(unknownFields)
    254                        .build();
    255       return (BuilderType) this;
    256     }
    257 
    258     public boolean isInitialized() {
    259       return internalGetResult().isInitialized();
    260     }
    261 
    262     /**
    263      * Called by subclasses to parse an unknown field.
    264      * @return {@code true} unless the tag is an end-group tag.
    265      */
    266     protected boolean parseUnknownField(
    267         final CodedInputStream input,
    268         final UnknownFieldSet.Builder unknownFields,
    269         final ExtensionRegistryLite extensionRegistry,
    270         final int tag) throws IOException {
    271       return unknownFields.mergeFieldFrom(tag, input);
    272     }
    273   }
    274 
    275   // =================================================================
    276   // Extensions-related stuff
    277 
    278   /**
    279    * Generated message classes for message types that contain extension ranges
    280    * subclass this.
    281    *
    282    * <p>This class implements type-safe accessors for extensions.  They
    283    * implement all the same operations that you can do with normal fields --
    284    * e.g. "has", "get", and "getCount" -- but for extensions.  The extensions
    285    * are identified using instances of the class {@link GeneratedExtension};
    286    * the protocol compiler generates a static instance of this class for every
    287    * extension in its input.  Through the magic of generics, all is made
    288    * type-safe.
    289    *
    290    * <p>For example, imagine you have the {@code .proto} file:
    291    *
    292    * <pre>
    293    * option java_class = "MyProto";
    294    *
    295    * message Foo {
    296    *   extensions 1000 to max;
    297    * }
    298    *
    299    * extend Foo {
    300    *   optional int32 bar;
    301    * }
    302    * </pre>
    303    *
    304    * <p>Then you might write code like:
    305    *
    306    * <pre>
    307    * MyProto.Foo foo = getFoo();
    308    * int i = foo.getExtension(MyProto.bar);
    309    * </pre>
    310    *
    311    * <p>See also {@link ExtendableBuilder}.
    312    */
    313   public abstract static class ExtendableMessage<
    314         MessageType extends ExtendableMessage>
    315       extends GeneratedMessage {
    316     protected ExtendableMessage() {}
    317     private final FieldSet<FieldDescriptor> extensions = FieldSet.newFieldSet();
    318 
    319     private void verifyExtensionContainingType(
    320         final GeneratedExtension<MessageType, ?> extension) {
    321       if (extension.getDescriptor().getContainingType() !=
    322           getDescriptorForType()) {
    323         // This can only happen if someone uses unchecked operations.
    324         throw new IllegalArgumentException(
    325           "Extension is for type \"" +
    326           extension.getDescriptor().getContainingType().getFullName() +
    327           "\" which does not match message type \"" +
    328           getDescriptorForType().getFullName() + "\".");
    329       }
    330     }
    331 
    332     /** Check if a singular extension is present. */
    333     public final boolean hasExtension(
    334         final GeneratedExtension<MessageType, ?> extension) {
    335       verifyExtensionContainingType(extension);
    336       return extensions.hasField(extension.getDescriptor());
    337     }
    338 
    339     /** Get the number of elements in a repeated extension. */
    340     public final <Type> int getExtensionCount(
    341         final GeneratedExtension<MessageType, List<Type>> extension) {
    342       verifyExtensionContainingType(extension);
    343       final FieldDescriptor descriptor = extension.getDescriptor();
    344       return extensions.getRepeatedFieldCount(descriptor);
    345     }
    346 
    347     /** Get the value of an extension. */
    348     @SuppressWarnings("unchecked")
    349     public final <Type> Type getExtension(
    350         final GeneratedExtension<MessageType, Type> extension) {
    351       verifyExtensionContainingType(extension);
    352       FieldDescriptor descriptor = extension.getDescriptor();
    353       final Object value = extensions.getField(descriptor);
    354       if (value == null) {
    355         if (descriptor.isRepeated()) {
    356           return (Type) Collections.emptyList();
    357         } else if (descriptor.getJavaType() ==
    358                    FieldDescriptor.JavaType.MESSAGE) {
    359           return (Type) extension.getMessageDefaultInstance();
    360         } else {
    361           return (Type) extension.fromReflectionType(
    362               descriptor.getDefaultValue());
    363         }
    364       } else {
    365         return (Type) extension.fromReflectionType(value);
    366       }
    367     }
    368 
    369     /** Get one element of a repeated extension. */
    370     @SuppressWarnings("unchecked")
    371     public final <Type> Type getExtension(
    372         final GeneratedExtension<MessageType, List<Type>> extension,
    373         final int index) {
    374       verifyExtensionContainingType(extension);
    375       FieldDescriptor descriptor = extension.getDescriptor();
    376       return (Type) extension.singularFromReflectionType(
    377           extensions.getRepeatedField(descriptor, index));
    378     }
    379 
    380     /** Called by subclasses to check if all extensions are initialized. */
    381     protected boolean extensionsAreInitialized() {
    382       return extensions.isInitialized();
    383     }
    384 
    385     @Override
    386     public boolean isInitialized() {
    387       return super.isInitialized() && extensionsAreInitialized();
    388     }
    389 
    390     /**
    391      * Used by subclasses to serialize extensions.  Extension ranges may be
    392      * interleaved with field numbers, but we must write them in canonical
    393      * (sorted by field number) order.  ExtensionWriter helps us write
    394      * individual ranges of extensions at once.
    395      */
    396     protected class ExtensionWriter {
    397       // Imagine how much simpler this code would be if Java iterators had
    398       // a way to get the next element without advancing the iterator.
    399 
    400       private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
    401         extensions.iterator();
    402       private Map.Entry<FieldDescriptor, Object> next;
    403       private final boolean messageSetWireFormat;
    404 
    405       private ExtensionWriter(final boolean messageSetWireFormat) {
    406         if (iter.hasNext()) {
    407           next = iter.next();
    408         }
    409         this.messageSetWireFormat = messageSetWireFormat;
    410       }
    411 
    412       public void writeUntil(final int end, final CodedOutputStream output)
    413                              throws IOException {
    414         while (next != null && next.getKey().getNumber() < end) {
    415           FieldDescriptor descriptor = next.getKey();
    416           if (messageSetWireFormat && descriptor.getLiteJavaType() ==
    417                   WireFormat.JavaType.MESSAGE &&
    418               !descriptor.isRepeated()) {
    419             output.writeMessageSetExtension(descriptor.getNumber(),
    420                                             (Message) next.getValue());
    421           } else {
    422             FieldSet.writeField(descriptor, next.getValue(), output);
    423           }
    424           if (iter.hasNext()) {
    425             next = iter.next();
    426           } else {
    427             next = null;
    428           }
    429         }
    430       }
    431     }
    432 
    433     protected ExtensionWriter newExtensionWriter() {
    434       return new ExtensionWriter(false);
    435     }
    436     protected ExtensionWriter newMessageSetExtensionWriter() {
    437       return new ExtensionWriter(true);
    438     }
    439 
    440     /** Called by subclasses to compute the size of extensions. */
    441     protected int extensionsSerializedSize() {
    442       return extensions.getSerializedSize();
    443     }
    444     protected int extensionsSerializedSizeAsMessageSet() {
    445       return extensions.getMessageSetSerializedSize();
    446     }
    447 
    448     // ---------------------------------------------------------------
    449     // Reflection
    450 
    451     @Override
    452     public Map<FieldDescriptor, Object> getAllFields() {
    453       final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
    454       result.putAll(extensions.getAllFields());
    455       return Collections.unmodifiableMap(result);
    456     }
    457 
    458     @Override
    459     public boolean hasField(final FieldDescriptor field) {
    460       if (field.isExtension()) {
    461         verifyContainingType(field);
    462         return extensions.hasField(field);
    463       } else {
    464         return super.hasField(field);
    465       }
    466     }
    467 
    468     @Override
    469     public Object getField(final FieldDescriptor field) {
    470       if (field.isExtension()) {
    471         verifyContainingType(field);
    472         final Object value = extensions.getField(field);
    473         if (value == null) {
    474           if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
    475             // Lacking an ExtensionRegistry, we have no way to determine the
    476             // extension's real type, so we return a DynamicMessage.
    477             return DynamicMessage.getDefaultInstance(field.getMessageType());
    478           } else {
    479             return field.getDefaultValue();
    480           }
    481         } else {
    482           return value;
    483         }
    484       } else {
    485         return super.getField(field);
    486       }
    487     }
    488 
    489     @Override
    490     public int getRepeatedFieldCount(final FieldDescriptor field) {
    491       if (field.isExtension()) {
    492         verifyContainingType(field);
    493         return extensions.getRepeatedFieldCount(field);
    494       } else {
    495         return super.getRepeatedFieldCount(field);
    496       }
    497     }
    498 
    499     @Override
    500     public Object getRepeatedField(final FieldDescriptor field,
    501                                    final int index) {
    502       if (field.isExtension()) {
    503         verifyContainingType(field);
    504         return extensions.getRepeatedField(field, index);
    505       } else {
    506         return super.getRepeatedField(field, index);
    507       }
    508     }
    509 
    510     private void verifyContainingType(final FieldDescriptor field) {
    511       if (field.getContainingType() != getDescriptorForType()) {
    512         throw new IllegalArgumentException(
    513           "FieldDescriptor does not match message type.");
    514       }
    515     }
    516   }
    517 
    518   /**
    519    * Generated message builders for message types that contain extension ranges
    520    * subclass this.
    521    *
    522    * <p>This class implements type-safe accessors for extensions.  They
    523    * implement all the same operations that you can do with normal fields --
    524    * e.g. "get", "set", and "add" -- but for extensions.  The extensions are
    525    * identified using instances of the class {@link GeneratedExtension}; the
    526    * protocol compiler generates a static instance of this class for every
    527    * extension in its input.  Through the magic of generics, all is made
    528    * type-safe.
    529    *
    530    * <p>For example, imagine you have the {@code .proto} file:
    531    *
    532    * <pre>
    533    * option java_class = "MyProto";
    534    *
    535    * message Foo {
    536    *   extensions 1000 to max;
    537    * }
    538    *
    539    * extend Foo {
    540    *   optional int32 bar;
    541    * }
    542    * </pre>
    543    *
    544    * <p>Then you might write code like:
    545    *
    546    * <pre>
    547    * MyProto.Foo foo =
    548    *   MyProto.Foo.newBuilder()
    549    *     .setExtension(MyProto.bar, 123)
    550    *     .build();
    551    * </pre>
    552    *
    553    * <p>See also {@link ExtendableMessage}.
    554    */
    555   @SuppressWarnings("unchecked")
    556   public abstract static class ExtendableBuilder<
    557         MessageType extends ExtendableMessage,
    558         BuilderType extends ExtendableBuilder>
    559       extends Builder<BuilderType> {
    560     protected ExtendableBuilder() {}
    561 
    562     // This is implemented here only to work around an apparent bug in the
    563     // Java compiler and/or build system.  See bug #1898463.  The mere presence
    564     // of this dummy clone() implementation makes it go away.
    565     @Override
    566     public BuilderType clone() {
    567       throw new UnsupportedOperationException(
    568           "This is supposed to be overridden by subclasses.");
    569     }
    570 
    571     @Override
    572     protected abstract ExtendableMessage<MessageType> internalGetResult();
    573 
    574     /** Check if a singular extension is present. */
    575     public final boolean hasExtension(
    576         final GeneratedExtension<MessageType, ?> extension) {
    577       return internalGetResult().hasExtension(extension);
    578     }
    579 
    580     /** Get the number of elements in a repeated extension. */
    581     public final <Type> int getExtensionCount(
    582         final GeneratedExtension<MessageType, List<Type>> extension) {
    583       return internalGetResult().getExtensionCount(extension);
    584     }
    585 
    586     /** Get the value of an extension. */
    587     public final <Type> Type getExtension(
    588         final GeneratedExtension<MessageType, Type> extension) {
    589       return internalGetResult().getExtension(extension);
    590     }
    591 
    592     /** Get one element of a repeated extension. */
    593     public final <Type> Type getExtension(
    594         final GeneratedExtension<MessageType, List<Type>> extension,
    595         final int index) {
    596       return internalGetResult().getExtension(extension, index);
    597     }
    598 
    599     /** Set the value of an extension. */
    600     public final <Type> BuilderType setExtension(
    601         final GeneratedExtension<MessageType, Type> extension,
    602         final Type value) {
    603       final ExtendableMessage<MessageType> message = internalGetResult();
    604       message.verifyExtensionContainingType(extension);
    605       final FieldDescriptor descriptor = extension.getDescriptor();
    606       message.extensions.setField(descriptor,
    607                                   extension.toReflectionType(value));
    608       return (BuilderType) this;
    609     }
    610 
    611     /** Set the value of one element of a repeated extension. */
    612     public final <Type> BuilderType setExtension(
    613         final GeneratedExtension<MessageType, List<Type>> extension,
    614         final int index, final Type value) {
    615       final ExtendableMessage<MessageType> message = internalGetResult();
    616       message.verifyExtensionContainingType(extension);
    617       final FieldDescriptor descriptor = extension.getDescriptor();
    618       message.extensions.setRepeatedField(
    619         descriptor, index,
    620         extension.singularToReflectionType(value));
    621       return (BuilderType) this;
    622     }
    623 
    624     /** Append a value to a repeated extension. */
    625     public final <Type> BuilderType addExtension(
    626         final GeneratedExtension<MessageType, List<Type>> extension,
    627         final Type value) {
    628       final ExtendableMessage<MessageType> message = internalGetResult();
    629       message.verifyExtensionContainingType(extension);
    630       final FieldDescriptor descriptor = extension.getDescriptor();
    631       message.extensions.addRepeatedField(
    632           descriptor, extension.singularToReflectionType(value));
    633       return (BuilderType) this;
    634     }
    635 
    636     /** Clear an extension. */
    637     public final <Type> BuilderType clearExtension(
    638         final GeneratedExtension<MessageType, ?> extension) {
    639       final ExtendableMessage<MessageType> message = internalGetResult();
    640       message.verifyExtensionContainingType(extension);
    641       message.extensions.clearField(extension.getDescriptor());
    642       return (BuilderType) this;
    643     }
    644 
    645     /**
    646      * Called by subclasses to parse an unknown field or an extension.
    647      * @return {@code true} unless the tag is an end-group tag.
    648      */
    649     @Override
    650     protected boolean parseUnknownField(
    651         final CodedInputStream input,
    652         final UnknownFieldSet.Builder unknownFields,
    653         final ExtensionRegistryLite extensionRegistry,
    654         final int tag) throws IOException {
    655       final ExtendableMessage<MessageType> message = internalGetResult();
    656       return AbstractMessage.Builder.mergeFieldFrom(
    657         input, unknownFields, extensionRegistry, this, tag);
    658     }
    659 
    660     // ---------------------------------------------------------------
    661     // Reflection
    662 
    663     // We don't have to override the get*() methods here because they already
    664     // just forward to the underlying message.
    665 
    666     @Override
    667     public BuilderType setField(final FieldDescriptor field,
    668                                 final Object value) {
    669       if (field.isExtension()) {
    670         final ExtendableMessage<MessageType> message = internalGetResult();
    671         message.verifyContainingType(field);
    672         message.extensions.setField(field, value);
    673         return (BuilderType) this;
    674       } else {
    675         return super.setField(field, value);
    676       }
    677     }
    678 
    679     @Override
    680     public BuilderType clearField(final FieldDescriptor field) {
    681       if (field.isExtension()) {
    682         final ExtendableMessage<MessageType> message = internalGetResult();
    683         message.verifyContainingType(field);
    684         message.extensions.clearField(field);
    685         return (BuilderType) this;
    686       } else {
    687         return super.clearField(field);
    688       }
    689     }
    690 
    691     @Override
    692     public BuilderType setRepeatedField(final FieldDescriptor field,
    693                                         final int index, final Object value) {
    694       if (field.isExtension()) {
    695         final ExtendableMessage<MessageType> message = internalGetResult();
    696         message.verifyContainingType(field);
    697         message.extensions.setRepeatedField(field, index, value);
    698         return (BuilderType) this;
    699       } else {
    700         return super.setRepeatedField(field, index, value);
    701       }
    702     }
    703 
    704     @Override
    705     public BuilderType addRepeatedField(final FieldDescriptor field,
    706                                         final Object value) {
    707       if (field.isExtension()) {
    708         final ExtendableMessage<MessageType> message = internalGetResult();
    709         message.verifyContainingType(field);
    710         message.extensions.addRepeatedField(field, value);
    711         return (BuilderType) this;
    712       } else {
    713         return super.addRepeatedField(field, value);
    714       }
    715     }
    716 
    717     protected final void mergeExtensionFields(final ExtendableMessage other) {
    718       internalGetResult().extensions.mergeFrom(other.extensions);
    719     }
    720   }
    721 
    722   // -----------------------------------------------------------------
    723 
    724   /** For use by generated code only. */
    725   public static <ContainingType extends Message, Type>
    726       GeneratedExtension<ContainingType, Type>
    727       newGeneratedExtension() {
    728     return new GeneratedExtension<ContainingType, Type>();
    729   }
    730 
    731   /**
    732    * Type used to represent generated extensions.  The protocol compiler
    733    * generates a static singleton instance of this class for each extension.
    734    *
    735    * <p>For example, imagine you have the {@code .proto} file:
    736    *
    737    * <pre>
    738    * option java_class = "MyProto";
    739    *
    740    * message Foo {
    741    *   extensions 1000 to max;
    742    * }
    743    *
    744    * extend Foo {
    745    *   optional int32 bar;
    746    * }
    747    * </pre>
    748    *
    749    * <p>Then, {@code MyProto.Foo.bar} has type
    750    * {@code GeneratedExtension<MyProto.Foo, Integer>}.
    751    *
    752    * <p>In general, users should ignore the details of this type, and simply use
    753    * these static singletons as parameters to the extension accessors defined
    754    * in {@link ExtendableMessage} and {@link ExtendableBuilder}.
    755    */
    756   public static final class GeneratedExtension<
    757       ContainingType extends Message, Type> {
    758     // TODO(kenton):  Find ways to avoid using Java reflection within this
    759     //   class.  Also try to avoid suppressing unchecked warnings.
    760 
    761     // We can't always initialize a GeneratedExtension when we first construct
    762     // it due to initialization order difficulties (namely, the descriptor may
    763     // not have been constructed yet, since it is often constructed by the
    764     // initializer of a separate module).  So, we construct an uninitialized
    765     // GeneratedExtension once, then call internalInit() on it later.  Generated
    766     // code will always call internalInit() on all extensions as part of the
    767     // static initialization code, and internalInit() throws an exception if
    768     // called more than once, so this method is useless to users.
    769     private GeneratedExtension() {}
    770 
    771     /** For use by generated code only. */
    772     public void internalInit(final FieldDescriptor descriptor,
    773                              final Class type) {
    774       if (this.descriptor != null) {
    775         throw new IllegalStateException("Already initialized.");
    776       }
    777 
    778       if (!descriptor.isExtension()) {
    779         throw new IllegalArgumentException(
    780           "GeneratedExtension given a regular (non-extension) field.");
    781       }
    782 
    783       this.descriptor = descriptor;
    784       this.type = type;
    785 
    786       switch (descriptor.getJavaType()) {
    787         case MESSAGE:
    788           enumValueOf = null;
    789           enumGetValueDescriptor = null;
    790           messageDefaultInstance =
    791             (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"),
    792                                   null);
    793           if (messageDefaultInstance == null) {
    794             throw new IllegalStateException(
    795                 type.getName() + ".getDefaultInstance() returned null.");
    796           }
    797           break;
    798         case ENUM:
    799           enumValueOf = getMethodOrDie(type, "valueOf",
    800                                        EnumValueDescriptor.class);
    801           enumGetValueDescriptor = getMethodOrDie(type, "getValueDescriptor");
    802           messageDefaultInstance = null;
    803           break;
    804         default:
    805           enumValueOf = null;
    806           enumGetValueDescriptor = null;
    807           messageDefaultInstance = null;
    808           break;
    809       }
    810     }
    811 
    812     private FieldDescriptor descriptor;
    813     private Class type;
    814     private Method enumValueOf;
    815     private Method enumGetValueDescriptor;
    816     private Message messageDefaultInstance;
    817 
    818     public FieldDescriptor getDescriptor() { return descriptor; }
    819 
    820     /**
    821      * If the extension is an embedded message or group, returns the default
    822      * instance of the message.
    823      */
    824     @SuppressWarnings("unchecked")
    825     public Message getMessageDefaultInstance() {
    826       return messageDefaultInstance;
    827     }
    828 
    829     /**
    830      * Convert from the type used by the reflection accessors to the type used
    831      * by native accessors.  E.g., for enums, the reflection accessors use
    832      * EnumValueDescriptors but the native accessors use the generated enum
    833      * type.
    834      */
    835     @SuppressWarnings("unchecked")
    836     private Object fromReflectionType(final Object value) {
    837       if (descriptor.isRepeated()) {
    838         if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE ||
    839             descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
    840           // Must convert the whole list.
    841           final List result = new ArrayList();
    842           for (final Object element : (List) value) {
    843             result.add(singularFromReflectionType(element));
    844           }
    845           return result;
    846         } else {
    847           return value;
    848         }
    849       } else {
    850         return singularFromReflectionType(value);
    851       }
    852     }
    853 
    854     /**
    855      * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
    856      * type, this converts a single element.
    857      */
    858     private Object singularFromReflectionType(final Object value) {
    859       switch (descriptor.getJavaType()) {
    860         case MESSAGE:
    861           if (type.isInstance(value)) {
    862             return value;
    863           } else {
    864             // It seems the copy of the embedded message stored inside the
    865             // extended message is not of the exact type the user was
    866             // expecting.  This can happen if a user defines a
    867             // GeneratedExtension manually and gives it a different type.
    868             // This should not happen in normal use.  But, to be nice, we'll
    869             // copy the message to whatever type the caller was expecting.
    870             return messageDefaultInstance.newBuilderForType()
    871                            .mergeFrom((Message) value).build();
    872           }
    873         case ENUM:
    874           return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
    875         default:
    876           return value;
    877       }
    878     }
    879 
    880     /**
    881      * Convert from the type used by the native accessors to the type used
    882      * by reflection accessors.  E.g., for enums, the reflection accessors use
    883      * EnumValueDescriptors but the native accessors use the generated enum
    884      * type.
    885      */
    886     @SuppressWarnings("unchecked")
    887     private Object toReflectionType(final Object value) {
    888       if (descriptor.isRepeated()) {
    889         if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
    890           // Must convert the whole list.
    891           final List result = new ArrayList();
    892           for (final Object element : (List) value) {
    893             result.add(singularToReflectionType(element));
    894           }
    895           return result;
    896         } else {
    897           return value;
    898         }
    899       } else {
    900         return singularToReflectionType(value);
    901       }
    902     }
    903 
    904     /**
    905      * Like {@link #toReflectionType(Object)}, but if the type is a repeated
    906      * type, this converts a single element.
    907      */
    908     private Object singularToReflectionType(final Object value) {
    909       switch (descriptor.getJavaType()) {
    910         case ENUM:
    911           return invokeOrDie(enumGetValueDescriptor, value);
    912         default:
    913           return value;
    914       }
    915     }
    916   }
    917 
    918   // =================================================================
    919 
    920   /** Calls Class.getMethod and throws a RuntimeException if it fails. */
    921   @SuppressWarnings("unchecked")
    922   private static Method getMethodOrDie(
    923       final Class clazz, final String name, final Class... params) {
    924     try {
    925       return clazz.getMethod(name, params);
    926     } catch (NoSuchMethodException e) {
    927       throw new RuntimeException(
    928         "Generated message class \"" + clazz.getName() +
    929         "\" missing method \"" + name + "\".", e);
    930     }
    931   }
    932 
    933   /** Calls invoke and throws a RuntimeException if it fails. */
    934   private static Object invokeOrDie(
    935       final Method method, final Object object, final Object... params) {
    936     try {
    937       return method.invoke(object, params);
    938     } catch (IllegalAccessException e) {
    939       throw new RuntimeException(
    940         "Couldn't use Java reflection to implement protocol message " +
    941         "reflection.", e);
    942     } catch (InvocationTargetException e) {
    943       final Throwable cause = e.getCause();
    944       if (cause instanceof RuntimeException) {
    945         throw (RuntimeException) cause;
    946       } else if (cause instanceof Error) {
    947         throw (Error) cause;
    948       } else {
    949         throw new RuntimeException(
    950           "Unexpected exception thrown by generated accessor method.", cause);
    951       }
    952     }
    953   }
    954 
    955   /**
    956    * Users should ignore this class.  This class provides the implementation
    957    * with access to the fields of a message object using Java reflection.
    958    */
    959   public static final class FieldAccessorTable {
    960 
    961     /**
    962      * Construct a FieldAccessorTable for a particular message class.  Only
    963      * one FieldAccessorTable should ever be constructed per class.
    964      *
    965      * @param descriptor     The type's descriptor.
    966      * @param camelCaseNames The camelcase names of all fields in the message.
    967      *                       These are used to derive the accessor method names.
    968      * @param messageClass   The message type.
    969      * @param builderClass   The builder type.
    970      */
    971     public FieldAccessorTable(
    972         final Descriptor descriptor,
    973         final String[] camelCaseNames,
    974         final Class<? extends GeneratedMessage> messageClass,
    975         final Class<? extends Builder> builderClass) {
    976       this.descriptor = descriptor;
    977       fields = new FieldAccessor[descriptor.getFields().size()];
    978 
    979       for (int i = 0; i < fields.length; i++) {
    980         final FieldDescriptor field = descriptor.getFields().get(i);
    981         if (field.isRepeated()) {
    982           if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
    983             fields[i] = new RepeatedMessageFieldAccessor(
    984               field, camelCaseNames[i], messageClass, builderClass);
    985           } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
    986             fields[i] = new RepeatedEnumFieldAccessor(
    987               field, camelCaseNames[i], messageClass, builderClass);
    988           } else {
    989             fields[i] = new RepeatedFieldAccessor(
    990               field, camelCaseNames[i], messageClass, builderClass);
    991           }
    992         } else {
    993           if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
    994             fields[i] = new SingularMessageFieldAccessor(
    995               field, camelCaseNames[i], messageClass, builderClass);
    996           } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
    997             fields[i] = new SingularEnumFieldAccessor(
    998               field, camelCaseNames[i], messageClass, builderClass);
    999           } else {
   1000             fields[i] = new SingularFieldAccessor(
   1001               field, camelCaseNames[i], messageClass, builderClass);
   1002           }
   1003         }
   1004       }
   1005     }
   1006 
   1007     private final Descriptor descriptor;
   1008     private final FieldAccessor[] fields;
   1009 
   1010     /** Get the FieldAccessor for a particular field. */
   1011     private FieldAccessor getField(final FieldDescriptor field) {
   1012       if (field.getContainingType() != descriptor) {
   1013         throw new IllegalArgumentException(
   1014           "FieldDescriptor does not match message type.");
   1015       } else if (field.isExtension()) {
   1016         // If this type had extensions, it would subclass ExtendableMessage,
   1017         // which overrides the reflection interface to handle extensions.
   1018         throw new IllegalArgumentException(
   1019           "This type does not have extensions.");
   1020       }
   1021       return fields[field.getIndex()];
   1022     }
   1023 
   1024     /**
   1025      * Abstract interface that provides access to a single field.  This is
   1026      * implemented differently depending on the field type and cardinality.
   1027      */
   1028     private interface FieldAccessor {
   1029       Object get(GeneratedMessage message);
   1030       void set(Builder builder, Object value);
   1031       Object getRepeated(GeneratedMessage message, int index);
   1032       void setRepeated(Builder builder,
   1033                        int index, Object value);
   1034       void addRepeated(Builder builder, Object value);
   1035       boolean has(GeneratedMessage message);
   1036       int getRepeatedCount(GeneratedMessage message);
   1037       void clear(Builder builder);
   1038       Message.Builder newBuilder();
   1039     }
   1040 
   1041     // ---------------------------------------------------------------
   1042 
   1043     private static class SingularFieldAccessor implements FieldAccessor {
   1044       SingularFieldAccessor(
   1045           final FieldDescriptor descriptor, final String camelCaseName,
   1046           final Class<? extends GeneratedMessage> messageClass,
   1047           final Class<? extends Builder> builderClass) {
   1048         getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
   1049         type = getMethod.getReturnType();
   1050         setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
   1051         hasMethod =
   1052           getMethodOrDie(messageClass, "has" + camelCaseName);
   1053         clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
   1054       }
   1055 
   1056       // Note:  We use Java reflection to call public methods rather than
   1057       //   access private fields directly as this avoids runtime security
   1058       //   checks.
   1059       protected final Class type;
   1060       protected final Method getMethod;
   1061       protected final Method setMethod;
   1062       protected final Method hasMethod;
   1063       protected final Method clearMethod;
   1064 
   1065       public Object get(final GeneratedMessage message) {
   1066         return invokeOrDie(getMethod, message);
   1067       }
   1068       public void set(final Builder builder, final Object value) {
   1069         invokeOrDie(setMethod, builder, value);
   1070       }
   1071       public Object getRepeated(final GeneratedMessage message,
   1072                                 final int index) {
   1073         throw new UnsupportedOperationException(
   1074           "getRepeatedField() called on a singular field.");
   1075       }
   1076       public void setRepeated(final Builder builder,
   1077                               final int index, final Object value) {
   1078         throw new UnsupportedOperationException(
   1079           "setRepeatedField() called on a singular field.");
   1080       }
   1081       public void addRepeated(final Builder builder, final Object value) {
   1082         throw new UnsupportedOperationException(
   1083           "addRepeatedField() called on a singular field.");
   1084       }
   1085       public boolean has(final GeneratedMessage message) {
   1086         return (Boolean) invokeOrDie(hasMethod, message);
   1087       }
   1088       public int getRepeatedCount(final GeneratedMessage message) {
   1089         throw new UnsupportedOperationException(
   1090           "getRepeatedFieldSize() called on a singular field.");
   1091       }
   1092       public void clear(final Builder builder) {
   1093         invokeOrDie(clearMethod, builder);
   1094       }
   1095       public Message.Builder newBuilder() {
   1096         throw new UnsupportedOperationException(
   1097           "newBuilderForField() called on a non-Message type.");
   1098       }
   1099     }
   1100 
   1101     private static class RepeatedFieldAccessor implements FieldAccessor {
   1102       RepeatedFieldAccessor(
   1103           final FieldDescriptor descriptor, final String camelCaseName,
   1104           final Class<? extends GeneratedMessage> messageClass,
   1105           final Class<? extends Builder> builderClass) {
   1106         getMethod = getMethodOrDie(messageClass,
   1107                                    "get" + camelCaseName + "List");
   1108 
   1109         getRepeatedMethod =
   1110           getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
   1111         type = getRepeatedMethod.getReturnType();
   1112         setRepeatedMethod =
   1113           getMethodOrDie(builderClass, "set" + camelCaseName,
   1114                          Integer.TYPE, type);
   1115         addRepeatedMethod =
   1116           getMethodOrDie(builderClass, "add" + camelCaseName, type);
   1117         getCountMethod =
   1118           getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
   1119 
   1120         clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
   1121       }
   1122 
   1123       protected final Class type;
   1124       protected final Method getMethod;
   1125       protected final Method getRepeatedMethod;
   1126       protected final Method setRepeatedMethod;
   1127       protected final Method addRepeatedMethod;
   1128       protected final Method getCountMethod;
   1129       protected final Method clearMethod;
   1130 
   1131       public Object get(final GeneratedMessage message) {
   1132         return invokeOrDie(getMethod, message);
   1133       }
   1134       public void set(final Builder builder, final Object value) {
   1135         // Add all the elements individually.  This serves two purposes:
   1136         // 1) Verifies that each element has the correct type.
   1137         // 2) Insures that the caller cannot modify the list later on and
   1138         //    have the modifications be reflected in the message.
   1139         clear(builder);
   1140         for (final Object element : (List) value) {
   1141           addRepeated(builder, element);
   1142         }
   1143       }
   1144       public Object getRepeated(final GeneratedMessage message,
   1145                                 final int index) {
   1146         return invokeOrDie(getRepeatedMethod, message, index);
   1147       }
   1148       public void setRepeated(final Builder builder,
   1149                               final int index, final Object value) {
   1150         invokeOrDie(setRepeatedMethod, builder, index, value);
   1151       }
   1152       public void addRepeated(final Builder builder, final Object value) {
   1153         invokeOrDie(addRepeatedMethod, builder, value);
   1154       }
   1155       public boolean has(final GeneratedMessage message) {
   1156         throw new UnsupportedOperationException(
   1157           "hasField() called on a singular field.");
   1158       }
   1159       public int getRepeatedCount(final GeneratedMessage message) {
   1160         return (Integer) invokeOrDie(getCountMethod, message);
   1161       }
   1162       public void clear(final Builder builder) {
   1163         invokeOrDie(clearMethod, builder);
   1164       }
   1165       public Message.Builder newBuilder() {
   1166         throw new UnsupportedOperationException(
   1167           "newBuilderForField() called on a non-Message type.");
   1168       }
   1169     }
   1170 
   1171     // ---------------------------------------------------------------
   1172 
   1173     private static final class SingularEnumFieldAccessor
   1174         extends SingularFieldAccessor {
   1175       SingularEnumFieldAccessor(
   1176           final FieldDescriptor descriptor, final String camelCaseName,
   1177           final Class<? extends GeneratedMessage> messageClass,
   1178           final Class<? extends Builder> builderClass) {
   1179         super(descriptor, camelCaseName, messageClass, builderClass);
   1180 
   1181         valueOfMethod = getMethodOrDie(type, "valueOf",
   1182                                        EnumValueDescriptor.class);
   1183         getValueDescriptorMethod =
   1184           getMethodOrDie(type, "getValueDescriptor");
   1185       }
   1186 
   1187       private Method valueOfMethod;
   1188       private Method getValueDescriptorMethod;
   1189 
   1190       @Override
   1191       public Object get(final GeneratedMessage message) {
   1192         return invokeOrDie(getValueDescriptorMethod, super.get(message));
   1193       }
   1194       @Override
   1195       public void set(final Builder builder, final Object value) {
   1196         super.set(builder, invokeOrDie(valueOfMethod, null, value));
   1197       }
   1198     }
   1199 
   1200     private static final class RepeatedEnumFieldAccessor
   1201         extends RepeatedFieldAccessor {
   1202       RepeatedEnumFieldAccessor(
   1203           final FieldDescriptor descriptor, final String camelCaseName,
   1204           final Class<? extends GeneratedMessage> messageClass,
   1205           final Class<? extends Builder> builderClass) {
   1206         super(descriptor, camelCaseName, messageClass, builderClass);
   1207 
   1208         valueOfMethod = getMethodOrDie(type, "valueOf",
   1209                                        EnumValueDescriptor.class);
   1210         getValueDescriptorMethod =
   1211           getMethodOrDie(type, "getValueDescriptor");
   1212       }
   1213 
   1214       private final Method valueOfMethod;
   1215       private final Method getValueDescriptorMethod;
   1216 
   1217       @Override
   1218       @SuppressWarnings("unchecked")
   1219       public Object get(final GeneratedMessage message) {
   1220         final List newList = new ArrayList();
   1221         for (final Object element : (List) super.get(message)) {
   1222           newList.add(invokeOrDie(getValueDescriptorMethod, element));
   1223         }
   1224         return Collections.unmodifiableList(newList);
   1225       }
   1226       @Override
   1227       public Object getRepeated(final GeneratedMessage message,
   1228                                 final int index) {
   1229         return invokeOrDie(getValueDescriptorMethod,
   1230           super.getRepeated(message, index));
   1231       }
   1232       @Override
   1233       public void setRepeated(final Builder builder,
   1234                               final int index, final Object value) {
   1235         super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
   1236                           value));
   1237       }
   1238       @Override
   1239       public void addRepeated(final Builder builder, final Object value) {
   1240         super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
   1241       }
   1242     }
   1243 
   1244     // ---------------------------------------------------------------
   1245 
   1246     private static final class SingularMessageFieldAccessor
   1247         extends SingularFieldAccessor {
   1248       SingularMessageFieldAccessor(
   1249           final FieldDescriptor descriptor, final String camelCaseName,
   1250           final Class<? extends GeneratedMessage> messageClass,
   1251           final Class<? extends Builder> builderClass) {
   1252         super(descriptor, camelCaseName, messageClass, builderClass);
   1253 
   1254         newBuilderMethod = getMethodOrDie(type, "newBuilder");
   1255       }
   1256 
   1257       private final Method newBuilderMethod;
   1258 
   1259       private Object coerceType(final Object value) {
   1260         if (type.isInstance(value)) {
   1261           return value;
   1262         } else {
   1263           // The value is not the exact right message type.  However, if it
   1264           // is an alternative implementation of the same type -- e.g. a
   1265           // DynamicMessage -- we should accept it.  In this case we can make
   1266           // a copy of the message.
   1267           return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
   1268                   .mergeFrom((Message) value).build();
   1269         }
   1270       }
   1271 
   1272       @Override
   1273       public void set(final Builder builder, final Object value) {
   1274         super.set(builder, coerceType(value));
   1275       }
   1276       @Override
   1277       public Message.Builder newBuilder() {
   1278         return (Message.Builder) invokeOrDie(newBuilderMethod, null);
   1279       }
   1280     }
   1281 
   1282     private static final class RepeatedMessageFieldAccessor
   1283         extends RepeatedFieldAccessor {
   1284       RepeatedMessageFieldAccessor(
   1285           final FieldDescriptor descriptor, final String camelCaseName,
   1286           final Class<? extends GeneratedMessage> messageClass,
   1287           final Class<? extends Builder> builderClass) {
   1288         super(descriptor, camelCaseName, messageClass, builderClass);
   1289 
   1290         newBuilderMethod = getMethodOrDie(type, "newBuilder");
   1291       }
   1292 
   1293       private final Method newBuilderMethod;
   1294 
   1295       private Object coerceType(final Object value) {
   1296         if (type.isInstance(value)) {
   1297           return value;
   1298         } else {
   1299           // The value is not the exact right message type.  However, if it
   1300           // is an alternative implementation of the same type -- e.g. a
   1301           // DynamicMessage -- we should accept it.  In this case we can make
   1302           // a copy of the message.
   1303           return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
   1304                   .mergeFrom((Message) value).build();
   1305         }
   1306       }
   1307 
   1308       @Override
   1309       public void setRepeated(final Builder builder,
   1310                               final int index, final Object value) {
   1311         super.setRepeated(builder, index, coerceType(value));
   1312       }
   1313       @Override
   1314       public void addRepeated(final Builder builder, final Object value) {
   1315         super.addRepeated(builder, coerceType(value));
   1316       }
   1317       @Override
   1318       public Message.Builder newBuilder() {
   1319         return (Message.Builder) invokeOrDie(newBuilderMethod, null);
   1320       }
   1321     }
   1322   }
   1323 }
   1324