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