• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import static com.google.protobuf.Internal.checkNotNull;
34 
35 import com.google.protobuf.Descriptors.Descriptor;
36 import com.google.protobuf.Descriptors.EnumDescriptor;
37 import com.google.protobuf.Descriptors.EnumValueDescriptor;
38 import com.google.protobuf.Descriptors.FieldDescriptor;
39 import com.google.protobuf.Descriptors.FileDescriptor;
40 import com.google.protobuf.Descriptors.OneofDescriptor;
41 import com.google.protobuf.Internal.BooleanList;
42 import com.google.protobuf.Internal.DoubleList;
43 import com.google.protobuf.Internal.FloatList;
44 import com.google.protobuf.Internal.IntList;
45 import com.google.protobuf.Internal.LongList;
46 // In opensource protobuf, we have versioned this GeneratedMessageV3 class to GeneratedMessageV3V3 and
47 // in the future may have GeneratedMessageV3V4 etc. This allows us to change some aspects of this
48 // class without breaking binary compatibility with old generated code that still subclasses
49 // the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to
50 // interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class
51 // type is GeneratedMessageV3V4), these classes still share a common parent class AbstractMessage
52 // and are using the same GeneratedMessage.GeneratedExtension class for extension definitions.
53 // Since this class becomes GeneratedMessageV3V? in opensource, we have to add an import here
54 // to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in
55 // this file is also excluded from opensource to avoid conflict.
56 import com.google.protobuf.GeneratedMessage.GeneratedExtension;
57 import java.io.IOException;
58 import java.io.InputStream;
59 import java.io.ObjectStreamException;
60 import java.io.Serializable;
61 import java.lang.reflect.InvocationTargetException;
62 import java.lang.reflect.Method;
63 import java.util.ArrayList;
64 import java.util.Arrays;
65 import java.util.Collections;
66 import java.util.Iterator;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.TreeMap;
70 
71 /**
72  * All generated protocol message classes extend this class.  This class
73  * implements most of the Message and Builder interfaces using Java reflection.
74  * Users can ignore this class and pretend that generated messages implement
75  * the Message interface directly.
76  *
77  * @author kenton@google.com Kenton Varda
78  */
79 public abstract class GeneratedMessageV3 extends AbstractMessage
80     implements Serializable {
81   private static final long serialVersionUID = 1L;
82 
83   /**
84    * For testing. Allows a test to disable the optimization that avoids using field builders for
85    * nested messages until they are requested. By disabling this optimization, existing tests can be
86    * reused to test the field builders.
87    */
88   protected static boolean alwaysUseFieldBuilders = false;
89 
90   /** For use by generated code only.  */
91   protected UnknownFieldSet unknownFields;
92 
GeneratedMessageV3()93   protected GeneratedMessageV3() {
94     unknownFields = UnknownFieldSet.getDefaultInstance();
95   }
96 
GeneratedMessageV3(Builder<?> builder)97   protected GeneratedMessageV3(Builder<?> builder) {
98     unknownFields = builder.getUnknownFields();
99   }
100 
101   @Override
getParserForType()102   public Parser<? extends GeneratedMessageV3> getParserForType() {
103     throw new UnsupportedOperationException(
104         "This is supposed to be overridden by subclasses.");
105   }
106 
107  /**
108   * @see #setAlwaysUseFieldBuildersForTesting(boolean)
109   */
enableAlwaysUseFieldBuildersForTesting()110   static void enableAlwaysUseFieldBuildersForTesting() {
111     setAlwaysUseFieldBuildersForTesting(true);
112   }
113 
114   /**
115    * For testing. Allows a test to disable/re-enable the optimization that avoids
116    * using field builders for nested messages until they are requested. By disabling
117    * this optimization, existing tests can be reused to test the field builders.
118    * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}.
119    */
setAlwaysUseFieldBuildersForTesting(boolean useBuilders)120   static void setAlwaysUseFieldBuildersForTesting(boolean useBuilders) {
121     alwaysUseFieldBuilders = useBuilders;
122   }
123 
124   /**
125    * Get the FieldAccessorTable for this type.  We can't have the message
126    * class pass this in to the constructor because of bootstrapping trouble
127    * with DescriptorProtos.
128    */
internalGetFieldAccessorTable()129   protected abstract FieldAccessorTable internalGetFieldAccessorTable();
130 
131   @Override
getDescriptorForType()132   public Descriptor getDescriptorForType() {
133     return internalGetFieldAccessorTable().descriptor;
134   }
135 
136   // TODO(b/248143958): This method should be removed. It enables parsing directly into an
137   // "immutable" message. Have to leave it for now to support old gencode.
138   // @deprecated use newBuilder().mergeFrom() instead
139   @Deprecated
mergeFromAndMakeImmutableInternal( CodedInputStream input, ExtensionRegistryLite extensionRegistry)140   protected void mergeFromAndMakeImmutableInternal(
141       CodedInputStream input, ExtensionRegistryLite extensionRegistry)
142       throws InvalidProtocolBufferException {
143     Schema<GeneratedMessageV3> schema =
144         (Schema<GeneratedMessageV3>) Protobuf.getInstance().schemaFor(this);
145     try {
146       schema.mergeFrom(this, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
147     } catch (InvalidProtocolBufferException e) {
148       throw e.setUnfinishedMessage(this);
149     } catch (IOException e) {
150       throw new InvalidProtocolBufferException(e).setUnfinishedMessage(this);
151     }
152     schema.makeImmutable(this);
153   }
154 
155   /**
156    * Internal helper to return a modifiable map containing all the fields.
157    * The returned Map is modifiable so that the caller can add additional
158    * extension fields to implement {@link #getAllFields()}.
159    *
160    * @param getBytesForString whether to generate ByteString for string fields
161    */
getAllFieldsMutable( boolean getBytesForString)162   private Map<FieldDescriptor, Object> getAllFieldsMutable(
163       boolean getBytesForString) {
164     final TreeMap<FieldDescriptor, Object> result =
165       new TreeMap<FieldDescriptor, Object>();
166     final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
167     final List<FieldDescriptor> fields = descriptor.getFields();
168 
169     for (int i = 0; i < fields.size(); i++) {
170       FieldDescriptor field = fields.get(i);
171       final OneofDescriptor oneofDescriptor = field.getContainingOneof();
172 
173       /*
174        * If the field is part of a Oneof, then at maximum one field in the Oneof is set
175        * and it is not repeated. There is no need to iterate through the others.
176        */
177       if (oneofDescriptor != null) {
178         // Skip other fields in the Oneof we know are not set
179         i += oneofDescriptor.getFieldCount() - 1;
180         if (!hasOneof(oneofDescriptor)) {
181           // If no field is set in the Oneof, skip all the fields in the Oneof
182           continue;
183         }
184         // Get the pointer to the only field which is set in the Oneof
185         field = getOneofFieldDescriptor(oneofDescriptor);
186       } else {
187         // If we are not in a Oneof, we need to check if the field is set and if it is repeated
188         if (field.isRepeated()) {
189           final List<?> value = (List<?>) getField(field);
190           if (!value.isEmpty()) {
191             result.put(field, value);
192           }
193           continue;
194         }
195         if (!hasField(field)) {
196           continue;
197         }
198       }
199       // Add the field to the map
200       if (getBytesForString && field.getJavaType() == FieldDescriptor.JavaType.STRING) {
201         result.put(field, getFieldRaw(field));
202       } else {
203         result.put(field, getField(field));
204       }
205     }
206     return result;
207   }
208 
209   @Override
isInitialized()210   public boolean isInitialized() {
211     for (final FieldDescriptor field : getDescriptorForType().getFields()) {
212       // Check that all required fields are present.
213       if (field.isRequired()) {
214         if (!hasField(field)) {
215           return false;
216         }
217       }
218       // Check that embedded messages are initialized.
219       if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
220         if (field.isRepeated()) {
221           @SuppressWarnings("unchecked") final
222           List<Message> messageList = (List<Message>) getField(field);
223           for (final Message element : messageList) {
224             if (!element.isInitialized()) {
225               return false;
226             }
227           }
228         } else {
229           if (hasField(field) && !((Message) getField(field)).isInitialized()) {
230             return false;
231           }
232         }
233       }
234     }
235 
236     return true;
237   }
238 
239   @Override
getAllFields()240   public Map<FieldDescriptor, Object> getAllFields() {
241     return Collections.unmodifiableMap(
242         getAllFieldsMutable(/* getBytesForString = */ false));
243   }
244 
245   /**
246    * Returns a collection of all the fields in this message which are set
247    * and their corresponding values.  A singular ("required" or "optional")
248    * field is set iff hasField() returns true for that field.  A "repeated"
249    * field is set iff getRepeatedFieldCount() is greater than zero.  The
250    * values are exactly what would be returned by calling
251    * {@link #getFieldRaw(Descriptors.FieldDescriptor)} for each field.  The map
252    * is guaranteed to be a sorted map, so iterating over it will return fields
253    * in order by field number.
254    */
getAllFieldsRaw()255   Map<FieldDescriptor, Object> getAllFieldsRaw() {
256     return Collections.unmodifiableMap(
257         getAllFieldsMutable(/* getBytesForString = */ true));
258   }
259 
260   @Override
hasOneof(final OneofDescriptor oneof)261   public boolean hasOneof(final OneofDescriptor oneof) {
262     return internalGetFieldAccessorTable().getOneof(oneof).has(this);
263   }
264 
265   @Override
getOneofFieldDescriptor(final OneofDescriptor oneof)266   public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
267     return internalGetFieldAccessorTable().getOneof(oneof).get(this);
268   }
269 
270   @Override
hasField(final FieldDescriptor field)271   public boolean hasField(final FieldDescriptor field) {
272     return internalGetFieldAccessorTable().getField(field).has(this);
273   }
274 
275   @Override
getField(final FieldDescriptor field)276   public Object getField(final FieldDescriptor field) {
277     return internalGetFieldAccessorTable().getField(field).get(this);
278   }
279 
280   /**
281    * Obtains the value of the given field, or the default value if it is
282    * not set.  For primitive fields, the boxed primitive value is returned.
283    * For enum fields, the EnumValueDescriptor for the value is returned. For
284    * embedded message fields, the sub-message is returned.  For repeated
285    * fields, a java.util.List is returned. For present string fields, a
286    * ByteString is returned representing the bytes that the field contains.
287    */
getFieldRaw(final FieldDescriptor field)288   Object getFieldRaw(final FieldDescriptor field) {
289     return internalGetFieldAccessorTable().getField(field).getRaw(this);
290   }
291 
292   @Override
getRepeatedFieldCount(final FieldDescriptor field)293   public int getRepeatedFieldCount(final FieldDescriptor field) {
294     return internalGetFieldAccessorTable().getField(field)
295       .getRepeatedCount(this);
296   }
297 
298   @Override
getRepeatedField(final FieldDescriptor field, final int index)299   public Object getRepeatedField(final FieldDescriptor field, final int index) {
300     return internalGetFieldAccessorTable().getField(field)
301       .getRepeated(this, index);
302   }
303 
304   @Override
getUnknownFields()305   public UnknownFieldSet getUnknownFields() {
306     return unknownFields;
307   }
308 
309   /**
310    * Called by subclasses to parse an unknown field.
311    *
312    * <p>TODO(b/248153893) remove this method
313    *
314    * @return {@code true} unless the tag is an end-group tag.
315    */
parseUnknownField( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, int tag)316   protected boolean parseUnknownField(
317       CodedInputStream input,
318       UnknownFieldSet.Builder unknownFields,
319       ExtensionRegistryLite extensionRegistry,
320       int tag)
321       throws IOException {
322     if (input.shouldDiscardUnknownFields()) {
323       return input.skipField(tag);
324     }
325     return unknownFields.mergeFieldFrom(tag, input);
326   }
327 
328   /**
329    * Delegates to parseUnknownField. This method is obsolete, but we must retain it for
330    * compatibility with older generated code.
331    *
332    * <p>TODO(b/248153893) remove this method
333    */
parseUnknownFieldProto3( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, int tag)334   protected boolean parseUnknownFieldProto3(
335       CodedInputStream input,
336       UnknownFieldSet.Builder unknownFields,
337       ExtensionRegistryLite extensionRegistry,
338       int tag)
339       throws IOException {
340     return parseUnknownField(input, unknownFields, extensionRegistry, tag);
341   }
342 
parseWithIOException(Parser<M> parser, InputStream input)343   protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input)
344       throws IOException {
345     try {
346       return parser.parseFrom(input);
347     } catch (InvalidProtocolBufferException e) {
348       throw e.unwrapIOException();
349     }
350   }
351 
parseWithIOException(Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)352   protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input,
353       ExtensionRegistryLite extensions) throws IOException {
354     try {
355       return parser.parseFrom(input, extensions);
356     } catch (InvalidProtocolBufferException e) {
357       throw e.unwrapIOException();
358     }
359   }
360 
parseWithIOException(Parser<M> parser, CodedInputStream input)361   protected static <M extends Message> M parseWithIOException(Parser<M> parser,
362       CodedInputStream input) throws IOException {
363     try {
364       return parser.parseFrom(input);
365     } catch (InvalidProtocolBufferException e) {
366       throw e.unwrapIOException();
367     }
368   }
369 
parseWithIOException(Parser<M> parser, CodedInputStream input, ExtensionRegistryLite extensions)370   protected static <M extends Message> M parseWithIOException(Parser<M> parser,
371       CodedInputStream input, ExtensionRegistryLite extensions) throws IOException {
372     try {
373       return parser.parseFrom(input, extensions);
374     } catch (InvalidProtocolBufferException e) {
375       throw e.unwrapIOException();
376     }
377   }
378 
parseDelimitedWithIOException(Parser<M> parser, InputStream input)379   protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
380       InputStream input) throws IOException {
381     try {
382       return parser.parseDelimitedFrom(input);
383     } catch (InvalidProtocolBufferException e) {
384       throw e.unwrapIOException();
385     }
386   }
387 
parseDelimitedWithIOException(Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)388   protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
389       InputStream input, ExtensionRegistryLite extensions) throws IOException {
390     try {
391       return parser.parseDelimitedFrom(input, extensions);
392     } catch (InvalidProtocolBufferException e) {
393       throw e.unwrapIOException();
394     }
395   }
396 
canUseUnsafe()397   protected static boolean canUseUnsafe() {
398     return UnsafeUtil.hasUnsafeArrayOperations() && UnsafeUtil.hasUnsafeByteBufferOperations();
399   }
400 
emptyIntList()401   protected static IntList emptyIntList() {
402     return IntArrayList.emptyList();
403   }
404 
newIntList()405   protected static IntList newIntList() {
406     return new IntArrayList();
407   }
408 
mutableCopy(IntList list)409   protected static IntList mutableCopy(IntList list) {
410     int size = list.size();
411     return list.mutableCopyWithCapacity(
412         size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
413   }
414 
emptyLongList()415   protected static LongList emptyLongList() {
416     return LongArrayList.emptyList();
417   }
418 
newLongList()419   protected static LongList newLongList() {
420     return new LongArrayList();
421   }
422 
mutableCopy(LongList list)423   protected static LongList mutableCopy(LongList list) {
424     int size = list.size();
425     return list.mutableCopyWithCapacity(
426         size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
427   }
428 
emptyFloatList()429   protected static FloatList emptyFloatList() {
430     return FloatArrayList.emptyList();
431   }
432 
newFloatList()433   protected static FloatList newFloatList() {
434     return new FloatArrayList();
435   }
436 
mutableCopy(FloatList list)437   protected static FloatList mutableCopy(FloatList list) {
438     int size = list.size();
439     return list.mutableCopyWithCapacity(
440         size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
441   }
442 
emptyDoubleList()443   protected static DoubleList emptyDoubleList() {
444     return DoubleArrayList.emptyList();
445   }
446 
newDoubleList()447   protected static DoubleList newDoubleList() {
448     return new DoubleArrayList();
449   }
450 
mutableCopy(DoubleList list)451   protected static DoubleList mutableCopy(DoubleList list) {
452     int size = list.size();
453     return list.mutableCopyWithCapacity(
454         size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
455   }
456 
emptyBooleanList()457   protected static BooleanList emptyBooleanList() {
458     return BooleanArrayList.emptyList();
459   }
460 
newBooleanList()461   protected static BooleanList newBooleanList() {
462     return new BooleanArrayList();
463   }
464 
mutableCopy(BooleanList list)465   protected static BooleanList mutableCopy(BooleanList list) {
466     int size = list.size();
467     return list.mutableCopyWithCapacity(
468         size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
469   }
470 
471 
472   @Override
writeTo(final CodedOutputStream output)473   public void writeTo(final CodedOutputStream output) throws IOException {
474     MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false);
475   }
476 
477   @Override
getSerializedSize()478   public int getSerializedSize() {
479     int size = memoizedSize;
480     if (size != -1) {
481       return size;
482     }
483 
484     memoizedSize = MessageReflection.getSerializedSize(
485         this, getAllFieldsRaw());
486     return memoizedSize;
487   }
488 
489 
490 
491   /**
492    * This class is used to make a generated protected method inaccessible from user's code (e.g.,
493    * the {@link #newInstance} method below). When this class is used as a parameter's type in a
494    * generated protected method, the method is visible to user's code in the same package, but
495    * since the constructor of this class is private to protobuf runtime, user's code can't obtain
496    * an instance of this class and as such can't actually make a method call on the protected
497    * method.
498    */
499   protected static final class UnusedPrivateParameter {
500     static final UnusedPrivateParameter INSTANCE = new UnusedPrivateParameter();
501 
UnusedPrivateParameter()502     private UnusedPrivateParameter() {
503     }
504   }
505 
506   /**
507    * Creates a new instance of this message type. Overridden in the generated code.
508    */
509   @SuppressWarnings({"unused"})
newInstance(UnusedPrivateParameter unused)510   protected Object newInstance(UnusedPrivateParameter unused) {
511     throw new UnsupportedOperationException("This method must be overridden by the subclass.");
512   }
513 
514   /**
515    * Used by parsing constructors in generated classes.
516    */
makeExtensionsImmutable()517   protected void makeExtensionsImmutable() {
518     // Noop for messages without extensions.
519   }
520 
521   /**
522    * TODO(xiaofeng): remove this after b/29368482 is fixed. We need to move this
523    * interface to AbstractMessage in order to versioning GeneratedMessageV3 but
524    * this move breaks binary compatibility for AppEngine. After AppEngine is
525    * fixed we can exclude this from google3.
526    */
527   protected interface BuilderParent extends AbstractMessage.BuilderParent {}
528 
529   /**
530    * TODO(xiaofeng): remove this together with GeneratedMessageV3.BuilderParent.
531    */
newBuilderForType(BuilderParent parent)532   protected abstract Message.Builder newBuilderForType(BuilderParent parent);
533 
534   @Override
newBuilderForType(final AbstractMessage.BuilderParent parent)535   protected Message.Builder newBuilderForType(final AbstractMessage.BuilderParent parent) {
536     return newBuilderForType(new BuilderParent() {
537       @Override
538       public void markDirty() {
539         parent.markDirty();
540       }
541     });
542   }
543 
544 
545   @SuppressWarnings("unchecked")
546   public abstract static class Builder <BuilderType extends Builder<BuilderType>>
547       extends AbstractMessage.Builder<BuilderType> {
548 
549     private BuilderParent builderParent;
550 
551     private BuilderParentImpl meAsParent;
552 
553     // Indicates that we've built a message and so we are now obligated
554     // to dispatch dirty invalidations. See GeneratedMessageV3.BuilderListener.
555     private boolean isClean;
556 
557     /**
558      * This field holds either an {@link UnknownFieldSet} or {@link UnknownFieldSet.Builder}.
559      *
560      * <p>We use an object because it should only be one or the other of those things at a time and
561      * Object is the only common base. This also saves space.
562      *
563      * <p>Conversions are lazy: if {@link #setUnknownFields} is called, this will contain {@link
564      * UnknownFieldSet}. If unknown fields are merged into this builder, the current {@link
565      * UnknownFieldSet} will be converted to a {@link UnknownFieldSet.Builder} and left that way
566      * until either {@link #setUnknownFields} or {@link #buildPartial} or {@link #build} is called.
567      */
568     private Object unknownFieldsOrBuilder = UnknownFieldSet.getDefaultInstance();
569 
570     protected Builder() {
571       this(null);
572     }
573 
574     protected Builder(BuilderParent builderParent) {
575       this.builderParent = builderParent;
576     }
577 
578     @Override
579     void dispose() {
580       builderParent = null;
581     }
582 
583     /**
584      * Called by the subclass when a message is built.
585      */
586     protected void onBuilt() {
587       if (builderParent != null) {
588         markClean();
589       }
590     }
591 
592     /**
593      * Called by the subclass or a builder to notify us that a message was
594      * built and may be cached and therefore invalidations are needed.
595      */
596     @Override
597     protected void markClean() {
598       this.isClean = true;
599     }
600 
601     /**
602      * Gets whether invalidations are needed
603      *
604      * @return whether invalidations are needed
605      */
606     protected boolean isClean() {
607       return isClean;
608     }
609 
610     @Override
611     public BuilderType clone() {
612       BuilderType builder =
613           (BuilderType) getDefaultInstanceForType().newBuilderForType();
614       builder.mergeFrom(buildPartial());
615       return builder;
616     }
617 
618     /**
619      * Called by the initialization and clear code paths to allow subclasses to
620      * reset any of their builtin fields back to the initial values.
621      */
622     @Override
623     public BuilderType clear() {
624       unknownFieldsOrBuilder = UnknownFieldSet.getDefaultInstance();
625       onChanged();
626       return (BuilderType) this;
627     }
628 
629     /**
630      * Get the FieldAccessorTable for this type.  We can't have the message
631      * class pass this in to the constructor because of bootstrapping trouble
632      * with DescriptorProtos.
633      */
634     protected abstract FieldAccessorTable internalGetFieldAccessorTable();
635 
636     @Override
637     public Descriptor getDescriptorForType() {
638       return internalGetFieldAccessorTable().descriptor;
639     }
640 
641     @Override
642     public Map<FieldDescriptor, Object> getAllFields() {
643       return Collections.unmodifiableMap(getAllFieldsMutable());
644     }
645 
646     /** Internal helper which returns a mutable map. */
647     private Map<FieldDescriptor, Object> getAllFieldsMutable() {
648       final TreeMap<FieldDescriptor, Object> result =
649         new TreeMap<FieldDescriptor, Object>();
650       final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
651       final List<FieldDescriptor> fields = descriptor.getFields();
652 
653       for (int i = 0; i < fields.size(); i++) {
654         FieldDescriptor field = fields.get(i);
655         final OneofDescriptor oneofDescriptor = field.getContainingOneof();
656 
657         /*
658          * If the field is part of a Oneof, then at maximum one field in the Oneof is set
659          * and it is not repeated. There is no need to iterate through the others.
660          */
661         if (oneofDescriptor != null) {
662           // Skip other fields in the Oneof we know are not set
663           i += oneofDescriptor.getFieldCount() - 1;
664           if (!hasOneof(oneofDescriptor)) {
665             // If no field is set in the Oneof, skip all the fields in the Oneof
666             continue;
667           }
668           // Get the pointer to the only field which is set in the Oneof
669           field = getOneofFieldDescriptor(oneofDescriptor);
670         } else {
671           // If we are not in a Oneof, we need to check if the field is set and if it is repeated
672           if (field.isRepeated()) {
673             final List<?> value = (List<?>) getField(field);
674             if (!value.isEmpty()) {
675               result.put(field, value);
676             }
677             continue;
678           }
679           if (!hasField(field)) {
680             continue;
681           }
682         }
683         // Add the field to the map
684         result.put(field, getField(field));
685       }
686       return result;
687     }
688 
689     @Override
690     public Message.Builder newBuilderForField(final FieldDescriptor field) {
691       return internalGetFieldAccessorTable().getField(field).newBuilder();
692     }
693 
694     @Override
695     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
696       return internalGetFieldAccessorTable().getField(field).getBuilder(this);
697     }
698 
699     @Override
700     public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
701       return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
702           this, index);
703     }
704 
705     @Override
706     public boolean hasOneof(final OneofDescriptor oneof) {
707       return internalGetFieldAccessorTable().getOneof(oneof).has(this);
708     }
709 
710     @Override
711     public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
712       return internalGetFieldAccessorTable().getOneof(oneof).get(this);
713     }
714 
715     @Override
716     public boolean hasField(final FieldDescriptor field) {
717       return internalGetFieldAccessorTable().getField(field).has(this);
718     }
719 
720     @Override
721     public Object getField(final FieldDescriptor field) {
722       Object object = internalGetFieldAccessorTable().getField(field).get(this);
723       if (field.isRepeated()) {
724         // The underlying list object is still modifiable at this point.
725         // Make sure not to expose the modifiable list to the caller.
726         return Collections.unmodifiableList((List) object);
727       } else {
728         return object;
729       }
730     }
731 
732     @Override
733     public BuilderType setField(final FieldDescriptor field, final Object value) {
734       internalGetFieldAccessorTable().getField(field).set(this, value);
735       return (BuilderType) this;
736     }
737 
738     @Override
739     public BuilderType clearField(final FieldDescriptor field) {
740       internalGetFieldAccessorTable().getField(field).clear(this);
741       return (BuilderType) this;
742     }
743 
744     @Override
745     public BuilderType clearOneof(final OneofDescriptor oneof) {
746       internalGetFieldAccessorTable().getOneof(oneof).clear(this);
747       return (BuilderType) this;
748     }
749 
750     @Override
751     public int getRepeatedFieldCount(final FieldDescriptor field) {
752       return internalGetFieldAccessorTable().getField(field)
753           .getRepeatedCount(this);
754     }
755 
756     @Override
757     public Object getRepeatedField(final FieldDescriptor field, final int index) {
758       return internalGetFieldAccessorTable().getField(field)
759           .getRepeated(this, index);
760     }
761 
762     @Override
763     public BuilderType setRepeatedField(
764         final FieldDescriptor field, final int index, final Object value) {
765       internalGetFieldAccessorTable().getField(field)
766         .setRepeated(this, index, value);
767       return (BuilderType) this;
768     }
769 
770     @Override
771     public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) {
772       internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
773       return (BuilderType) this;
774     }
775 
776     private BuilderType setUnknownFieldsInternal(final UnknownFieldSet unknownFields) {
777       unknownFieldsOrBuilder = unknownFields;
778       onChanged();
779       return (BuilderType) this;
780     }
781 
782     @Override
783     public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
784       return setUnknownFieldsInternal(unknownFields);
785     }
786 
787     /**
788      * This method is obsolete, but we must retain it for compatibility with
789      * older generated code.
790      */
791     protected BuilderType setUnknownFieldsProto3(final UnknownFieldSet unknownFields) {
792       return setUnknownFieldsInternal(unknownFields);
793     }
794 
795     @Override
796     public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
797       if (UnknownFieldSet.getDefaultInstance().equals(unknownFields)) {
798         return (BuilderType) this;
799       }
800 
801       if (UnknownFieldSet.getDefaultInstance().equals(unknownFieldsOrBuilder)) {
802         unknownFieldsOrBuilder = unknownFields;
803         onChanged();
804         return (BuilderType) this;
805       }
806 
807       getUnknownFieldSetBuilder().mergeFrom(unknownFields);
808       onChanged();
809       return (BuilderType) this;
810     }
811 
812 
813     @Override
814     public boolean isInitialized() {
815       for (final FieldDescriptor field : getDescriptorForType().getFields()) {
816         // Check that all required fields are present.
817         if (field.isRequired()) {
818           if (!hasField(field)) {
819             return false;
820           }
821         }
822         // Check that embedded messages are initialized.
823         if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
824           if (field.isRepeated()) {
825             @SuppressWarnings("unchecked") final
826             List<Message> messageList = (List<Message>) getField(field);
827             for (final Message element : messageList) {
828               if (!element.isInitialized()) {
829                 return false;
830               }
831             }
832           } else {
833             if (hasField(field) &&
834                 !((Message) getField(field)).isInitialized()) {
835               return false;
836             }
837           }
838         }
839       }
840       return true;
841     }
842 
843     @Override
844     public final UnknownFieldSet getUnknownFields() {
845       if (unknownFieldsOrBuilder instanceof UnknownFieldSet) {
846         return (UnknownFieldSet) unknownFieldsOrBuilder;
847       } else {
848         return ((UnknownFieldSet.Builder) unknownFieldsOrBuilder).buildPartial();
849       }
850     }
851 
852     /**
853      * Called by generated subclasses to parse an unknown field.
854      *
855      * @return {@code true} unless the tag is an end-group tag.
856      */
857     protected boolean parseUnknownField(
858         CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)
859         throws IOException {
860       if (input.shouldDiscardUnknownFields()) {
861         return input.skipField(tag);
862       }
863       return getUnknownFieldSetBuilder().mergeFieldFrom(tag, input);
864     }
865 
866     /** Called by generated subclasses to add to the unknown field set. */
867     protected final void mergeUnknownLengthDelimitedField(int number, ByteString bytes) {
868       getUnknownFieldSetBuilder().mergeLengthDelimitedField(number, bytes);
869     }
870 
871     /** Called by generated subclasses to add to the unknown field set. */
872     protected final void mergeUnknownVarintField(int number, int value) {
873       getUnknownFieldSetBuilder().mergeVarintField(number, value);
874     }
875 
876     @Override
877     protected UnknownFieldSet.Builder getUnknownFieldSetBuilder() {
878       if (unknownFieldsOrBuilder instanceof UnknownFieldSet) {
879         unknownFieldsOrBuilder = ((UnknownFieldSet) unknownFieldsOrBuilder).toBuilder();
880       }
881       onChanged();
882       return (UnknownFieldSet.Builder) unknownFieldsOrBuilder;
883     }
884 
885     @Override
886     protected void setUnknownFieldSetBuilder(UnknownFieldSet.Builder builder) {
887       unknownFieldsOrBuilder = builder;
888       onChanged();
889     }
890 
891     /**
892      * Implementation of {@link BuilderParent} for giving to our children. This
893      * small inner class makes it so we don't publicly expose the BuilderParent
894      * methods.
895      */
896     private class BuilderParentImpl implements BuilderParent {
897 
898       @Override
899       public void markDirty() {
900         onChanged();
901       }
902     }
903 
904     /**
905      * Gets the {@link BuilderParent} for giving to our children.
906      * @return The builder parent for our children.
907      */
908     protected BuilderParent getParentForChildren() {
909       if (meAsParent == null) {
910         meAsParent = new BuilderParentImpl();
911       }
912       return meAsParent;
913     }
914 
915     /**
916      * Called when a the builder or one of its nested children has changed
917      * and any parent should be notified of its invalidation.
918      */
919     protected final void onChanged() {
920       if (isClean && builderParent != null) {
921         builderParent.markDirty();
922 
923         // Don't keep dispatching invalidations until build is called again.
924         isClean = false;
925       }
926     }
927 
928     /**
929      * Gets the map field with the given field number. This method should be
930      * overridden in the generated message class if the message contains map
931      * fields.
932      *
933      * Unlike other field types, reflection support for map fields can't be
934      * implemented based on generated public API because we need to access a
935      * map field as a list in reflection API but the generated API only allows
936      * us to access it as a map. This method returns the underlying map field
937      * directly and thus enables us to access the map field as a list.
938      */
939     @SuppressWarnings({"unused", "rawtypes"})
940     protected MapField internalGetMapField(int fieldNumber) {
941       // Note that we can't use descriptor names here because this method will
942       // be called when descriptor is being initialized.
943       throw new RuntimeException(
944           "No map fields found in " + getClass().getName());
945     }
946 
947     /** Like {@link #internalGetMapField} but return a mutable version. */
948     @SuppressWarnings({"unused", "rawtypes"})
949     protected MapField internalGetMutableMapField(int fieldNumber) {
950       // Note that we can't use descriptor names here because this method will
951       // be called when descriptor is being initialized.
952       throw new RuntimeException(
953           "No map fields found in " + getClass().getName());
954     }
955   }
956 
957   // =================================================================
958   // Extensions-related stuff
959 
960   public interface ExtendableMessageOrBuilder<
961       MessageType extends ExtendableMessage> extends MessageOrBuilder {
962     // Re-define for return type covariance.
963     @Override
964     Message getDefaultInstanceForType();
965 
966     /** Check if a singular extension is present. */
967     <Type> boolean hasExtension(
968         ExtensionLite<MessageType, Type> extension);
969 
970     /** Get the number of elements in a repeated extension. */
971     <Type> int getExtensionCount(
972         ExtensionLite<MessageType, List<Type>> extension);
973 
974     /** Get the value of an extension. */
975     <Type> Type getExtension(
976         ExtensionLite<MessageType, Type> extension);
977 
978     /** Get one element of a repeated extension. */
979     <Type> Type getExtension(
980         ExtensionLite<MessageType, List<Type>> extension,
981         int index);
982 
983     /** Check if a singular extension is present. */
984     <Type> boolean hasExtension(
985         Extension<MessageType, Type> extension);
986     /** Check if a singular extension is present. */
987     <Type> boolean hasExtension(
988         GeneratedExtension<MessageType, Type> extension);
989     /** Get the number of elements in a repeated extension. */
990     <Type> int getExtensionCount(
991         Extension<MessageType, List<Type>> extension);
992     /** Get the number of elements in a repeated extension. */
993     <Type> int getExtensionCount(
994         GeneratedExtension<MessageType, List<Type>> extension);
995     /** Get the value of an extension. */
996     <Type> Type getExtension(
997         Extension<MessageType, Type> extension);
998     /** Get the value of an extension. */
999     <Type> Type getExtension(
1000         GeneratedExtension<MessageType, Type> extension);
1001     /** Get one element of a repeated extension. */
1002     <Type> Type getExtension(
1003         Extension<MessageType, List<Type>> extension,
1004         int index);
1005     /** Get one element of a repeated extension. */
1006     <Type> Type getExtension(
1007         GeneratedExtension<MessageType, List<Type>> extension,
1008         int index);
1009   }
1010 
1011   /**
1012    * Generated message classes for message types that contain extension ranges
1013    * subclass this.
1014    *
1015    * <p>This class implements type-safe accessors for extensions.  They
1016    * implement all the same operations that you can do with normal fields --
1017    * e.g. "has", "get", and "getCount" -- but for extensions.  The extensions
1018    * are identified using instances of the class {@link GeneratedExtension};
1019    * the protocol compiler generates a static instance of this class for every
1020    * extension in its input.  Through the magic of generics, all is made
1021    * type-safe.
1022    *
1023    * <p>For example, imagine you have the {@code .proto} file:
1024    *
1025    * <pre>
1026    * option java_class = "MyProto";
1027    *
1028    * message Foo {
1029    *   extensions 1000 to max;
1030    * }
1031    *
1032    * extend Foo {
1033    *   optional int32 bar;
1034    * }
1035    * </pre>
1036    *
1037    * <p>Then you might write code like:
1038    *
1039    * <pre>
1040    * MyProto.Foo foo = getFoo();
1041    * int i = foo.getExtension(MyProto.bar);
1042    * </pre>
1043    *
1044    * <p>See also {@link ExtendableBuilder}.
1045    */
1046   public abstract static class ExtendableMessage<
1047         MessageType extends ExtendableMessage>
1048       extends GeneratedMessageV3
1049       implements ExtendableMessageOrBuilder<MessageType> {
1050 
1051     private static final long serialVersionUID = 1L;
1052 
1053     private final FieldSet<FieldDescriptor> extensions;
1054 
1055     protected ExtendableMessage() {
1056       this.extensions = FieldSet.newFieldSet();
1057     }
1058 
1059     protected ExtendableMessage(
1060         ExtendableBuilder<MessageType, ?> builder) {
1061       super(builder);
1062       this.extensions = builder.buildExtensions();
1063     }
1064 
1065     private void verifyExtensionContainingType(
1066         final Extension<MessageType, ?> extension) {
1067       if (extension.getDescriptor().getContainingType() !=
1068           getDescriptorForType()) {
1069         // This can only happen if someone uses unchecked operations.
1070         throw new IllegalArgumentException(
1071           "Extension is for type \"" +
1072           extension.getDescriptor().getContainingType().getFullName() +
1073           "\" which does not match message type \"" +
1074           getDescriptorForType().getFullName() + "\".");
1075       }
1076     }
1077 
1078     /** Check if a singular extension is present. */
1079     @Override
1080     @SuppressWarnings("unchecked")
1081     public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
1082       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
1083 
1084       verifyExtensionContainingType(extension);
1085       return extensions.hasField(extension.getDescriptor());
1086     }
1087 
1088     /** Get the number of elements in a repeated extension. */
1089     @Override
1090     @SuppressWarnings("unchecked")
1091     public final <Type> int getExtensionCount(
1092         final ExtensionLite<MessageType, List<Type>> extensionLite) {
1093       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1094 
1095       verifyExtensionContainingType(extension);
1096       final FieldDescriptor descriptor = extension.getDescriptor();
1097       return extensions.getRepeatedFieldCount(descriptor);
1098     }
1099 
1100     /** Get the value of an extension. */
1101     @Override
1102     @SuppressWarnings("unchecked")
1103     public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
1104       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
1105 
1106       verifyExtensionContainingType(extension);
1107       FieldDescriptor descriptor = extension.getDescriptor();
1108       final Object value = extensions.getField(descriptor);
1109       if (value == null) {
1110         if (descriptor.isRepeated()) {
1111           return (Type) Collections.emptyList();
1112         } else if (descriptor.getJavaType() ==
1113                    FieldDescriptor.JavaType.MESSAGE) {
1114           return (Type) extension.getMessageDefaultInstance();
1115         } else {
1116           return (Type) extension.fromReflectionType(
1117               descriptor.getDefaultValue());
1118         }
1119       } else {
1120         return (Type) extension.fromReflectionType(value);
1121       }
1122     }
1123 
1124     /** Get one element of a repeated extension. */
1125     @Override
1126     @SuppressWarnings("unchecked")
1127     public final <Type> Type getExtension(
1128         final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
1129       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1130 
1131       verifyExtensionContainingType(extension);
1132       FieldDescriptor descriptor = extension.getDescriptor();
1133       return (Type) extension.singularFromReflectionType(
1134           extensions.getRepeatedField(descriptor, index));
1135     }
1136 
1137     /** Check if a singular extension is present. */
1138     @Override
1139     public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
1140       return hasExtension((ExtensionLite<MessageType, Type>) extension);
1141     }
1142     /** Check if a singular extension is present. */
1143     @Override
1144     public final <Type> boolean hasExtension(
1145         final GeneratedExtension<MessageType, Type> extension) {
1146       return hasExtension((ExtensionLite<MessageType, Type>) extension);
1147     }
1148     /** Get the number of elements in a repeated extension. */
1149     @Override
1150     public final <Type> int getExtensionCount(
1151         final Extension<MessageType, List<Type>> extension) {
1152       return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
1153     }
1154     /** Get the number of elements in a repeated extension. */
1155     @Override
1156     public final <Type> int getExtensionCount(
1157         final GeneratedExtension<MessageType, List<Type>> extension) {
1158       return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
1159     }
1160     /** Get the value of an extension. */
1161     @Override
1162     public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
1163       return getExtension((ExtensionLite<MessageType, Type>) extension);
1164     }
1165     /** Get the value of an extension. */
1166     @Override
1167     public final <Type> Type getExtension(
1168         final GeneratedExtension<MessageType, Type> extension) {
1169       return getExtension((ExtensionLite<MessageType, Type>) extension);
1170     }
1171     /** Get one element of a repeated extension. */
1172     @Override
1173     public final <Type> Type getExtension(
1174         final Extension<MessageType, List<Type>> extension, final int index) {
1175       return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
1176     }
1177     /** Get one element of a repeated extension. */
1178     @Override
1179     public final <Type> Type getExtension(
1180         final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
1181       return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
1182     }
1183 
1184     /** Called by subclasses to check if all extensions are initialized. */
1185     protected boolean extensionsAreInitialized() {
1186       return extensions.isInitialized();
1187     }
1188 
1189     @Override
1190     public boolean isInitialized() {
1191       return super.isInitialized() && extensionsAreInitialized();
1192     }
1193 
1194     @Override
1195     protected boolean parseUnknownField(
1196         CodedInputStream input,
1197         UnknownFieldSet.Builder unknownFields,
1198         ExtensionRegistryLite extensionRegistry,
1199         int tag) throws IOException {
1200       return MessageReflection.mergeFieldFrom(
1201           input, input.shouldDiscardUnknownFields() ? null : unknownFields, extensionRegistry,
1202           getDescriptorForType(), new MessageReflection.ExtensionAdapter(extensions), tag);
1203     }
1204 
1205     /**
1206      * Delegates to parseUnknownField. This method is obsolete, but we must retain it for
1207      * compatibility with older generated code.
1208      */
1209     @Override
1210     protected boolean parseUnknownFieldProto3(
1211         CodedInputStream input,
1212         UnknownFieldSet.Builder unknownFields,
1213         ExtensionRegistryLite extensionRegistry,
1214         int tag) throws IOException {
1215       return parseUnknownField(input, unknownFields, extensionRegistry, tag);
1216     }
1217 
1218 
1219     /**
1220      * Used by parsing constructors in generated classes.
1221      */
1222     @Override
1223     protected void makeExtensionsImmutable() {
1224       extensions.makeImmutable();
1225     }
1226 
1227     /**
1228      * Used by subclasses to serialize extensions.  Extension ranges may be
1229      * interleaved with field numbers, but we must write them in canonical
1230      * (sorted by field number) order.  ExtensionWriter helps us write
1231      * individual ranges of extensions at once.
1232      */
1233     protected class ExtensionWriter {
1234       // Imagine how much simpler this code would be if Java iterators had
1235       // a way to get the next element without advancing the iterator.
1236 
1237       private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
1238         extensions.iterator();
1239       private Map.Entry<FieldDescriptor, Object> next;
1240       private final boolean messageSetWireFormat;
1241 
1242       private ExtensionWriter(final boolean messageSetWireFormat) {
1243         if (iter.hasNext()) {
1244           next = iter.next();
1245         }
1246         this.messageSetWireFormat = messageSetWireFormat;
1247       }
1248 
1249       public void writeUntil(final int end, final CodedOutputStream output)
1250                              throws IOException {
1251         while (next != null && next.getKey().getNumber() < end) {
1252           FieldDescriptor descriptor = next.getKey();
1253           if (messageSetWireFormat && descriptor.getLiteJavaType() ==
1254                   WireFormat.JavaType.MESSAGE &&
1255               !descriptor.isRepeated()) {
1256             if (next instanceof LazyField.LazyEntry<?>) {
1257               output.writeRawMessageSetExtension(descriptor.getNumber(),
1258                   ((LazyField.LazyEntry<?>) next).getField().toByteString());
1259             } else {
1260               output.writeMessageSetExtension(descriptor.getNumber(),
1261                                               (Message) next.getValue());
1262             }
1263           } else {
1264             // TODO(xiangl): Taken care of following code, it may cause
1265             // problem when we use LazyField for normal fields/extensions.
1266             // Due to the optional field can be duplicated at the end of
1267             // serialized bytes, which will make the serialized size change
1268             // after lazy field parsed. So when we use LazyField globally,
1269             // we need to change the following write method to write cached
1270             // bytes directly rather than write the parsed message.
1271             FieldSet.writeField(descriptor, next.getValue(), output);
1272           }
1273           if (iter.hasNext()) {
1274             next = iter.next();
1275           } else {
1276             next = null;
1277           }
1278         }
1279       }
1280     }
1281 
1282     protected ExtensionWriter newExtensionWriter() {
1283       return new ExtensionWriter(false);
1284     }
1285     protected ExtensionWriter newMessageSetExtensionWriter() {
1286       return new ExtensionWriter(true);
1287     }
1288 
1289     /** Called by subclasses to compute the size of extensions. */
1290     protected int extensionsSerializedSize() {
1291       return extensions.getSerializedSize();
1292     }
1293     protected int extensionsSerializedSizeAsMessageSet() {
1294       return extensions.getMessageSetSerializedSize();
1295     }
1296 
1297     // ---------------------------------------------------------------
1298     // Reflection
1299 
1300     protected Map<FieldDescriptor, Object> getExtensionFields() {
1301       return extensions.getAllFields();
1302     }
1303 
1304     @Override
1305     public Map<FieldDescriptor, Object> getAllFields() {
1306       final Map<FieldDescriptor, Object> result =
1307           super.getAllFieldsMutable(/* getBytesForString = */ false);
1308       result.putAll(getExtensionFields());
1309       return Collections.unmodifiableMap(result);
1310     }
1311 
1312     @Override
1313     public Map<FieldDescriptor, Object> getAllFieldsRaw() {
1314       final Map<FieldDescriptor, Object> result =
1315           super.getAllFieldsMutable(/* getBytesForString = */ false);
1316       result.putAll(getExtensionFields());
1317       return Collections.unmodifiableMap(result);
1318     }
1319 
1320     @Override
1321     public boolean hasField(final FieldDescriptor field) {
1322       if (field.isExtension()) {
1323         verifyContainingType(field);
1324         return extensions.hasField(field);
1325       } else {
1326         return super.hasField(field);
1327       }
1328     }
1329 
1330     @Override
1331     public Object getField(final FieldDescriptor field) {
1332       if (field.isExtension()) {
1333         verifyContainingType(field);
1334         final Object value = extensions.getField(field);
1335         if (value == null) {
1336           if (field.isRepeated()) {
1337             return Collections.emptyList();
1338           } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
1339             // Lacking an ExtensionRegistry, we have no way to determine the
1340             // extension's real type, so we return a DynamicMessage.
1341             return DynamicMessage.getDefaultInstance(field.getMessageType());
1342           } else {
1343             return field.getDefaultValue();
1344           }
1345         } else {
1346           return value;
1347         }
1348       } else {
1349         return super.getField(field);
1350       }
1351     }
1352 
1353     @Override
1354     public int getRepeatedFieldCount(final FieldDescriptor field) {
1355       if (field.isExtension()) {
1356         verifyContainingType(field);
1357         return extensions.getRepeatedFieldCount(field);
1358       } else {
1359         return super.getRepeatedFieldCount(field);
1360       }
1361     }
1362 
1363     @Override
1364     public Object getRepeatedField(final FieldDescriptor field,
1365                                    final int index) {
1366       if (field.isExtension()) {
1367         verifyContainingType(field);
1368         return extensions.getRepeatedField(field, index);
1369       } else {
1370         return super.getRepeatedField(field, index);
1371       }
1372     }
1373 
1374     private void verifyContainingType(final FieldDescriptor field) {
1375       if (field.getContainingType() != getDescriptorForType()) {
1376         throw new IllegalArgumentException(
1377           "FieldDescriptor does not match message type.");
1378       }
1379     }
1380   }
1381 
1382   /**
1383    * Generated message builders for message types that contain extension ranges
1384    * subclass this.
1385    *
1386    * <p>This class implements type-safe accessors for extensions.  They
1387    * implement all the same operations that you can do with normal fields --
1388    * e.g. "get", "set", and "add" -- but for extensions.  The extensions are
1389    * identified using instances of the class {@link GeneratedExtension}; the
1390    * protocol compiler generates a static instance of this class for every
1391    * extension in its input.  Through the magic of generics, all is made
1392    * type-safe.
1393    *
1394    * <p>For example, imagine you have the {@code .proto} file:
1395    *
1396    * <pre>
1397    * option java_class = "MyProto";
1398    *
1399    * message Foo {
1400    *   extensions 1000 to max;
1401    * }
1402    *
1403    * extend Foo {
1404    *   optional int32 bar;
1405    * }
1406    * </pre>
1407    *
1408    * <p>Then you might write code like:
1409    *
1410    * <pre>
1411    * MyProto.Foo foo =
1412    *   MyProto.Foo.newBuilder()
1413    *     .setExtension(MyProto.bar, 123)
1414    *     .build();
1415    * </pre>
1416    *
1417    * <p>See also {@link ExtendableMessage}.
1418    */
1419   @SuppressWarnings("unchecked")
1420   public abstract static class ExtendableBuilder<
1421         MessageType extends ExtendableMessage,
1422         BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
1423       extends Builder<BuilderType>
1424       implements ExtendableMessageOrBuilder<MessageType> {
1425 
1426     private FieldSet.Builder<FieldDescriptor> extensions;
1427 
1428     protected ExtendableBuilder() {}
1429 
1430     protected ExtendableBuilder(
1431         BuilderParent parent) {
1432       super(parent);
1433     }
1434 
1435     // For immutable message conversion.
1436     void internalSetExtensionSet(FieldSet<FieldDescriptor> extensions) {
1437       this.extensions = FieldSet.Builder.fromFieldSet(extensions);
1438     }
1439 
1440     @Override
1441     public BuilderType clear() {
1442       extensions = null;
1443       return super.clear();
1444     }
1445 
1446     private void ensureExtensionsIsMutable() {
1447       if (extensions == null) {
1448         extensions = FieldSet.newBuilder();
1449       }
1450     }
1451 
1452     private void verifyExtensionContainingType(
1453         final Extension<MessageType, ?> extension) {
1454       if (extension.getDescriptor().getContainingType() !=
1455           getDescriptorForType()) {
1456         // This can only happen if someone uses unchecked operations.
1457         throw new IllegalArgumentException(
1458           "Extension is for type \"" +
1459           extension.getDescriptor().getContainingType().getFullName() +
1460           "\" which does not match message type \"" +
1461           getDescriptorForType().getFullName() + "\".");
1462       }
1463     }
1464 
1465     /** Check if a singular extension is present. */
1466     @Override
1467     public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
1468       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
1469 
1470       verifyExtensionContainingType(extension);
1471       return extensions == null ? false : extensions.hasField(extension.getDescriptor());
1472     }
1473 
1474     /** Get the number of elements in a repeated extension. */
1475     @Override
1476     public final <Type> int getExtensionCount(
1477         final ExtensionLite<MessageType, List<Type>> extensionLite) {
1478       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1479 
1480       verifyExtensionContainingType(extension);
1481       final FieldDescriptor descriptor = extension.getDescriptor();
1482       return extensions == null ? 0 : extensions.getRepeatedFieldCount(descriptor);
1483     }
1484 
1485     /** Get the value of an extension. */
1486     @Override
1487     public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
1488       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
1489 
1490       verifyExtensionContainingType(extension);
1491       FieldDescriptor descriptor = extension.getDescriptor();
1492       final Object value = extensions == null ? null : extensions.getField(descriptor);
1493       if (value == null) {
1494         if (descriptor.isRepeated()) {
1495           return (Type) Collections.emptyList();
1496         } else if (descriptor.getJavaType() ==
1497                    FieldDescriptor.JavaType.MESSAGE) {
1498           return (Type) extension.getMessageDefaultInstance();
1499         } else {
1500           return (Type) extension.fromReflectionType(
1501               descriptor.getDefaultValue());
1502         }
1503       } else {
1504         return (Type) extension.fromReflectionType(value);
1505       }
1506     }
1507 
1508     /** Get one element of a repeated extension. */
1509     @Override
1510     public final <Type> Type getExtension(
1511         final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
1512       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1513 
1514       verifyExtensionContainingType(extension);
1515       FieldDescriptor descriptor = extension.getDescriptor();
1516       if (extensions == null) {
1517         throw new IndexOutOfBoundsException();
1518       }
1519       return (Type)
1520           extension.singularFromReflectionType(extensions.getRepeatedField(descriptor, index));
1521     }
1522 
1523     /** Set the value of an extension. */
1524     public final <Type> BuilderType setExtension(
1525         final ExtensionLite<MessageType, Type> extensionLite,
1526         final Type value) {
1527       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
1528 
1529       verifyExtensionContainingType(extension);
1530       ensureExtensionsIsMutable();
1531       final FieldDescriptor descriptor = extension.getDescriptor();
1532       extensions.setField(descriptor, extension.toReflectionType(value));
1533       onChanged();
1534       return (BuilderType) this;
1535     }
1536 
1537     /** Set the value of one element of a repeated extension. */
1538     public final <Type> BuilderType setExtension(
1539         final ExtensionLite<MessageType, List<Type>> extensionLite,
1540         final int index, final Type value) {
1541       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1542 
1543       verifyExtensionContainingType(extension);
1544       ensureExtensionsIsMutable();
1545       final FieldDescriptor descriptor = extension.getDescriptor();
1546       extensions.setRepeatedField(
1547         descriptor, index,
1548         extension.singularToReflectionType(value));
1549       onChanged();
1550       return (BuilderType) this;
1551     }
1552 
1553     /** Append a value to a repeated extension. */
1554     public final <Type> BuilderType addExtension(
1555         final ExtensionLite<MessageType, List<Type>> extensionLite,
1556         final Type value) {
1557       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
1558 
1559       verifyExtensionContainingType(extension);
1560       ensureExtensionsIsMutable();
1561       final FieldDescriptor descriptor = extension.getDescriptor();
1562       extensions.addRepeatedField(
1563           descriptor, extension.singularToReflectionType(value));
1564       onChanged();
1565       return (BuilderType) this;
1566     }
1567 
1568     /** Clear an extension. */
1569     public final BuilderType clearExtension(final ExtensionLite<MessageType, ?> extensionLite) {
1570       Extension<MessageType, ?> extension = checkNotLite(extensionLite);
1571 
1572       verifyExtensionContainingType(extension);
1573       ensureExtensionsIsMutable();
1574       extensions.clearField(extension.getDescriptor());
1575       onChanged();
1576       return (BuilderType) this;
1577     }
1578 
1579     /** Check if a singular extension is present. */
1580     @Override
1581     public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
1582       return hasExtension((ExtensionLite<MessageType, Type>) extension);
1583     }
1584     /** Check if a singular extension is present. */
1585     @Override
1586     public final <Type> boolean hasExtension(
1587         final GeneratedExtension<MessageType, Type> extension) {
1588       return hasExtension((ExtensionLite<MessageType, Type>) extension);
1589     }
1590     /** Get the number of elements in a repeated extension. */
1591     @Override
1592     public final <Type> int getExtensionCount(
1593         final Extension<MessageType, List<Type>> extension) {
1594       return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
1595     }
1596     /** Get the number of elements in a repeated extension. */
1597     @Override
1598     public final <Type> int getExtensionCount(
1599         final GeneratedExtension<MessageType, List<Type>> extension) {
1600       return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
1601     }
1602     /** Get the value of an extension. */
1603     @Override
1604     public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
1605       return getExtension((ExtensionLite<MessageType, Type>) extension);
1606     }
1607     /** Get the value of an extension. */
1608     @Override
1609     public final <Type> Type getExtension(
1610         final GeneratedExtension<MessageType, Type> extension) {
1611       return getExtension((ExtensionLite<MessageType, Type>) extension);
1612     }
1613     /** Get the value of an extension. */
1614     @Override
1615     public final <Type> Type getExtension(
1616         final Extension<MessageType, List<Type>> extension, final int index) {
1617       return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
1618     }
1619     /** Get the value of an extension. */
1620     @Override
1621     public final <Type> Type getExtension(
1622         final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
1623       return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
1624     }
1625     /** Set the value of an extension. */
1626     public final <Type> BuilderType setExtension(
1627         final Extension<MessageType, Type> extension, final Type value) {
1628       return setExtension((ExtensionLite<MessageType, Type>) extension, value);
1629     }
1630     /** Set the value of an extension. */
1631     public <Type> BuilderType setExtension(
1632         final GeneratedExtension<MessageType, Type> extension, final Type value) {
1633       return setExtension((ExtensionLite<MessageType, Type>) extension, value);
1634     }
1635     /** Set the value of one element of a repeated extension. */
1636     public final <Type> BuilderType setExtension(
1637         final Extension<MessageType, List<Type>> extension,
1638         final int index, final Type value) {
1639       return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
1640     }
1641     /** Set the value of one element of a repeated extension. */
1642     public <Type> BuilderType setExtension(
1643         final GeneratedExtension<MessageType, List<Type>> extension,
1644         final int index, final Type value) {
1645       return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
1646     }
1647     /** Append a value to a repeated extension. */
1648     public final <Type> BuilderType addExtension(
1649         final Extension<MessageType, List<Type>> extension, final Type value) {
1650       return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
1651     }
1652     /** Append a value to a repeated extension. */
1653     public <Type> BuilderType addExtension(
1654         final GeneratedExtension<MessageType, List<Type>> extension, final Type value) {
1655       return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
1656     }
1657     /** Clear an extension. */
1658     public final <Type> BuilderType clearExtension(
1659         final Extension<MessageType, ?> extension) {
1660       return clearExtension((ExtensionLite<MessageType, ?>) extension);
1661     }
1662     /** Clear an extension. */
1663     public <Type> BuilderType clearExtension(
1664         final GeneratedExtension<MessageType, ?> extension) {
1665       return clearExtension((ExtensionLite<MessageType, ?>) extension);
1666     }
1667 
1668     /** Called by subclasses to check if all extensions are initialized. */
1669     protected boolean extensionsAreInitialized() {
1670       return extensions == null ? true : extensions.isInitialized();
1671     }
1672 
1673     /**
1674      * Called by the build code path to create a copy of the extensions for
1675      * building the message.
1676      */
1677     private FieldSet<FieldDescriptor> buildExtensions() {
1678       return extensions == null
1679           ? (FieldSet<FieldDescriptor>) FieldSet.emptySet()
1680           : extensions.buildPartial();
1681     }
1682 
1683     @Override
1684     public boolean isInitialized() {
1685       return super.isInitialized() && extensionsAreInitialized();
1686     }
1687 
1688     // ---------------------------------------------------------------
1689     // Reflection
1690 
1691     @Override
1692     public Map<FieldDescriptor, Object> getAllFields() {
1693       final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
1694       if (extensions != null) {
1695         result.putAll(extensions.getAllFields());
1696       }
1697       return Collections.unmodifiableMap(result);
1698     }
1699 
1700     @Override
1701     public Object getField(final FieldDescriptor field) {
1702       if (field.isExtension()) {
1703         verifyContainingType(field);
1704         final Object value = extensions == null ? null : extensions.getField(field);
1705         if (value == null) {
1706           if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
1707             // Lacking an ExtensionRegistry, we have no way to determine the
1708             // extension's real type, so we return a DynamicMessage.
1709             return DynamicMessage.getDefaultInstance(field.getMessageType());
1710           } else {
1711             return field.getDefaultValue();
1712           }
1713         } else {
1714           return value;
1715         }
1716       } else {
1717         return super.getField(field);
1718       }
1719     }
1720 
1721     @Override
1722     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
1723       if (field.isExtension()) {
1724         verifyContainingType(field);
1725         if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
1726           throw new UnsupportedOperationException(
1727               "getFieldBuilder() called on a non-Message type.");
1728         }
1729         ensureExtensionsIsMutable();
1730         final Object value = extensions.getFieldAllowBuilders(field);
1731         if (value == null) {
1732           Message.Builder builder = DynamicMessage.newBuilder(field.getMessageType());
1733           extensions.setField(field, builder);
1734           onChanged();
1735           return builder;
1736         } else {
1737           if (value instanceof Message.Builder) {
1738             return (Message.Builder) value;
1739           } else if (value instanceof Message) {
1740             Message.Builder builder = ((Message) value).toBuilder();
1741             extensions.setField(field, builder);
1742             onChanged();
1743             return builder;
1744           } else {
1745             throw new UnsupportedOperationException(
1746                 "getRepeatedFieldBuilder() called on a non-Message type.");
1747           }
1748         }
1749       } else {
1750         return super.getFieldBuilder(field);
1751       }
1752     }
1753 
1754     @Override
1755     public int getRepeatedFieldCount(final FieldDescriptor field) {
1756       if (field.isExtension()) {
1757         verifyContainingType(field);
1758         return extensions == null ? 0 : extensions.getRepeatedFieldCount(field);
1759       } else {
1760         return super.getRepeatedFieldCount(field);
1761       }
1762     }
1763 
1764     @Override
1765     public Object getRepeatedField(final FieldDescriptor field,
1766                                    final int index) {
1767       if (field.isExtension()) {
1768         verifyContainingType(field);
1769         if (extensions == null) {
1770           throw new IndexOutOfBoundsException();
1771         }
1772         return extensions.getRepeatedField(field, index);
1773       } else {
1774         return super.getRepeatedField(field, index);
1775       }
1776     }
1777 
1778     @Override
1779     public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, final int index) {
1780       if (field.isExtension()) {
1781         verifyContainingType(field);
1782         ensureExtensionsIsMutable();
1783         if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
1784           throw new UnsupportedOperationException(
1785               "getRepeatedFieldBuilder() called on a non-Message type.");
1786         }
1787         final Object value = extensions.getRepeatedFieldAllowBuilders(field, index);
1788         if (value instanceof Message.Builder) {
1789           return (Message.Builder) value;
1790         } else if (value instanceof Message) {
1791           Message.Builder builder = ((Message) value).toBuilder();
1792           extensions.setRepeatedField(field, index, builder);
1793           onChanged();
1794           return builder;
1795         } else {
1796           throw new UnsupportedOperationException(
1797               "getRepeatedFieldBuilder() called on a non-Message type.");
1798         }
1799       } else {
1800         return super.getRepeatedFieldBuilder(field, index);
1801       }
1802     }
1803 
1804     @Override
1805     public boolean hasField(final FieldDescriptor field) {
1806       if (field.isExtension()) {
1807         verifyContainingType(field);
1808         return extensions == null ? false : extensions.hasField(field);
1809       } else {
1810         return super.hasField(field);
1811       }
1812     }
1813 
1814     @Override
1815     public BuilderType setField(final FieldDescriptor field,
1816                                 final Object value) {
1817       if (field.isExtension()) {
1818         verifyContainingType(field);
1819         ensureExtensionsIsMutable();
1820         extensions.setField(field, value);
1821         onChanged();
1822         return (BuilderType) this;
1823       } else {
1824         return super.setField(field, value);
1825       }
1826     }
1827 
1828     @Override
1829     public BuilderType clearField(final FieldDescriptor field) {
1830       if (field.isExtension()) {
1831         verifyContainingType(field);
1832         ensureExtensionsIsMutable();
1833         extensions.clearField(field);
1834         onChanged();
1835         return (BuilderType) this;
1836       } else {
1837         return super.clearField(field);
1838       }
1839     }
1840 
1841     @Override
1842     public BuilderType setRepeatedField(final FieldDescriptor field,
1843                                         final int index, final Object value) {
1844       if (field.isExtension()) {
1845         verifyContainingType(field);
1846         ensureExtensionsIsMutable();
1847         extensions.setRepeatedField(field, index, value);
1848         onChanged();
1849         return (BuilderType) this;
1850       } else {
1851         return super.setRepeatedField(field, index, value);
1852       }
1853     }
1854 
1855     @Override
1856     public BuilderType addRepeatedField(final FieldDescriptor field,
1857                                         final Object value) {
1858       if (field.isExtension()) {
1859         verifyContainingType(field);
1860         ensureExtensionsIsMutable();
1861         extensions.addRepeatedField(field, value);
1862         onChanged();
1863         return (BuilderType) this;
1864       } else {
1865         return super.addRepeatedField(field, value);
1866       }
1867     }
1868 
1869     @Override
1870     public Message.Builder newBuilderForField(final FieldDescriptor field) {
1871       if (field.isExtension()) {
1872         return DynamicMessage.newBuilder(field.getMessageType());
1873       } else {
1874         return super.newBuilderForField(field);
1875       }
1876     }
1877 
1878     protected final void mergeExtensionFields(final ExtendableMessage other) {
1879       if (other.extensions != null) {
1880         ensureExtensionsIsMutable();
1881         extensions.mergeFrom(other.extensions);
1882         onChanged();
1883       }
1884     }
1885 
1886     @Override
1887     protected boolean parseUnknownField(
1888         CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)
1889         throws IOException {
1890       ensureExtensionsIsMutable();
1891       return MessageReflection.mergeFieldFrom(
1892           input,
1893           input.shouldDiscardUnknownFields() ? null : getUnknownFieldSetBuilder(),
1894           extensionRegistry,
1895           getDescriptorForType(),
1896           new MessageReflection.ExtensionBuilderAdapter(extensions),
1897           tag);
1898     }
1899 
1900     private void verifyContainingType(final FieldDescriptor field) {
1901       if (field.getContainingType() != getDescriptorForType()) {
1902         throw new IllegalArgumentException(
1903           "FieldDescriptor does not match message type.");
1904       }
1905     }
1906   }
1907 
1908   // -----------------------------------------------------------------
1909 
1910   /**
1911    * Gets the descriptor for an extension. The implementation depends on whether
1912    * the extension is scoped in the top level of a file or scoped in a Message.
1913    */
1914   static interface ExtensionDescriptorRetriever {
1915     FieldDescriptor getDescriptor();
1916   }
1917 
1918 
1919   // =================================================================
1920 
1921   /** Calls Class.getMethod and throws a RuntimeException if it fails. */
1922   @SuppressWarnings("unchecked")
1923   private static Method getMethodOrDie(
1924       final Class clazz, final String name, final Class... params) {
1925     try {
1926       return clazz.getMethod(name, params);
1927     } catch (NoSuchMethodException e) {
1928       throw new RuntimeException(
1929         "Generated message class \"" + clazz.getName() +
1930         "\" missing method \"" + name + "\".", e);
1931     }
1932   }
1933 
1934   /** Calls invoke and throws a RuntimeException if it fails. */
1935   private static Object invokeOrDie(
1936       final Method method, final Object object, final Object... params) {
1937     try {
1938       return method.invoke(object, params);
1939     } catch (IllegalAccessException e) {
1940       throw new RuntimeException(
1941         "Couldn't use Java reflection to implement protocol message " +
1942         "reflection.", e);
1943     } catch (InvocationTargetException e) {
1944       final Throwable cause = e.getCause();
1945       if (cause instanceof RuntimeException) {
1946         throw (RuntimeException) cause;
1947       } else if (cause instanceof Error) {
1948         throw (Error) cause;
1949       } else {
1950         throw new RuntimeException(
1951           "Unexpected exception thrown by generated accessor method.", cause);
1952       }
1953     }
1954   }
1955 
1956   /**
1957    * Gets the map field with the given field number. This method should be overridden in the
1958    * generated message class if the message contains map fields.
1959    *
1960    * <p>Unlike other field types, reflection support for map fields can't be implemented based on
1961    * generated public API because we need to access a map field as a list in reflection API but the
1962    * generated API only allows us to access it as a map. This method returns the underlying map
1963    * field directly and thus enables us to access the map field as a list.
1964    */
1965   @SuppressWarnings({"rawtypes", "unused"})
1966   protected MapField internalGetMapField(int fieldNumber) {
1967     // Note that we can't use descriptor names here because this method will
1968     // be called when descriptor is being initialized.
1969     throw new RuntimeException(
1970         "No map fields found in " + getClass().getName());
1971   }
1972 
1973   /**
1974    * Users should ignore this class.  This class provides the implementation
1975    * with access to the fields of a message object using Java reflection.
1976    */
1977   public static final class FieldAccessorTable {
1978 
1979     /**
1980      * Construct a FieldAccessorTable for a particular message class.  Only
1981      * one FieldAccessorTable should ever be constructed per class.
1982      *
1983      * @param descriptor     The type's descriptor.
1984      * @param camelCaseNames The camelcase names of all fields in the message.
1985      *                       These are used to derive the accessor method names.
1986      * @param messageClass   The message type.
1987      * @param builderClass   The builder type.
1988      */
1989     public FieldAccessorTable(
1990         final Descriptor descriptor,
1991         final String[] camelCaseNames,
1992         final Class<? extends GeneratedMessageV3> messageClass,
1993         final Class<? extends Builder> builderClass) {
1994       this(descriptor, camelCaseNames);
1995       ensureFieldAccessorsInitialized(messageClass, builderClass);
1996     }
1997 
1998     /**
1999      * Construct a FieldAccessorTable for a particular message class without
2000      * initializing FieldAccessors.
2001      */
2002     public FieldAccessorTable(
2003         final Descriptor descriptor,
2004         final String[] camelCaseNames) {
2005       this.descriptor = descriptor;
2006       this.camelCaseNames = camelCaseNames;
2007       fields = new FieldAccessor[descriptor.getFields().size()];
2008       oneofs = new OneofAccessor[descriptor.getOneofs().size()];
2009       initialized = false;
2010     }
2011 
2012     /**
2013      * Ensures the field accessors are initialized. This method is thread-safe.
2014      *
2015      * @param messageClass   The message type.
2016      * @param builderClass   The builder type.
2017      * @return this
2018      */
2019     public FieldAccessorTable ensureFieldAccessorsInitialized(
2020         Class<? extends GeneratedMessageV3> messageClass,
2021         Class<? extends Builder> builderClass) {
2022       if (initialized) { return this; }
2023       synchronized (this) {
2024         if (initialized) { return this; }
2025         int fieldsSize = fields.length;
2026         for (int i = 0; i < fieldsSize; i++) {
2027           FieldDescriptor field = descriptor.getFields().get(i);
2028           String containingOneofCamelCaseName = null;
2029           if (field.getContainingOneof() != null) {
2030             containingOneofCamelCaseName =
2031                 camelCaseNames[fieldsSize + field.getContainingOneof().getIndex()];
2032           }
2033           if (field.isRepeated()) {
2034             if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
2035               if (field.isMapField()) {
2036                 fields[i] = new MapFieldAccessor(
2037                     field, camelCaseNames[i], messageClass, builderClass);
2038               } else {
2039                 fields[i] = new RepeatedMessageFieldAccessor(
2040                     field, camelCaseNames[i], messageClass, builderClass);
2041               }
2042             } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
2043               fields[i] = new RepeatedEnumFieldAccessor(
2044                   field, camelCaseNames[i], messageClass, builderClass);
2045             } else {
2046               fields[i] = new RepeatedFieldAccessor(
2047                   field, camelCaseNames[i], messageClass, builderClass);
2048             }
2049           } else {
2050             if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
2051               fields[i] = new SingularMessageFieldAccessor(
2052                   field, camelCaseNames[i], messageClass, builderClass,
2053                   containingOneofCamelCaseName);
2054             } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
2055               fields[i] = new SingularEnumFieldAccessor(
2056                   field, camelCaseNames[i], messageClass, builderClass,
2057                   containingOneofCamelCaseName);
2058             } else if (field.getJavaType() == FieldDescriptor.JavaType.STRING) {
2059               fields[i] = new SingularStringFieldAccessor(
2060                   field, camelCaseNames[i], messageClass, builderClass,
2061                   containingOneofCamelCaseName);
2062             } else {
2063               fields[i] = new SingularFieldAccessor(
2064                   field, camelCaseNames[i], messageClass, builderClass,
2065                   containingOneofCamelCaseName);
2066             }
2067           }
2068         }
2069 
2070         int oneofsSize = oneofs.length;
2071         for (int i = 0; i < oneofsSize; i++) {
2072           oneofs[i] =
2073               new OneofAccessor(
2074                   descriptor, i, camelCaseNames[i + fieldsSize], messageClass, builderClass);
2075         }
2076         initialized = true;
2077         camelCaseNames = null;
2078         return this;
2079       }
2080     }
2081 
2082     private final Descriptor descriptor;
2083     private final FieldAccessor[] fields;
2084     private String[] camelCaseNames;
2085     private final OneofAccessor[] oneofs;
2086     private volatile boolean initialized;
2087 
2088     /** Get the FieldAccessor for a particular field. */
2089     private FieldAccessor getField(final FieldDescriptor field) {
2090       if (field.getContainingType() != descriptor) {
2091         throw new IllegalArgumentException(
2092           "FieldDescriptor does not match message type.");
2093       } else if (field.isExtension()) {
2094         // If this type had extensions, it would subclass ExtendableMessage,
2095         // which overrides the reflection interface to handle extensions.
2096         throw new IllegalArgumentException(
2097           "This type does not have extensions.");
2098       }
2099       return fields[field.getIndex()];
2100     }
2101 
2102     /** Get the OneofAccessor for a particular oneof. */
2103     private OneofAccessor getOneof(final OneofDescriptor oneof) {
2104       if (oneof.getContainingType() != descriptor) {
2105         throw new IllegalArgumentException(
2106           "OneofDescriptor does not match message type.");
2107       }
2108       return oneofs[oneof.getIndex()];
2109     }
2110 
2111     /**
2112      * Abstract interface that provides access to a single field.  This is
2113      * implemented differently depending on the field type and cardinality.
2114      */
2115     private interface FieldAccessor {
2116       Object get(GeneratedMessageV3 message);
2117       Object get(GeneratedMessageV3.Builder builder);
2118       Object getRaw(GeneratedMessageV3 message);
2119       Object getRaw(GeneratedMessageV3.Builder builder);
2120       void set(Builder builder, Object value);
2121       Object getRepeated(GeneratedMessageV3 message, int index);
2122       Object getRepeated(GeneratedMessageV3.Builder builder, int index);
2123       Object getRepeatedRaw(GeneratedMessageV3 message, int index);
2124       Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index);
2125       void setRepeated(Builder builder,
2126                        int index, Object value);
2127       void addRepeated(Builder builder, Object value);
2128       boolean has(GeneratedMessageV3 message);
2129       boolean has(GeneratedMessageV3.Builder builder);
2130       int getRepeatedCount(GeneratedMessageV3 message);
2131       int getRepeatedCount(GeneratedMessageV3.Builder builder);
2132       void clear(Builder builder);
2133       Message.Builder newBuilder();
2134       Message.Builder getBuilder(GeneratedMessageV3.Builder builder);
2135       Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder,
2136                                          int index);
2137     }
2138 
2139     /** OneofAccessor provides access to a single oneof. */
2140     private static class OneofAccessor {
2141       OneofAccessor(
2142           final Descriptor descriptor,
2143           final int oneofIndex,
2144           final String camelCaseName,
2145           final Class<? extends GeneratedMessageV3> messageClass,
2146           final Class<? extends Builder> builderClass) {
2147         this.descriptor = descriptor;
2148         OneofDescriptor oneofDescriptor = descriptor.getOneofs().get(oneofIndex);
2149         if (oneofDescriptor.isSynthetic()) {
2150           caseMethod = null;
2151           caseMethodBuilder = null;
2152           fieldDescriptor = oneofDescriptor.getFields().get(0);
2153         } else {
2154           caseMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Case");
2155           caseMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Case");
2156           fieldDescriptor = null;
2157         }
2158         clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
2159       }
2160 
2161       private final Descriptor descriptor;
2162       private final Method caseMethod;
2163       private final Method caseMethodBuilder;
2164       private final Method clearMethod;
2165       private final FieldDescriptor fieldDescriptor;
2166 
2167       public boolean has(final GeneratedMessageV3 message) {
2168         if (fieldDescriptor != null) {
2169           return message.hasField(fieldDescriptor);
2170         } else {
2171           if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) {
2172             return false;
2173           }
2174         }
2175         return true;
2176       }
2177 
2178       public boolean has(GeneratedMessageV3.Builder builder) {
2179         if (fieldDescriptor != null) {
2180           return builder.hasField(fieldDescriptor);
2181         } else {
2182           if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) {
2183             return false;
2184           }
2185         }
2186         return true;
2187       }
2188 
2189       public FieldDescriptor get(final GeneratedMessageV3 message) {
2190         if (fieldDescriptor != null) {
2191           return message.hasField(fieldDescriptor) ? fieldDescriptor : null;
2192         } else {
2193           int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
2194           if (fieldNumber > 0) {
2195             return descriptor.findFieldByNumber(fieldNumber);
2196           }
2197         }
2198         return null;
2199       }
2200 
2201       public FieldDescriptor get(GeneratedMessageV3.Builder builder) {
2202         if (fieldDescriptor != null) {
2203           return builder.hasField(fieldDescriptor) ? fieldDescriptor : null;
2204         } else {
2205           int fieldNumber =
2206               ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
2207           if (fieldNumber > 0) {
2208             return descriptor.findFieldByNumber(fieldNumber);
2209           }
2210         }
2211         return null;
2212       }
2213 
2214       public void clear(final Builder builder) {
2215         invokeOrDie(clearMethod, builder);
2216       }
2217     }
2218 
2219     // ---------------------------------------------------------------
2220 
2221     private static class SingularFieldAccessor implements FieldAccessor {
2222       private interface MethodInvoker {
2223         Object get(final GeneratedMessageV3 message);
2224 
2225         Object get(GeneratedMessageV3.Builder<?> builder);
2226 
2227         int getOneofFieldNumber(final GeneratedMessageV3 message);
2228 
2229         int getOneofFieldNumber(final GeneratedMessageV3.Builder<?> builder);
2230 
2231         void set(final GeneratedMessageV3.Builder<?> builder, final Object value);
2232 
2233         boolean has(final GeneratedMessageV3 message);
2234 
2235         boolean has(GeneratedMessageV3.Builder<?> builder);
2236 
2237         void clear(final GeneratedMessageV3.Builder<?> builder);
2238       }
2239 
2240       private static final class ReflectionInvoker implements MethodInvoker {
2241         protected final Method getMethod;
2242         protected final Method getMethodBuilder;
2243         protected final Method setMethod;
2244         protected final Method hasMethod;
2245         protected final Method hasMethodBuilder;
2246         protected final Method clearMethod;
2247         protected final Method caseMethod;
2248         protected final Method caseMethodBuilder;
2249 
2250         ReflectionInvoker(
2251             final FieldDescriptor descriptor,
2252             final String camelCaseName,
2253             final Class<? extends GeneratedMessageV3> messageClass,
2254             final Class<? extends Builder> builderClass,
2255             final String containingOneofCamelCaseName,
2256             boolean isOneofField,
2257             boolean hasHasMethod) {
2258           getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
2259           getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName);
2260           Class<?> type = getMethod.getReturnType();
2261           setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
2262           hasMethod = hasHasMethod ? getMethodOrDie(messageClass, "has" + camelCaseName) : null;
2263           hasMethodBuilder =
2264               hasHasMethod ? getMethodOrDie(builderClass, "has" + camelCaseName) : null;
2265           clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
2266           caseMethod =
2267               isOneofField
2268                   ? getMethodOrDie(messageClass, "get" + containingOneofCamelCaseName + "Case")
2269                   : null;
2270           caseMethodBuilder =
2271               isOneofField
2272                   ? getMethodOrDie(builderClass, "get" + containingOneofCamelCaseName + "Case")
2273                   : null;
2274         }
2275 
2276         @Override
2277         public Object get(final GeneratedMessageV3 message) {
2278           return invokeOrDie(getMethod, message);
2279         }
2280 
2281         @Override
2282         public Object get(GeneratedMessageV3.Builder<?> builder) {
2283           return invokeOrDie(getMethodBuilder, builder);
2284         }
2285 
2286         @Override
2287         public int getOneofFieldNumber(final GeneratedMessageV3 message) {
2288           return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
2289         }
2290 
2291         @Override
2292         public int getOneofFieldNumber(final GeneratedMessageV3.Builder<?> builder) {
2293           return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
2294         }
2295 
2296         @Override
2297         public void set(final GeneratedMessageV3.Builder<?> builder, final Object value) {
2298           invokeOrDie(setMethod, builder, value);
2299         }
2300 
2301         @Override
2302         public boolean has(final GeneratedMessageV3 message) {
2303           return (Boolean) invokeOrDie(hasMethod, message);
2304         }
2305 
2306         @Override
2307         public boolean has(GeneratedMessageV3.Builder<?> builder) {
2308           return (Boolean) invokeOrDie(hasMethodBuilder, builder);
2309         }
2310 
2311         @Override
2312         public void clear(final GeneratedMessageV3.Builder<?> builder) {
2313           invokeOrDie(clearMethod, builder);
2314         }
2315       }
2316 
2317       SingularFieldAccessor(
2318           final FieldDescriptor descriptor,
2319           final String camelCaseName,
2320           final Class<? extends GeneratedMessageV3> messageClass,
2321           final Class<? extends Builder> builderClass,
2322           final String containingOneofCamelCaseName) {
2323         isOneofField =
2324             descriptor.getContainingOneof() != null
2325                 && !descriptor.getContainingOneof().isSynthetic();
2326         hasHasMethod =
2327             descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO2
2328                 || descriptor.hasOptionalKeyword()
2329                 || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE);
2330         ReflectionInvoker reflectionInvoker =
2331             new ReflectionInvoker(
2332                 descriptor,
2333                 camelCaseName,
2334                 messageClass,
2335                 builderClass,
2336                 containingOneofCamelCaseName,
2337                 isOneofField,
2338                 hasHasMethod);
2339         field = descriptor;
2340         type = reflectionInvoker.getMethod.getReturnType();
2341         invoker = getMethodInvoker(reflectionInvoker);
2342       }
2343 
2344       static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) {
2345         return accessor;
2346       }
2347 
2348       // Note:  We use Java reflection to call public methods rather than
2349       //   access private fields directly as this avoids runtime security
2350       //   checks.
2351       protected final Class<?> type;
2352       protected final FieldDescriptor field;
2353       protected final boolean isOneofField;
2354       protected final boolean hasHasMethod;
2355       protected final MethodInvoker invoker;
2356 
2357       @Override
2358       public Object get(final GeneratedMessageV3 message) {
2359         return invoker.get(message);
2360       }
2361       @Override
2362       public Object get(GeneratedMessageV3.Builder builder) {
2363         return invoker.get(builder);
2364       }
2365       @Override
2366       public Object getRaw(final GeneratedMessageV3 message) {
2367         return get(message);
2368       }
2369       @Override
2370       public Object getRaw(GeneratedMessageV3.Builder builder) {
2371         return get(builder);
2372       }
2373       @Override
2374       public void set(final Builder builder, final Object value) {
2375         invoker.set(builder, value);
2376       }
2377       @Override
2378       public Object getRepeated(final GeneratedMessageV3 message, final int index) {
2379         throw new UnsupportedOperationException("getRepeatedField() called on a singular field.");
2380       }
2381       @Override
2382       public Object getRepeatedRaw(final GeneratedMessageV3 message, final int index) {
2383         throw new UnsupportedOperationException(
2384             "getRepeatedFieldRaw() called on a singular field.");
2385       }
2386       @Override
2387       public Object getRepeated(GeneratedMessageV3.Builder builder, int index) {
2388         throw new UnsupportedOperationException("getRepeatedField() called on a singular field.");
2389       }
2390       @Override
2391       public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) {
2392         throw new UnsupportedOperationException(
2393             "getRepeatedFieldRaw() called on a singular field.");
2394       }
2395       @Override
2396       public void setRepeated(final Builder builder, final int index, final Object value) {
2397         throw new UnsupportedOperationException("setRepeatedField() called on a singular field.");
2398       }
2399       @Override
2400       public void addRepeated(final Builder builder, final Object value) {
2401         throw new UnsupportedOperationException("addRepeatedField() called on a singular field.");
2402       }
2403       @Override
2404       public boolean has(final GeneratedMessageV3 message) {
2405         if (!hasHasMethod) {
2406           if (isOneofField) {
2407             return invoker.getOneofFieldNumber(message) == field.getNumber();
2408           }
2409           return !get(message).equals(field.getDefaultValue());
2410         }
2411         return invoker.has(message);
2412       }
2413       @Override
2414       public boolean has(GeneratedMessageV3.Builder builder) {
2415         if (!hasHasMethod) {
2416           if (isOneofField) {
2417             return invoker.getOneofFieldNumber(builder) == field.getNumber();
2418           }
2419           return !get(builder).equals(field.getDefaultValue());
2420         }
2421         return invoker.has(builder);
2422       }
2423       @Override
2424       public int getRepeatedCount(final GeneratedMessageV3 message) {
2425         throw new UnsupportedOperationException(
2426             "getRepeatedFieldSize() called on a singular field.");
2427       }
2428       @Override
2429       public int getRepeatedCount(GeneratedMessageV3.Builder builder) {
2430         throw new UnsupportedOperationException(
2431             "getRepeatedFieldSize() called on a singular field.");
2432       }
2433       @Override
2434       public void clear(final Builder builder) {
2435         invoker.clear(builder);
2436       }
2437       @Override
2438       public Message.Builder newBuilder() {
2439         throw new UnsupportedOperationException(
2440             "newBuilderForField() called on a non-Message type.");
2441       }
2442       @Override
2443       public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
2444         throw new UnsupportedOperationException("getFieldBuilder() called on a non-Message type.");
2445       }
2446       @Override
2447       public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) {
2448         throw new UnsupportedOperationException(
2449             "getRepeatedFieldBuilder() called on a non-Message type.");
2450       }
2451     }
2452 
2453     private static class RepeatedFieldAccessor implements FieldAccessor {
2454       interface MethodInvoker {
2455         public Object get(final GeneratedMessageV3 message);
2456 
2457         public Object get(GeneratedMessageV3.Builder<?> builder);
2458 
2459         Object getRepeated(final GeneratedMessageV3 message, final int index);
2460 
2461         Object getRepeated(GeneratedMessageV3.Builder<?> builder, int index);
2462 
2463         void setRepeated(
2464             final GeneratedMessageV3.Builder<?> builder, final int index, final Object value);
2465 
2466         void addRepeated(final GeneratedMessageV3.Builder<?> builder, final Object value);
2467 
2468         int getRepeatedCount(final GeneratedMessageV3 message);
2469 
2470         int getRepeatedCount(GeneratedMessageV3.Builder<?> builder);
2471 
2472         void clear(final GeneratedMessageV3.Builder<?> builder);
2473       }
2474 
2475       private static final class ReflectionInvoker implements MethodInvoker {
2476         protected final Method getMethod;
2477         protected final Method getMethodBuilder;
2478         protected final Method getRepeatedMethod;
2479         protected final Method getRepeatedMethodBuilder;
2480         protected final Method setRepeatedMethod;
2481         protected final Method addRepeatedMethod;
2482         protected final Method getCountMethod;
2483         protected final Method getCountMethodBuilder;
2484         protected final Method clearMethod;
2485 
2486         ReflectionInvoker(
2487             final FieldDescriptor descriptor,
2488             final String camelCaseName,
2489             final Class<? extends GeneratedMessageV3> messageClass,
2490             final Class<? extends Builder> builderClass) {
2491           getMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "List");
2492           getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "List");
2493           getRepeatedMethod = getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
2494           getRepeatedMethodBuilder =
2495               getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
2496           Class<?> type = getRepeatedMethod.getReturnType();
2497           setRepeatedMethod =
2498               getMethodOrDie(builderClass, "set" + camelCaseName, Integer.TYPE, type);
2499           addRepeatedMethod = getMethodOrDie(builderClass, "add" + camelCaseName, type);
2500           getCountMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
2501           getCountMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
2502           clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
2503         }
2504 
2505         @Override
2506         public Object get(final GeneratedMessageV3 message) {
2507           return invokeOrDie(getMethod, message);
2508         }
2509 
2510         @Override
2511         public Object get(GeneratedMessageV3.Builder<?> builder) {
2512           return invokeOrDie(getMethodBuilder, builder);
2513         }
2514 
2515         @Override
2516         public Object getRepeated(
2517             final GeneratedMessageV3 message, final int index) {
2518           return invokeOrDie(getRepeatedMethod, message, index);
2519         }
2520 
2521         @Override
2522         public Object getRepeated(GeneratedMessageV3.Builder<?> builder, int index) {
2523           return invokeOrDie(getRepeatedMethodBuilder, builder, index);
2524         }
2525 
2526         @Override
2527         public void setRepeated(
2528             final GeneratedMessageV3.Builder<?> builder, final int index, final Object value) {
2529           invokeOrDie(setRepeatedMethod, builder, index, value);
2530         }
2531 
2532         @Override
2533         public void addRepeated(
2534             final GeneratedMessageV3.Builder<?> builder, final Object value) {
2535           invokeOrDie(addRepeatedMethod, builder, value);
2536         }
2537 
2538         @Override
2539         public int getRepeatedCount(final GeneratedMessageV3 message) {
2540           return (Integer) invokeOrDie(getCountMethod, message);
2541         }
2542 
2543         @Override
2544         public int getRepeatedCount(GeneratedMessageV3.Builder<?> builder) {
2545           return (Integer) invokeOrDie(getCountMethodBuilder, builder);
2546         }
2547 
2548         @Override
2549         public void clear(final GeneratedMessageV3.Builder<?> builder) {
2550           invokeOrDie(clearMethod, builder);
2551         }
2552       }
2553 
2554       protected final Class type;
2555       protected final MethodInvoker invoker;
2556 
2557       RepeatedFieldAccessor(
2558           final FieldDescriptor descriptor, final String camelCaseName,
2559           final Class<? extends GeneratedMessageV3> messageClass,
2560           final Class<? extends Builder> builderClass) {
2561         ReflectionInvoker reflectionInvoker =
2562             new ReflectionInvoker(descriptor, camelCaseName, messageClass, builderClass);
2563         type = reflectionInvoker.getRepeatedMethod.getReturnType();
2564         invoker = getMethodInvoker(reflectionInvoker);
2565       }
2566 
2567       static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) {
2568         return accessor;
2569       }
2570 
2571       @Override
2572       public Object get(final GeneratedMessageV3 message) {
2573         return invoker.get(message);
2574       }
2575       @Override
2576       public Object get(GeneratedMessageV3.Builder builder) {
2577         return invoker.get(builder);
2578       }
2579       @Override
2580       public Object getRaw(final GeneratedMessageV3 message) {
2581         return get(message);
2582       }
2583       @Override
2584       public Object getRaw(GeneratedMessageV3.Builder builder) {
2585         return get(builder);
2586       }
2587       @Override
2588       public void set(final Builder builder, final Object value) {
2589         // Add all the elements individually.  This serves two purposes:
2590         // 1) Verifies that each element has the correct type.
2591         // 2) Insures that the caller cannot modify the list later on and
2592         //    have the modifications be reflected in the message.
2593         clear(builder);
2594         for (final Object element : (List<?>) value) {
2595           addRepeated(builder, element);
2596         }
2597       }
2598       @Override
2599       public Object getRepeated(final GeneratedMessageV3 message, final int index) {
2600         return invoker.getRepeated(message, index);
2601       }
2602       @Override
2603       public Object getRepeated(GeneratedMessageV3.Builder builder, int index) {
2604         return invoker.getRepeated(builder, index);
2605       }
2606       @Override
2607       public Object getRepeatedRaw(GeneratedMessageV3 message, int index) {
2608         return getRepeated(message, index);
2609       }
2610       @Override
2611       public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) {
2612         return getRepeated(builder, index);
2613       }
2614       @Override
2615       public void setRepeated(final Builder builder, final int index, final Object value) {
2616         invoker.setRepeated(builder, index, value);
2617       }
2618       @Override
2619       public void addRepeated(final Builder builder, final Object value) {
2620         invoker.addRepeated(builder, value);
2621       }
2622       @Override
2623       public boolean has(final GeneratedMessageV3 message) {
2624         throw new UnsupportedOperationException("hasField() called on a repeated field.");
2625       }
2626       @Override
2627       public boolean has(GeneratedMessageV3.Builder builder) {
2628         throw new UnsupportedOperationException("hasField() called on a repeated field.");
2629       }
2630       @Override
2631       public int getRepeatedCount(final GeneratedMessageV3 message) {
2632         return invoker.getRepeatedCount(message);
2633       }
2634       @Override
2635       public int getRepeatedCount(GeneratedMessageV3.Builder builder) {
2636         return invoker.getRepeatedCount(builder);
2637       }
2638       @Override
2639       public void clear(final Builder builder) {
2640         invoker.clear(builder);
2641       }
2642       @Override
2643       public Message.Builder newBuilder() {
2644         throw new UnsupportedOperationException(
2645             "newBuilderForField() called on a non-Message type.");
2646       }
2647       @Override
2648       public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
2649         throw new UnsupportedOperationException("getFieldBuilder() called on a non-Message type.");
2650       }
2651       @Override
2652       public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) {
2653         throw new UnsupportedOperationException(
2654             "getRepeatedFieldBuilder() called on a non-Message type.");
2655       }
2656     }
2657 
2658     private static class MapFieldAccessor implements FieldAccessor {
2659       MapFieldAccessor(
2660           final FieldDescriptor descriptor, final String camelCaseName,
2661           final Class<? extends GeneratedMessageV3> messageClass,
2662           final Class<? extends Builder> builderClass) {
2663         field = descriptor;
2664         Method getDefaultInstanceMethod =
2665             getMethodOrDie(messageClass, "getDefaultInstance");
2666         MapField defaultMapField = getMapField(
2667             (GeneratedMessageV3) invokeOrDie(getDefaultInstanceMethod, null));
2668         mapEntryMessageDefaultInstance =
2669             defaultMapField.getMapEntryMessageDefaultInstance();
2670       }
2671 
2672       private final FieldDescriptor field;
2673       private final Message mapEntryMessageDefaultInstance;
2674 
2675       private MapField<?, ?> getMapField(GeneratedMessageV3 message) {
2676         return (MapField<?, ?>) message.internalGetMapField(field.getNumber());
2677       }
2678 
2679       private MapField<?, ?> getMapField(GeneratedMessageV3.Builder builder) {
2680         return (MapField<?, ?>) builder.internalGetMapField(field.getNumber());
2681       }
2682 
2683       private MapField<?, ?> getMutableMapField(
2684           GeneratedMessageV3.Builder builder) {
2685         return (MapField<?, ?>) builder.internalGetMutableMapField(
2686             field.getNumber());
2687       }
2688 
2689       private Message coerceType(Message value) {
2690         if (value == null) {
2691           return null;
2692         }
2693         if (mapEntryMessageDefaultInstance.getClass().isInstance(value)) {
2694           return value;
2695         }
2696         // The value is not the exact right message type.  However, if it
2697         // is an alternative implementation of the same type -- e.g. a
2698         // DynamicMessage -- we should accept it.  In this case we can make
2699         // a copy of the message.
2700         return mapEntryMessageDefaultInstance.toBuilder().mergeFrom(value).build();
2701       }
2702 
2703       @Override
2704       @SuppressWarnings("unchecked")
2705       public Object get(GeneratedMessageV3 message) {
2706         List result = new ArrayList<>();
2707         for (int i = 0; i < getRepeatedCount(message); i++) {
2708           result.add(getRepeated(message, i));
2709         }
2710         return Collections.unmodifiableList(result);
2711       }
2712 
2713       @Override
2714       @SuppressWarnings("unchecked")
2715       public Object get(Builder builder) {
2716         List result = new ArrayList<>();
2717         for (int i = 0; i < getRepeatedCount(builder); i++) {
2718           result.add(getRepeated(builder, i));
2719         }
2720         return Collections.unmodifiableList(result);
2721       }
2722 
2723       @Override
2724       public Object getRaw(GeneratedMessageV3 message) {
2725         return get(message);
2726       }
2727 
2728       @Override
2729       public Object getRaw(GeneratedMessageV3.Builder builder) {
2730         return get(builder);
2731       }
2732 
2733       @Override
2734       public void set(Builder builder, Object value) {
2735         clear(builder);
2736         for (Object entry : (List) value) {
2737           addRepeated(builder, entry);
2738         }
2739       }
2740 
2741       @Override
2742       public Object getRepeated(GeneratedMessageV3 message, int index) {
2743         return getMapField(message).getList().get(index);
2744       }
2745 
2746       @Override
2747       public Object getRepeated(Builder builder, int index) {
2748         return getMapField(builder).getList().get(index);
2749       }
2750 
2751       @Override
2752       public Object getRepeatedRaw(GeneratedMessageV3 message, int index) {
2753         return getRepeated(message, index);
2754       }
2755 
2756       @Override
2757       public Object getRepeatedRaw(Builder builder, int index) {
2758         return getRepeated(builder, index);
2759       }
2760 
2761       @Override
2762       public void setRepeated(Builder builder, int index, Object value) {
2763         getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value));
2764       }
2765 
2766       @Override
2767       public void addRepeated(Builder builder, Object value) {
2768         getMutableMapField(builder).getMutableList().add(coerceType((Message) value));
2769       }
2770 
2771       @Override
2772       public boolean has(GeneratedMessageV3 message) {
2773         throw new UnsupportedOperationException(
2774             "hasField() is not supported for repeated fields.");
2775       }
2776 
2777       @Override
2778       public boolean has(Builder builder) {
2779         throw new UnsupportedOperationException(
2780             "hasField() is not supported for repeated fields.");
2781       }
2782 
2783       @Override
2784       public int getRepeatedCount(GeneratedMessageV3 message) {
2785         return getMapField(message).getList().size();
2786       }
2787 
2788       @Override
2789       public int getRepeatedCount(Builder builder) {
2790         return getMapField(builder).getList().size();
2791       }
2792 
2793       @Override
2794       public void clear(Builder builder) {
2795         getMutableMapField(builder).getMutableList().clear();
2796       }
2797 
2798       @Override
2799       public com.google.protobuf.Message.Builder newBuilder() {
2800         return mapEntryMessageDefaultInstance.newBuilderForType();
2801       }
2802 
2803       @Override
2804       public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
2805         throw new UnsupportedOperationException(
2806             "Nested builder not supported for map fields.");
2807       }
2808 
2809       @Override
2810       public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) {
2811         throw new UnsupportedOperationException(
2812             "Nested builder not supported for map fields.");
2813       }
2814     }
2815 
2816     // ---------------------------------------------------------------
2817 
2818     private static final class SingularEnumFieldAccessor
2819         extends SingularFieldAccessor {
2820       SingularEnumFieldAccessor(
2821           final FieldDescriptor descriptor, final String camelCaseName,
2822           final Class<? extends GeneratedMessageV3> messageClass,
2823           final Class<? extends Builder> builderClass,
2824           final String containingOneofCamelCaseName) {
2825         super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName);
2826 
2827         enumDescriptor = descriptor.getEnumType();
2828 
2829         valueOfMethod = getMethodOrDie(type, "valueOf", EnumValueDescriptor.class);
2830         getValueDescriptorMethod = getMethodOrDie(type, "getValueDescriptor");
2831 
2832         supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue();
2833         if (supportUnknownEnumValue) {
2834           getValueMethod =
2835               getMethodOrDie(messageClass, "get" + camelCaseName + "Value");
2836           getValueMethodBuilder =
2837               getMethodOrDie(builderClass, "get" + camelCaseName + "Value");
2838           setValueMethod =
2839               getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class);
2840         }
2841       }
2842 
2843       private EnumDescriptor enumDescriptor;
2844 
2845       private Method valueOfMethod;
2846       private Method getValueDescriptorMethod;
2847 
2848       private boolean supportUnknownEnumValue;
2849       private Method getValueMethod;
2850       private Method getValueMethodBuilder;
2851       private Method setValueMethod;
2852 
2853       @Override
2854       public Object get(final GeneratedMessageV3 message) {
2855         if (supportUnknownEnumValue) {
2856           int value = (Integer) invokeOrDie(getValueMethod, message);
2857           return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
2858         }
2859         return invokeOrDie(getValueDescriptorMethod, super.get(message));
2860       }
2861 
2862       @Override
2863       public Object get(final GeneratedMessageV3.Builder builder) {
2864         if (supportUnknownEnumValue) {
2865           int value = (Integer) invokeOrDie(getValueMethodBuilder, builder);
2866           return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
2867         }
2868         return invokeOrDie(getValueDescriptorMethod, super.get(builder));
2869       }
2870 
2871       @Override
2872       public void set(final Builder builder, final Object value) {
2873         if (supportUnknownEnumValue) {
2874           invokeOrDie(setValueMethod, builder,
2875               ((EnumValueDescriptor) value).getNumber());
2876           return;
2877         }
2878         super.set(builder, invokeOrDie(valueOfMethod, null, value));
2879       }
2880     }
2881 
2882     private static final class RepeatedEnumFieldAccessor
2883         extends RepeatedFieldAccessor {
2884       RepeatedEnumFieldAccessor(
2885           final FieldDescriptor descriptor, final String camelCaseName,
2886           final Class<? extends GeneratedMessageV3> messageClass,
2887           final Class<? extends Builder> builderClass) {
2888         super(descriptor, camelCaseName, messageClass, builderClass);
2889 
2890         enumDescriptor = descriptor.getEnumType();
2891 
2892         valueOfMethod = getMethodOrDie(type, "valueOf", EnumValueDescriptor.class);
2893         getValueDescriptorMethod = getMethodOrDie(type, "getValueDescriptor");
2894 
2895         supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue();
2896         if (supportUnknownEnumValue) {
2897           getRepeatedValueMethod =
2898               getMethodOrDie(messageClass, "get" + camelCaseName + "Value", int.class);
2899           getRepeatedValueMethodBuilder =
2900               getMethodOrDie(builderClass, "get" + camelCaseName + "Value", int.class);
2901           setRepeatedValueMethod =
2902               getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class, int.class);
2903           addRepeatedValueMethod =
2904               getMethodOrDie(builderClass, "add" + camelCaseName + "Value", int.class);
2905         }
2906       }
2907       private EnumDescriptor enumDescriptor;
2908 
2909       private final Method valueOfMethod;
2910       private final Method getValueDescriptorMethod;
2911 
2912       private boolean supportUnknownEnumValue;
2913       private Method getRepeatedValueMethod;
2914       private Method getRepeatedValueMethodBuilder;
2915       private Method setRepeatedValueMethod;
2916       private Method addRepeatedValueMethod;
2917 
2918       @Override
2919       @SuppressWarnings("unchecked")
2920       public Object get(final GeneratedMessageV3 message) {
2921         final List newList = new ArrayList<>();
2922         final int size = getRepeatedCount(message);
2923         for (int i = 0; i < size; i++) {
2924           newList.add(getRepeated(message, i));
2925         }
2926         return Collections.unmodifiableList(newList);
2927       }
2928 
2929       @Override
2930       @SuppressWarnings("unchecked")
2931       public Object get(final GeneratedMessageV3.Builder builder) {
2932         final List newList = new ArrayList<>();
2933         final int size = getRepeatedCount(builder);
2934         for (int i = 0; i < size; i++) {
2935           newList.add(getRepeated(builder, i));
2936         }
2937         return Collections.unmodifiableList(newList);
2938       }
2939 
2940       @Override
2941       public Object getRepeated(final GeneratedMessageV3 message, final int index) {
2942         if (supportUnknownEnumValue) {
2943           int value = (Integer) invokeOrDie(getRepeatedValueMethod, message, index);
2944           return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
2945         }
2946         return invokeOrDie(getValueDescriptorMethod, super.getRepeated(message, index));
2947       }
2948 
2949       @Override
2950       public Object getRepeated(final GeneratedMessageV3.Builder builder, final int index) {
2951         if (supportUnknownEnumValue) {
2952           int value = (Integer) invokeOrDie(getRepeatedValueMethodBuilder, builder, index);
2953           return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
2954         }
2955         return invokeOrDie(getValueDescriptorMethod, super.getRepeated(builder, index));
2956       }
2957 
2958       @Override
2959       public void setRepeated(final Builder builder, final int index, final Object value) {
2960         if (supportUnknownEnumValue) {
2961           invokeOrDie(setRepeatedValueMethod, builder, index,
2962               ((EnumValueDescriptor) value).getNumber());
2963           return;
2964         }
2965         super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, value));
2966       }
2967       @Override
2968       public void addRepeated(final Builder builder, final Object value) {
2969         if (supportUnknownEnumValue) {
2970           invokeOrDie(addRepeatedValueMethod, builder,
2971               ((EnumValueDescriptor) value).getNumber());
2972           return;
2973         }
2974         super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
2975       }
2976     }
2977 
2978     // ---------------------------------------------------------------
2979 
2980     /**
2981      * Field accessor for string fields.
2982      *
2983      * <p>This class makes getFooBytes() and setFooBytes() available for
2984      * reflection API so that reflection based serialize/parse functions can
2985      * access the raw bytes of the field to preserve non-UTF8 bytes in the
2986      * string.
2987      *
2988      * <p>This ensures the serialize/parse round-trip safety, which is important
2989      * for servers which forward messages.
2990      */
2991     private static final class SingularStringFieldAccessor
2992         extends SingularFieldAccessor {
2993       SingularStringFieldAccessor(
2994           final FieldDescriptor descriptor, final String camelCaseName,
2995           final Class<? extends GeneratedMessageV3> messageClass,
2996           final Class<? extends Builder> builderClass,
2997           final String containingOneofCamelCaseName) {
2998         super(descriptor, camelCaseName, messageClass, builderClass,
2999             containingOneofCamelCaseName);
3000         getBytesMethod = getMethodOrDie(messageClass,
3001             "get" + camelCaseName + "Bytes");
3002         getBytesMethodBuilder = getMethodOrDie(builderClass,
3003             "get" + camelCaseName + "Bytes");
3004         setBytesMethodBuilder = getMethodOrDie(builderClass,
3005             "set" + camelCaseName + "Bytes", ByteString.class);
3006       }
3007 
3008       private final Method getBytesMethod;
3009       private final Method getBytesMethodBuilder;
3010       private final Method setBytesMethodBuilder;
3011 
3012       @Override
3013       public Object getRaw(final GeneratedMessageV3 message) {
3014         return invokeOrDie(getBytesMethod, message);
3015       }
3016 
3017       @Override
3018       public Object getRaw(GeneratedMessageV3.Builder builder) {
3019         return invokeOrDie(getBytesMethodBuilder, builder);
3020       }
3021 
3022       @Override
3023       public void set(GeneratedMessageV3.Builder builder, Object value) {
3024         if (value instanceof ByteString) {
3025           invokeOrDie(setBytesMethodBuilder, builder, value);
3026         } else {
3027           super.set(builder, value);
3028         }
3029       }
3030     }
3031 
3032     // ---------------------------------------------------------------
3033 
3034     private static final class SingularMessageFieldAccessor
3035         extends SingularFieldAccessor {
3036       SingularMessageFieldAccessor(
3037           final FieldDescriptor descriptor, final String camelCaseName,
3038           final Class<? extends GeneratedMessageV3> messageClass,
3039           final Class<? extends Builder> builderClass,
3040           final String containingOneofCamelCaseName) {
3041         super(descriptor, camelCaseName, messageClass, builderClass,
3042             containingOneofCamelCaseName);
3043 
3044         newBuilderMethod = getMethodOrDie(type, "newBuilder");
3045         getBuilderMethodBuilder =
3046             getMethodOrDie(builderClass, "get" + camelCaseName + "Builder");
3047       }
3048 
3049       private final Method newBuilderMethod;
3050       private final Method getBuilderMethodBuilder;
3051 
3052       private Object coerceType(final Object value) {
3053         if (type.isInstance(value)) {
3054           return value;
3055         } else {
3056           // The value is not the exact right message type.  However, if it
3057           // is an alternative implementation of the same type -- e.g. a
3058           // DynamicMessage -- we should accept it.  In this case we can make
3059           // a copy of the message.
3060           return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
3061               .mergeFrom((Message) value)
3062               .buildPartial();
3063         }
3064       }
3065 
3066       @Override
3067       public void set(final Builder builder, final Object value) {
3068         super.set(builder, coerceType(value));
3069       }
3070       @Override
3071       public Message.Builder newBuilder() {
3072         return (Message.Builder) invokeOrDie(newBuilderMethod, null);
3073       }
3074       @Override
3075       public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
3076         return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder);
3077       }
3078     }
3079 
3080     private static final class RepeatedMessageFieldAccessor
3081         extends RepeatedFieldAccessor {
3082       RepeatedMessageFieldAccessor(
3083           final FieldDescriptor descriptor, final String camelCaseName,
3084           final Class<? extends GeneratedMessageV3> messageClass,
3085           final Class<? extends Builder> builderClass) {
3086         super(descriptor, camelCaseName, messageClass, builderClass);
3087 
3088         newBuilderMethod = getMethodOrDie(type, "newBuilder");
3089         getBuilderMethodBuilder = getMethodOrDie(builderClass,
3090             "get" + camelCaseName + "Builder", Integer.TYPE);
3091       }
3092 
3093       private final Method newBuilderMethod;
3094       private final Method getBuilderMethodBuilder;
3095 
3096       private Object coerceType(final Object value) {
3097         if (type.isInstance(value)) {
3098           return value;
3099         } else {
3100           // The value is not the exact right message type.  However, if it
3101           // is an alternative implementation of the same type -- e.g. a
3102           // DynamicMessage -- we should accept it.  In this case we can make
3103           // a copy of the message.
3104           return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
3105               .mergeFrom((Message) value)
3106               .build();
3107         }
3108       }
3109 
3110       @Override
3111       public void setRepeated(final Builder builder, final int index, final Object value) {
3112         super.setRepeated(builder, index, coerceType(value));
3113       }
3114       @Override
3115       public void addRepeated(final Builder builder, final Object value) {
3116         super.addRepeated(builder, coerceType(value));
3117       }
3118       @Override
3119       public Message.Builder newBuilder() {
3120         return (Message.Builder) invokeOrDie(newBuilderMethod, null);
3121       }
3122       @Override
3123       public Message.Builder getRepeatedBuilder(
3124           final GeneratedMessageV3.Builder builder, final int index) {
3125         return (Message.Builder) invokeOrDie(
3126             getBuilderMethodBuilder, builder, index);
3127       }
3128     }
3129   }
3130 
3131   /**
3132    * Replaces this object in the output stream with a serialized form.
3133    * Part of Java's serialization magic.  Generated sub-classes must override
3134    * this method by calling {@code return super.writeReplace();}
3135    * @return a SerializedForm of this message
3136    */
3137   protected Object writeReplace() throws ObjectStreamException {
3138     return new GeneratedMessageLite.SerializedForm(this);
3139   }
3140 
3141   /**
3142    * Checks that the {@link Extension} is non-Lite and returns it as a {@link GeneratedExtension}.
3143    */
3144   private static <MessageType extends ExtendableMessage<MessageType>, T>
3145       Extension<MessageType, T> checkNotLite(ExtensionLite<MessageType, T> extension) {
3146     if (extension.isLite()) {
3147       throw new IllegalArgumentException("Expected non-lite extension.");
3148     }
3149 
3150     return (Extension<MessageType, T>) extension;
3151   }
3152 
3153   protected static int computeStringSize(final int fieldNumber, final Object value) {
3154     if (value instanceof String) {
3155       return CodedOutputStream.computeStringSize(fieldNumber, (String) value);
3156     } else {
3157       return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value);
3158     }
3159   }
3160 
3161   protected static int computeStringSizeNoTag(final Object value) {
3162     if (value instanceof String) {
3163       return CodedOutputStream.computeStringSizeNoTag((String) value);
3164     } else {
3165       return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
3166     }
3167   }
3168 
3169   protected static void writeString(
3170       CodedOutputStream output, final int fieldNumber, final Object value) throws IOException {
3171     if (value instanceof String) {
3172       output.writeString(fieldNumber, (String) value);
3173     } else {
3174       output.writeBytes(fieldNumber, (ByteString) value);
3175     }
3176   }
3177 
3178   protected static void writeStringNoTag(
3179       CodedOutputStream output, final Object value) throws IOException {
3180     if (value instanceof String) {
3181       output.writeStringNoTag((String) value);
3182     } else {
3183       output.writeBytesNoTag((ByteString) value);
3184     }
3185   }
3186 
3187   protected static <V> void serializeIntegerMapTo(
3188       CodedOutputStream out,
3189       MapField<Integer, V> field,
3190       MapEntry<Integer, V> defaultEntry,
3191       int fieldNumber) throws IOException {
3192     Map<Integer, V> m = field.getMap();
3193     if (!out.isSerializationDeterministic()) {
3194       serializeMapTo(out, m, defaultEntry, fieldNumber);
3195       return;
3196     }
3197     // Sorting the unboxed keys and then look up the values during serialization is 2x faster
3198     // than sorting map entries with a custom comparator directly.
3199     int[] keys = new int[m.size()];
3200     int index = 0;
3201     for (int k : m.keySet()) {
3202       keys[index++] = k;
3203     }
3204     Arrays.sort(keys);
3205     for (int key : keys) {
3206       out.writeMessage(fieldNumber,
3207           defaultEntry.newBuilderForType()
3208               .setKey(key)
3209               .setValue(m.get(key))
3210               .build());
3211     }
3212   }
3213 
3214   protected static <V> void serializeLongMapTo(
3215       CodedOutputStream out,
3216       MapField<Long, V> field,
3217       MapEntry<Long, V> defaultEntry,
3218       int fieldNumber)
3219       throws IOException {
3220     Map<Long, V> m = field.getMap();
3221     if (!out.isSerializationDeterministic()) {
3222       serializeMapTo(out, m, defaultEntry, fieldNumber);
3223       return;
3224     }
3225 
3226     long[] keys = new long[m.size()];
3227     int index = 0;
3228     for (long k : m.keySet()) {
3229       keys[index++] = k;
3230     }
3231     Arrays.sort(keys);
3232     for (long key : keys) {
3233       out.writeMessage(fieldNumber,
3234           defaultEntry.newBuilderForType()
3235               .setKey(key)
3236               .setValue(m.get(key))
3237               .build());
3238     }
3239   }
3240 
3241   protected static <V> void serializeStringMapTo(
3242       CodedOutputStream out,
3243       MapField<String, V> field,
3244       MapEntry<String, V> defaultEntry,
3245       int fieldNumber)
3246       throws IOException {
3247     Map<String, V> m = field.getMap();
3248     if (!out.isSerializationDeterministic()) {
3249       serializeMapTo(out, m, defaultEntry, fieldNumber);
3250       return;
3251     }
3252 
3253     // Sorting the String keys and then look up the values during serialization is 25% faster than
3254     // sorting map entries with a custom comparator directly.
3255     String[] keys = new String[m.size()];
3256     keys = m.keySet().toArray(keys);
3257     Arrays.sort(keys);
3258     for (String key : keys) {
3259       out.writeMessage(fieldNumber,
3260           defaultEntry.newBuilderForType()
3261               .setKey(key)
3262               .setValue(m.get(key))
3263               .build());
3264     }
3265   }
3266 
3267   protected static <V> void serializeBooleanMapTo(
3268       CodedOutputStream out,
3269       MapField<Boolean, V> field,
3270       MapEntry<Boolean, V> defaultEntry,
3271       int fieldNumber)
3272       throws IOException {
3273     Map<Boolean, V> m = field.getMap();
3274     if (!out.isSerializationDeterministic()) {
3275       serializeMapTo(out, m, defaultEntry, fieldNumber);
3276       return;
3277     }
3278     maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, false);
3279     maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, true);
3280   }
3281 
3282   private static <V> void maybeSerializeBooleanEntryTo(
3283       CodedOutputStream out,
3284       Map<Boolean, V> m,
3285       MapEntry<Boolean, V> defaultEntry,
3286       int fieldNumber,
3287       boolean key)
3288       throws IOException {
3289     if (m.containsKey(key)) {
3290       out.writeMessage(fieldNumber,
3291           defaultEntry.newBuilderForType()
3292               .setKey(key)
3293               .setValue(m.get(key))
3294               .build());
3295     }
3296   }
3297 
3298   /** Serialize the map using the iteration order. */
3299   private static <K, V> void serializeMapTo(
3300       CodedOutputStream out,
3301       Map<K, V> m,
3302       MapEntry<K, V> defaultEntry,
3303       int fieldNumber)
3304       throws IOException {
3305     for (Map.Entry<K, V> entry : m.entrySet()) {
3306       out.writeMessage(fieldNumber,
3307           defaultEntry.newBuilderForType()
3308               .setKey(entry.getKey())
3309               .setValue(entry.getValue())
3310               .build());
3311     }
3312   }
3313 }
3314 
3315