Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/tools/ExternalEvaluation/Java/ExternalEvaluation.Service/src/com/google/protobuf/GeneratedMessage.java @ 15014

Last change on this file since 15014 was 15014, checked in by pfleck, 7 years ago

Added code and tools for the ExternalEvaluationProblem. (e.g. Java-side evaluation)

File size: 66.4 KB
Line 
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31package com.google.protobuf;
32
33import com.google.protobuf.Descriptors.Descriptor;
34import com.google.protobuf.Descriptors.EnumValueDescriptor;
35import com.google.protobuf.Descriptors.FieldDescriptor;
36
37import java.io.IOException;
38import java.io.ObjectStreamException;
39import java.io.Serializable;
40import java.lang.reflect.InvocationTargetException;
41import java.lang.reflect.Method;
42import java.util.ArrayList;
43import java.util.Collections;
44import java.util.Iterator;
45import java.util.List;
46import java.util.Map;
47import java.util.TreeMap;
48
49/**
50 * All generated protocol message classes extend this class.  This class
51 * implements most of the Message and Builder interfaces using Java reflection.
52 * Users can ignore this class and pretend that generated messages implement
53 * the Message interface directly.
54 *
55 * @author kenton@google.com Kenton Varda
56 */
57public abstract class GeneratedMessage extends AbstractMessage
58    implements Serializable {
59  private static final long serialVersionUID = 1L;
60
61  private final UnknownFieldSet unknownFields;
62
63  /**
64   * For testing. Allows a test to disable the optimization that avoids using
65   * field builders for nested messages until they are requested. By disabling
66   * this optimization, existing tests can be reused to test the field builders.
67   */
68  protected static boolean alwaysUseFieldBuilders = false;
69
70  protected GeneratedMessage() {
71    this.unknownFields = UnknownFieldSet.getDefaultInstance();
72  }
73
74  protected GeneratedMessage(Builder<?> builder) {
75    this.unknownFields = builder.getUnknownFields();
76  }
77
78 /**
79  * For testing. Allows a test to disable the optimization that avoids using
80  * field builders for nested messages until they are requested. By disabling
81  * this optimization, existing tests can be reused to test the field builders.
82  * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}.
83  */
84  static void enableAlwaysUseFieldBuildersForTesting() {
85    alwaysUseFieldBuilders = true;
86  }
87
88  /**
89   * Get the FieldAccessorTable for this type.  We can't have the message
90   * class pass this in to the constructor because of bootstrapping trouble
91   * with DescriptorProtos.
92   */
93  protected abstract FieldAccessorTable internalGetFieldAccessorTable();
94
95  //@Override (Java 1.6 override semantics, but we must support 1.5)
96  public Descriptor getDescriptorForType() {
97    return internalGetFieldAccessorTable().descriptor;
98  }
99
100  /** Internal helper which returns a mutable map. */
101  private Map<FieldDescriptor, Object> getAllFieldsMutable() {
102    final TreeMap<FieldDescriptor, Object> result =
103      new TreeMap<FieldDescriptor, Object>();
104    final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
105    for (final FieldDescriptor field : descriptor.getFields()) {
106      if (field.isRepeated()) {
107        final List<?> value = (List<?>) getField(field);
108        if (!value.isEmpty()) {
109          result.put(field, value);
110        }
111      } else {
112        if (hasField(field)) {
113          result.put(field, getField(field));
114        }
115      }
116    }
117    return result;
118  }
119
120  @Override
121  public boolean isInitialized() {
122    for (final FieldDescriptor field : getDescriptorForType().getFields()) {
123      // Check that all required fields are present.
124      if (field.isRequired()) {
125        if (!hasField(field)) {
126          return false;
127        }
128      }
129      // Check that embedded messages are initialized.
130      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
131        if (field.isRepeated()) {
132          @SuppressWarnings("unchecked") final
133          List<Message> messageList = (List<Message>) getField(field);
134          for (final Message element : messageList) {
135            if (!element.isInitialized()) {
136              return false;
137            }
138          }
139        } else {
140          if (hasField(field) && !((Message) getField(field)).isInitialized()) {
141            return false;
142          }
143        }
144      }
145    }
146
147    return true;
148  }
149
150  //@Override (Java 1.6 override semantics, but we must support 1.5)
151  public Map<FieldDescriptor, Object> getAllFields() {
152    return Collections.unmodifiableMap(getAllFieldsMutable());
153  }
154
155  //@Override (Java 1.6 override semantics, but we must support 1.5)
156  public boolean hasField(final FieldDescriptor field) {
157    return internalGetFieldAccessorTable().getField(field).has(this);
158  }
159
160  //@Override (Java 1.6 override semantics, but we must support 1.5)
161  public Object getField(final FieldDescriptor field) {
162    return internalGetFieldAccessorTable().getField(field).get(this);
163  }
164
165  //@Override (Java 1.6 override semantics, but we must support 1.5)
166  public int getRepeatedFieldCount(final FieldDescriptor field) {
167    return internalGetFieldAccessorTable().getField(field)
168      .getRepeatedCount(this);
169  }
170
171  //@Override (Java 1.6 override semantics, but we must support 1.5)
172  public Object getRepeatedField(final FieldDescriptor field, final int index) {
173    return internalGetFieldAccessorTable().getField(field)
174      .getRepeated(this, index);
175  }
176
177  //@Override (Java 1.6 override semantics, but we must support 1.5)
178  public final UnknownFieldSet getUnknownFields() {
179    return unknownFields;
180  }
181
182  protected abstract Message.Builder newBuilderForType(BuilderParent parent);
183
184  /**
185   * Interface for the parent of a Builder that allows the builder to
186   * communicate invalidations back to the parent for use when using nested
187   * builders.
188   */
189  protected interface BuilderParent {
190
191    /**
192     * A builder becomes dirty whenever a field is modified -- including fields
193     * in nested builders -- and becomes clean when build() is called.  Thus,
194     * when a builder becomes dirty, all its parents become dirty as well, and
195     * when it becomes clean, all its children become clean.  The dirtiness
196     * state is used to invalidate certain cached values.
197     * <br>
198     * To this end, a builder calls markAsDirty() on its parent whenever it
199     * transitions from clean to dirty.  The parent must propagate this call to
200     * its own parent, unless it was already dirty, in which case the
201     * grandparent must necessarily already be dirty as well.  The parent can
202     * only transition back to "clean" after calling build() on all children.
203     */
204    void markDirty();
205  }
206
207  @SuppressWarnings("unchecked")
208  public abstract static class Builder <BuilderType extends Builder>
209      extends AbstractMessage.Builder<BuilderType> {
210
211    private BuilderParent builderParent;
212
213    private BuilderParentImpl meAsParent;
214
215    // Indicates that we've built a message and so we are now obligated
216    // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
217    private boolean isClean;
218
219    private UnknownFieldSet unknownFields =
220        UnknownFieldSet.getDefaultInstance();
221
222    protected Builder() {
223      this(null);
224    }
225
226    protected Builder(BuilderParent builderParent) {
227      this.builderParent = builderParent;
228    }
229
230    void dispose() {
231      builderParent = null;
232    }
233
234    /**
235     * Called by the subclass when a message is built.
236     */
237    protected void onBuilt() {
238      if (builderParent != null) {
239        markClean();
240      }
241    }
242
243    /**
244     * Called by the subclass or a builder to notify us that a message was
245     * built and may be cached and therefore invalidations are needed.
246     */
247    protected void markClean() {
248      this.isClean = true;
249    }
250
251    /**
252     * Gets whether invalidations are needed
253     *
254     * @return whether invalidations are needed
255     */
256    protected boolean isClean() {
257      return isClean;
258    }
259
260    // This is implemented here only to work around an apparent bug in the
261    // Java compiler and/or build system.  See bug #1898463.  The mere presence
262    // of this dummy clone() implementation makes it go away.
263    @Override
264    public BuilderType clone() {
265      throw new UnsupportedOperationException(
266          "This is supposed to be overridden by subclasses.");
267    }
268
269    /**
270     * Called by the initialization and clear code paths to allow subclasses to
271     * reset any of their builtin fields back to the initial values.
272     */
273    public BuilderType clear() {
274      unknownFields = UnknownFieldSet.getDefaultInstance();
275      onChanged();
276      return (BuilderType) this;
277    }
278
279    /**
280     * Get the FieldAccessorTable for this type.  We can't have the message
281     * class pass this in to the constructor because of bootstrapping trouble
282     * with DescriptorProtos.
283     */
284    protected abstract FieldAccessorTable internalGetFieldAccessorTable();
285
286    //@Override (Java 1.6 override semantics, but we must support 1.5)
287    public Descriptor getDescriptorForType() {
288      return internalGetFieldAccessorTable().descriptor;
289    }
290
291    //@Override (Java 1.6 override semantics, but we must support 1.5)
292    public Map<FieldDescriptor, Object> getAllFields() {
293      return Collections.unmodifiableMap(getAllFieldsMutable());
294    }
295
296    /** Internal helper which returns a mutable map. */
297    private Map<FieldDescriptor, Object> getAllFieldsMutable() {
298      final TreeMap<FieldDescriptor, Object> result =
299        new TreeMap<FieldDescriptor, Object>();
300      final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
301      for (final FieldDescriptor field : descriptor.getFields()) {
302        if (field.isRepeated()) {
303          final List value = (List) getField(field);
304          if (!value.isEmpty()) {
305            result.put(field, value);
306          }
307        } else {
308          if (hasField(field)) {
309            result.put(field, getField(field));
310          }
311        }
312      }
313      return result;
314    }
315
316    public Message.Builder newBuilderForField(
317        final FieldDescriptor field) {
318      return internalGetFieldAccessorTable().getField(field).newBuilder();
319    }
320
321    //@Override (Java 1.6 override semantics, but we must support 1.5)
322    public boolean hasField(final FieldDescriptor field) {
323      return internalGetFieldAccessorTable().getField(field).has(this);
324    }
325
326    //@Override (Java 1.6 override semantics, but we must support 1.5)
327    public Object getField(final FieldDescriptor field) {
328      Object object = internalGetFieldAccessorTable().getField(field).get(this);
329      if (field.isRepeated()) {
330        // The underlying list object is still modifiable at this point.
331        // Make sure not to expose the modifiable list to the caller.
332        return Collections.unmodifiableList((List) object);
333      } else {
334        return object;
335      }
336    }
337
338    public BuilderType setField(final FieldDescriptor field,
339                                final Object value) {
340      internalGetFieldAccessorTable().getField(field).set(this, value);
341      return (BuilderType) this;
342    }
343
344    //@Override (Java 1.6 override semantics, but we must support 1.5)
345    public BuilderType clearField(final FieldDescriptor field) {
346      internalGetFieldAccessorTable().getField(field).clear(this);
347      return (BuilderType) this;
348    }
349
350    //@Override (Java 1.6 override semantics, but we must support 1.5)
351    public int getRepeatedFieldCount(final FieldDescriptor field) {
352      return internalGetFieldAccessorTable().getField(field)
353          .getRepeatedCount(this);
354    }
355
356    //@Override (Java 1.6 override semantics, but we must support 1.5)
357    public Object getRepeatedField(final FieldDescriptor field,
358                                   final int index) {
359      return internalGetFieldAccessorTable().getField(field)
360          .getRepeated(this, index);
361    }
362
363    public BuilderType setRepeatedField(final FieldDescriptor field,
364                                        final int index, final Object value) {
365      internalGetFieldAccessorTable().getField(field)
366        .setRepeated(this, index, value);
367      return (BuilderType) this;
368    }
369
370    public BuilderType addRepeatedField(final FieldDescriptor field,
371                                        final Object value) {
372      internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
373      return (BuilderType) this;
374    }
375
376    public final BuilderType setUnknownFields(
377        final UnknownFieldSet unknownFields) {
378      this.unknownFields = unknownFields;
379      onChanged();
380      return (BuilderType) this;
381    }
382
383    @Override
384    public final BuilderType mergeUnknownFields(
385        final UnknownFieldSet unknownFields) {
386      this.unknownFields =
387        UnknownFieldSet.newBuilder(this.unknownFields)
388                       .mergeFrom(unknownFields)
389                       .build();
390      onChanged();
391      return (BuilderType) this;
392    }
393
394    //@Override (Java 1.6 override semantics, but we must support 1.5)
395    public boolean isInitialized() {
396      for (final FieldDescriptor field : getDescriptorForType().getFields()) {
397        // Check that all required fields are present.
398        if (field.isRequired()) {
399          if (!hasField(field)) {
400            return false;
401          }
402        }
403        // Check that embedded messages are initialized.
404        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
405          if (field.isRepeated()) {
406            @SuppressWarnings("unchecked") final
407            List<Message> messageList = (List<Message>) getField(field);
408            for (final Message element : messageList) {
409              if (!element.isInitialized()) {
410                return false;
411              }
412            }
413          } else {
414            if (hasField(field) &&
415                !((Message) getField(field)).isInitialized()) {
416              return false;
417            }
418          }
419        }
420      }
421      return true;
422    }
423
424    //@Override (Java 1.6 override semantics, but we must support 1.5)
425    public final UnknownFieldSet getUnknownFields() {
426      return unknownFields;
427    }
428
429    /**
430     * Called by subclasses to parse an unknown field.
431     * @return {@code true} unless the tag is an end-group tag.
432     */
433    protected boolean parseUnknownField(
434        final CodedInputStream input,
435        final UnknownFieldSet.Builder unknownFields,
436        final ExtensionRegistryLite extensionRegistry,
437        final int tag) throws IOException {
438      return unknownFields.mergeFieldFrom(tag, input);
439    }
440
441    /**
442     * Implementation of {@link BuilderParent} for giving to our children. This
443     * small inner class makes it so we don't publicly expose the BuilderParent
444     * methods.
445     */
446    private class BuilderParentImpl implements BuilderParent {
447
448      //@Override (Java 1.6 override semantics, but we must support 1.5)
449      public void markDirty() {
450        onChanged();
451      }
452    }
453
454    /**
455     * Gets the {@link BuilderParent} for giving to our children.
456     * @return The builder parent for our children.
457     */
458    protected BuilderParent getParentForChildren() {
459      if (meAsParent == null) {
460        meAsParent = new BuilderParentImpl();
461      }
462      return meAsParent;
463    }
464
465    /**
466     * Called when a the builder or one of its nested children has changed
467     * and any parent should be notified of its invalidation.
468     */
469    protected final void onChanged() {
470      if (isClean && builderParent != null) {
471        builderParent.markDirty();
472
473        // Don't keep dispatching invalidations until build is called again.
474        isClean = false;
475      }
476    }
477  }
478
479  // =================================================================
480  // Extensions-related stuff
481
482  public interface ExtendableMessageOrBuilder<
483      MessageType extends ExtendableMessage> extends MessageOrBuilder {
484
485    /** Check if a singular extension is present. */
486    <Type> boolean hasExtension(
487        GeneratedExtension<MessageType, Type> extension);
488
489    /** Get the number of elements in a repeated extension. */
490    <Type> int getExtensionCount(
491        GeneratedExtension<MessageType, List<Type>> extension);
492
493    /** Get the value of an extension. */
494    <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
495
496    /** Get one element of a repeated extension. */
497    <Type> Type getExtension(
498        GeneratedExtension<MessageType, List<Type>> extension,
499        int index);
500  }
501
502  /**
503   * Generated message classes for message types that contain extension ranges
504   * subclass this.
505   *
506   * <p>This class implements type-safe accessors for extensions.  They
507   * implement all the same operations that you can do with normal fields --
508   * e.g. "has", "get", and "getCount" -- but for extensions.  The extensions
509   * are identified using instances of the class {@link GeneratedExtension};
510   * the protocol compiler generates a static instance of this class for every
511   * extension in its input.  Through the magic of generics, all is made
512   * type-safe.
513   *
514   * <p>For example, imagine you have the {@code .proto} file:
515   *
516   * <pre>
517   * option java_class = "MyProto";
518   *
519   * message Foo {
520   *   extensions 1000 to max;
521   * }
522   *
523   * extend Foo {
524   *   optional int32 bar;
525   * }
526   * </pre>
527   *
528   * <p>Then you might write code like:
529   *
530   * <pre>
531   * MyProto.Foo foo = getFoo();
532   * int i = foo.getExtension(MyProto.bar);
533   * </pre>
534   *
535   * <p>See also {@link ExtendableBuilder}.
536   */
537  public abstract static class ExtendableMessage<
538        MessageType extends ExtendableMessage>
539      extends GeneratedMessage
540      implements ExtendableMessageOrBuilder<MessageType> {
541
542    private final FieldSet<FieldDescriptor> extensions;
543
544    protected ExtendableMessage() {
545      this.extensions = FieldSet.newFieldSet();
546    }
547
548    protected ExtendableMessage(
549        ExtendableBuilder<MessageType, ?> builder) {
550      super(builder);
551      this.extensions = builder.buildExtensions();
552    }
553
554    private void verifyExtensionContainingType(
555        final GeneratedExtension<MessageType, ?> extension) {
556      if (extension.getDescriptor().getContainingType() !=
557          getDescriptorForType()) {
558        // This can only happen if someone uses unchecked operations.
559        throw new IllegalArgumentException(
560          "Extension is for type \"" +
561          extension.getDescriptor().getContainingType().getFullName() +
562          "\" which does not match message type \"" +
563          getDescriptorForType().getFullName() + "\".");
564      }
565    }
566
567    /** Check if a singular extension is present. */
568    //@Override (Java 1.6 override semantics, but we must support 1.5)
569    public final <Type> boolean hasExtension(
570        final GeneratedExtension<MessageType, Type> extension) {
571      verifyExtensionContainingType(extension);
572      return extensions.hasField(extension.getDescriptor());
573    }
574
575    /** Get the number of elements in a repeated extension. */
576    //@Override (Java 1.6 override semantics, but we must support 1.5)
577    public final <Type> int getExtensionCount(
578        final GeneratedExtension<MessageType, List<Type>> extension) {
579      verifyExtensionContainingType(extension);
580      final FieldDescriptor descriptor = extension.getDescriptor();
581      return extensions.getRepeatedFieldCount(descriptor);
582    }
583
584    /** Get the value of an extension. */
585    //@Override (Java 1.6 override semantics, but we must support 1.5)
586    @SuppressWarnings("unchecked")
587    public final <Type> Type getExtension(
588        final GeneratedExtension<MessageType, Type> extension) {
589      verifyExtensionContainingType(extension);
590      FieldDescriptor descriptor = extension.getDescriptor();
591      final Object value = extensions.getField(descriptor);
592      if (value == null) {
593        if (descriptor.isRepeated()) {
594          return (Type) Collections.emptyList();
595        } else if (descriptor.getJavaType() ==
596                   FieldDescriptor.JavaType.MESSAGE) {
597          return (Type) extension.getMessageDefaultInstance();
598        } else {
599          return (Type) extension.fromReflectionType(
600              descriptor.getDefaultValue());
601        }
602      } else {
603        return (Type) extension.fromReflectionType(value);
604      }
605    }
606
607    /** Get one element of a repeated extension. */
608    //@Override (Java 1.6 override semantics, but we must support 1.5)
609    @SuppressWarnings("unchecked")
610    public final <Type> Type getExtension(
611        final GeneratedExtension<MessageType, List<Type>> extension,
612        final int index) {
613      verifyExtensionContainingType(extension);
614      FieldDescriptor descriptor = extension.getDescriptor();
615      return (Type) extension.singularFromReflectionType(
616          extensions.getRepeatedField(descriptor, index));
617    }
618
619    /** Called by subclasses to check if all extensions are initialized. */
620    protected boolean extensionsAreInitialized() {
621      return extensions.isInitialized();
622    }
623
624    @Override
625    public boolean isInitialized() {
626      return super.isInitialized() && extensionsAreInitialized();
627    }
628
629    /**
630     * Used by subclasses to serialize extensions.  Extension ranges may be
631     * interleaved with field numbers, but we must write them in canonical
632     * (sorted by field number) order.  ExtensionWriter helps us write
633     * individual ranges of extensions at once.
634     */
635    protected class ExtensionWriter {
636      // Imagine how much simpler this code would be if Java iterators had
637      // a way to get the next element without advancing the iterator.
638
639      private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
640        extensions.iterator();
641      private Map.Entry<FieldDescriptor, Object> next;
642      private final boolean messageSetWireFormat;
643
644      private ExtensionWriter(final boolean messageSetWireFormat) {
645        if (iter.hasNext()) {
646          next = iter.next();
647        }
648        this.messageSetWireFormat = messageSetWireFormat;
649      }
650
651      public void writeUntil(final int end, final CodedOutputStream output)
652                             throws IOException {
653        while (next != null && next.getKey().getNumber() < end) {
654          FieldDescriptor descriptor = next.getKey();
655          if (messageSetWireFormat && descriptor.getLiteJavaType() ==
656                  WireFormat.JavaType.MESSAGE &&
657              !descriptor.isRepeated()) {
658            output.writeMessageSetExtension(descriptor.getNumber(),
659                                            (Message) next.getValue());
660          } else {
661            FieldSet.writeField(descriptor, next.getValue(), output);
662          }
663          if (iter.hasNext()) {
664            next = iter.next();
665          } else {
666            next = null;
667          }
668        }
669      }
670    }
671
672    protected ExtensionWriter newExtensionWriter() {
673      return new ExtensionWriter(false);
674    }
675    protected ExtensionWriter newMessageSetExtensionWriter() {
676      return new ExtensionWriter(true);
677    }
678
679    /** Called by subclasses to compute the size of extensions. */
680    protected int extensionsSerializedSize() {
681      return extensions.getSerializedSize();
682    }
683    protected int extensionsSerializedSizeAsMessageSet() {
684      return extensions.getMessageSetSerializedSize();
685    }
686
687    // ---------------------------------------------------------------
688    // Reflection
689
690    protected Map<FieldDescriptor, Object> getExtensionFields() {
691      return extensions.getAllFields();
692    }
693
694    @Override
695    public Map<FieldDescriptor, Object> getAllFields() {
696      final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
697      result.putAll(getExtensionFields());
698      return Collections.unmodifiableMap(result);
699    }
700
701    @Override
702    public boolean hasField(final FieldDescriptor field) {
703      if (field.isExtension()) {
704        verifyContainingType(field);
705        return extensions.hasField(field);
706      } else {
707        return super.hasField(field);
708      }
709    }
710
711    @Override
712    public Object getField(final FieldDescriptor field) {
713      if (field.isExtension()) {
714        verifyContainingType(field);
715        final Object value = extensions.getField(field);
716        if (value == null) {
717          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
718            // Lacking an ExtensionRegistry, we have no way to determine the
719            // extension's real type, so we return a DynamicMessage.
720            return DynamicMessage.getDefaultInstance(field.getMessageType());
721          } else {
722            return field.getDefaultValue();
723          }
724        } else {
725          return value;
726        }
727      } else {
728        return super.getField(field);
729      }
730    }
731
732    @Override
733    public int getRepeatedFieldCount(final FieldDescriptor field) {
734      if (field.isExtension()) {
735        verifyContainingType(field);
736        return extensions.getRepeatedFieldCount(field);
737      } else {
738        return super.getRepeatedFieldCount(field);
739      }
740    }
741
742    @Override
743    public Object getRepeatedField(final FieldDescriptor field,
744                                   final int index) {
745      if (field.isExtension()) {
746        verifyContainingType(field);
747        return extensions.getRepeatedField(field, index);
748      } else {
749        return super.getRepeatedField(field, index);
750      }
751    }
752
753    private void verifyContainingType(final FieldDescriptor field) {
754      if (field.getContainingType() != getDescriptorForType()) {
755        throw new IllegalArgumentException(
756          "FieldDescriptor does not match message type.");
757      }
758    }
759  }
760
761  /**
762   * Generated message builders for message types that contain extension ranges
763   * subclass this.
764   *
765   * <p>This class implements type-safe accessors for extensions.  They
766   * implement all the same operations that you can do with normal fields --
767   * e.g. "get", "set", and "add" -- but for extensions.  The extensions are
768   * identified using instances of the class {@link GeneratedExtension}; the
769   * protocol compiler generates a static instance of this class for every
770   * extension in its input.  Through the magic of generics, all is made
771   * type-safe.
772   *
773   * <p>For example, imagine you have the {@code .proto} file:
774   *
775   * <pre>
776   * option java_class = "MyProto";
777   *
778   * message Foo {
779   *   extensions 1000 to max;
780   * }
781   *
782   * extend Foo {
783   *   optional int32 bar;
784   * }
785   * </pre>
786   *
787   * <p>Then you might write code like:
788   *
789   * <pre>
790   * MyProto.Foo foo =
791   *   MyProto.Foo.newBuilder()
792   *     .setExtension(MyProto.bar, 123)
793   *     .build();
794   * </pre>
795   *
796   * <p>See also {@link ExtendableMessage}.
797   */
798  @SuppressWarnings("unchecked")
799  public abstract static class ExtendableBuilder<
800        MessageType extends ExtendableMessage,
801        BuilderType extends ExtendableBuilder>
802      extends Builder<BuilderType>
803      implements ExtendableMessageOrBuilder<MessageType> {
804
805    private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet();
806
807    protected ExtendableBuilder() {}
808
809    protected ExtendableBuilder(
810        BuilderParent parent) {
811      super(parent);
812    }
813
814    @Override
815    public BuilderType clear() {
816      extensions = FieldSet.emptySet();
817      return super.clear();
818    }
819
820    // This is implemented here only to work around an apparent bug in the
821    // Java compiler and/or build system.  See bug #1898463.  The mere presence
822    // of this dummy clone() implementation makes it go away.
823    @Override
824    public BuilderType clone() {
825      throw new UnsupportedOperationException(
826          "This is supposed to be overridden by subclasses.");
827    }
828
829    private void ensureExtensionsIsMutable() {
830      if (extensions.isImmutable()) {
831        extensions = extensions.clone();
832      }
833    }
834
835    private void verifyExtensionContainingType(
836        final GeneratedExtension<MessageType, ?> extension) {
837      if (extension.getDescriptor().getContainingType() !=
838          getDescriptorForType()) {
839        // This can only happen if someone uses unchecked operations.
840        throw new IllegalArgumentException(
841          "Extension is for type \"" +
842          extension.getDescriptor().getContainingType().getFullName() +
843          "\" which does not match message type \"" +
844          getDescriptorForType().getFullName() + "\".");
845      }
846    }
847
848    /** Check if a singular extension is present. */
849    //@Override (Java 1.6 override semantics, but we must support 1.5)
850    public final <Type> boolean hasExtension(
851        final GeneratedExtension<MessageType, Type> extension) {
852      verifyExtensionContainingType(extension);
853      return extensions.hasField(extension.getDescriptor());
854    }
855
856    /** Get the number of elements in a repeated extension. */
857    //@Override (Java 1.6 override semantics, but we must support 1.5)
858    public final <Type> int getExtensionCount(
859        final GeneratedExtension<MessageType, List<Type>> extension) {
860      verifyExtensionContainingType(extension);
861      final FieldDescriptor descriptor = extension.getDescriptor();
862      return extensions.getRepeatedFieldCount(descriptor);
863    }
864
865    /** Get the value of an extension. */
866    //@Override (Java 1.6 override semantics, but we must support 1.5)
867    public final <Type> Type getExtension(
868        final GeneratedExtension<MessageType, Type> extension) {
869      verifyExtensionContainingType(extension);
870      FieldDescriptor descriptor = extension.getDescriptor();
871      final Object value = extensions.getField(descriptor);
872      if (value == null) {
873        if (descriptor.isRepeated()) {
874          return (Type) Collections.emptyList();
875        } else if (descriptor.getJavaType() ==
876                   FieldDescriptor.JavaType.MESSAGE) {
877          return (Type) extension.getMessageDefaultInstance();
878        } else {
879          return (Type) extension.fromReflectionType(
880              descriptor.getDefaultValue());
881        }
882      } else {
883        return (Type) extension.fromReflectionType(value);
884      }
885    }
886
887    /** Get one element of a repeated extension. */
888    //@Override (Java 1.6 override semantics, but we must support 1.5)
889    public final <Type> Type getExtension(
890        final GeneratedExtension<MessageType, List<Type>> extension,
891        final int index) {
892      verifyExtensionContainingType(extension);
893      FieldDescriptor descriptor = extension.getDescriptor();
894      return (Type) extension.singularFromReflectionType(
895          extensions.getRepeatedField(descriptor, index));
896    }
897
898    /** Set the value of an extension. */
899    public final <Type> BuilderType setExtension(
900        final GeneratedExtension<MessageType, Type> extension,
901        final Type value) {
902      verifyExtensionContainingType(extension);
903      ensureExtensionsIsMutable();
904      final FieldDescriptor descriptor = extension.getDescriptor();
905      extensions.setField(descriptor, extension.toReflectionType(value));
906      onChanged();
907      return (BuilderType) this;
908    }
909
910    /** Set the value of one element of a repeated extension. */
911    public final <Type> BuilderType setExtension(
912        final GeneratedExtension<MessageType, List<Type>> extension,
913        final int index, final Type value) {
914      verifyExtensionContainingType(extension);
915      ensureExtensionsIsMutable();
916      final FieldDescriptor descriptor = extension.getDescriptor();
917      extensions.setRepeatedField(
918        descriptor, index,
919        extension.singularToReflectionType(value));
920      onChanged();
921      return (BuilderType) this;
922    }
923
924    /** Append a value to a repeated extension. */
925    public final <Type> BuilderType addExtension(
926        final GeneratedExtension<MessageType, List<Type>> extension,
927        final Type value) {
928      verifyExtensionContainingType(extension);
929      ensureExtensionsIsMutable();
930      final FieldDescriptor descriptor = extension.getDescriptor();
931      extensions.addRepeatedField(
932          descriptor, extension.singularToReflectionType(value));
933      onChanged();
934      return (BuilderType) this;
935    }
936
937    /** Clear an extension. */
938    public final <Type> BuilderType clearExtension(
939        final GeneratedExtension<MessageType, ?> extension) {
940      verifyExtensionContainingType(extension);
941      ensureExtensionsIsMutable();
942      extensions.clearField(extension.getDescriptor());
943      onChanged();
944      return (BuilderType) this;
945    }
946
947    /** Called by subclasses to check if all extensions are initialized. */
948    protected boolean extensionsAreInitialized() {
949      return extensions.isInitialized();
950    }
951
952    /**
953     * Called by the build code path to create a copy of the extensions for
954     * building the message.
955     */
956    private FieldSet<FieldDescriptor> buildExtensions() {
957      extensions.makeImmutable();
958      return extensions;
959    }
960
961    @Override
962    public boolean isInitialized() {
963      return super.isInitialized() && extensionsAreInitialized();
964    }
965
966    /**
967     * Called by subclasses to parse an unknown field or an extension.
968     * @return {@code true} unless the tag is an end-group tag.
969     */
970    @Override
971    protected boolean parseUnknownField(
972        final CodedInputStream input,
973        final UnknownFieldSet.Builder unknownFields,
974        final ExtensionRegistryLite extensionRegistry,
975        final int tag) throws IOException {
976      return AbstractMessage.Builder.mergeFieldFrom(
977        input, unknownFields, extensionRegistry, this, tag);
978    }
979
980    // ---------------------------------------------------------------
981    // Reflection
982
983    @Override
984    public Map<FieldDescriptor, Object> getAllFields() {
985      final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
986      result.putAll(extensions.getAllFields());
987      return Collections.unmodifiableMap(result);
988    }
989
990    @Override
991    public Object getField(final FieldDescriptor field) {
992      if (field.isExtension()) {
993        verifyContainingType(field);
994        final Object value = extensions.getField(field);
995        if (value == null) {
996          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
997            // Lacking an ExtensionRegistry, we have no way to determine the
998            // extension's real type, so we return a DynamicMessage.
999            return DynamicMessage.getDefaultInstance(field.getMessageType());
1000          } else {
1001            return field.getDefaultValue();
1002          }
1003        } else {
1004          return value;
1005        }
1006      } else {
1007        return super.getField(field);
1008      }
1009    }
1010
1011    @Override
1012    public int getRepeatedFieldCount(final FieldDescriptor field) {
1013      if (field.isExtension()) {
1014        verifyContainingType(field);
1015        return extensions.getRepeatedFieldCount(field);
1016      } else {
1017        return super.getRepeatedFieldCount(field);
1018      }
1019    }
1020
1021    @Override
1022    public Object getRepeatedField(final FieldDescriptor field,
1023                                   final int index) {
1024      if (field.isExtension()) {
1025        verifyContainingType(field);
1026        return extensions.getRepeatedField(field, index);
1027      } else {
1028        return super.getRepeatedField(field, index);
1029      }
1030    }
1031
1032    @Override
1033    public boolean hasField(final FieldDescriptor field) {
1034      if (field.isExtension()) {
1035        verifyContainingType(field);
1036        return extensions.hasField(field);
1037      } else {
1038        return super.hasField(field);
1039      }
1040    }
1041
1042    @Override
1043    public BuilderType setField(final FieldDescriptor field,
1044                                final Object value) {
1045      if (field.isExtension()) {
1046        verifyContainingType(field);
1047        ensureExtensionsIsMutable();
1048        extensions.setField(field, value);
1049        onChanged();
1050        return (BuilderType) this;
1051      } else {
1052        return super.setField(field, value);
1053      }
1054    }
1055
1056    @Override
1057    public BuilderType clearField(final FieldDescriptor field) {
1058      if (field.isExtension()) {
1059        verifyContainingType(field);
1060        ensureExtensionsIsMutable();
1061        extensions.clearField(field);
1062        onChanged();
1063        return (BuilderType) this;
1064      } else {
1065        return super.clearField(field);
1066      }
1067    }
1068
1069    @Override
1070    public BuilderType setRepeatedField(final FieldDescriptor field,
1071                                        final int index, final Object value) {
1072      if (field.isExtension()) {
1073        verifyContainingType(field);
1074        ensureExtensionsIsMutable();
1075        extensions.setRepeatedField(field, index, value);
1076        onChanged();
1077        return (BuilderType) this;
1078      } else {
1079        return super.setRepeatedField(field, index, value);
1080      }
1081    }
1082
1083    @Override
1084    public BuilderType addRepeatedField(final FieldDescriptor field,
1085                                        final Object value) {
1086      if (field.isExtension()) {
1087        verifyContainingType(field);
1088        ensureExtensionsIsMutable();
1089        extensions.addRepeatedField(field, value);
1090        onChanged();
1091        return (BuilderType) this;
1092      } else {
1093        return super.addRepeatedField(field, value);
1094      }
1095    }
1096
1097    protected final void mergeExtensionFields(final ExtendableMessage other) {
1098      ensureExtensionsIsMutable();
1099      extensions.mergeFrom(other.extensions);
1100      onChanged();
1101    }
1102
1103    private void verifyContainingType(final FieldDescriptor field) {
1104      if (field.getContainingType() != getDescriptorForType()) {
1105        throw new IllegalArgumentException(
1106          "FieldDescriptor does not match message type.");
1107      }
1108    }
1109  }
1110
1111  // -----------------------------------------------------------------
1112
1113  /**
1114   * Gets the descriptor for an extension. The implementation depends on whether
1115   * the extension is scoped in the top level of a file or scoped in a Message.
1116   */
1117  private static interface ExtensionDescriptorRetriever {
1118    FieldDescriptor getDescriptor();
1119  }
1120
1121  /** For use by generated code only. */
1122  public static <ContainingType extends Message, Type>
1123      GeneratedExtension<ContainingType, Type>
1124      newMessageScopedGeneratedExtension(final Message scope,
1125                                         final int descriptorIndex,
1126                                         final Class singularType,
1127                                         final Message defaultInstance) {
1128    // For extensions scoped within a Message, we use the Message to resolve
1129    // the outer class's descriptor, from which the extension descriptor is
1130    // obtained.
1131    return new GeneratedExtension<ContainingType, Type>(
1132        new ExtensionDescriptorRetriever() {
1133          //@Override (Java 1.6 override semantics, but we must support 1.5)
1134          public FieldDescriptor getDescriptor() {
1135            return scope.getDescriptorForType().getExtensions()
1136                .get(descriptorIndex);
1137          }
1138        },
1139        singularType,
1140        defaultInstance);
1141  }
1142
1143  /** For use by generated code only. */
1144  public static <ContainingType extends Message, Type>
1145     GeneratedExtension<ContainingType, Type>
1146     newFileScopedGeneratedExtension(final Class singularType,
1147                                     final Message defaultInstance) {
1148    // For extensions scoped within a file, we rely on the outer class's
1149    // static initializer to call internalInit() on the extension when the
1150    // descriptor is available.
1151    return new GeneratedExtension<ContainingType, Type>(
1152        null,  // ExtensionDescriptorRetriever is initialized in internalInit();
1153        singularType,
1154        defaultInstance);
1155  }
1156
1157  /**
1158   * Type used to represent generated extensions.  The protocol compiler
1159   * generates a static singleton instance of this class for each extension.
1160   *
1161   * <p>For example, imagine you have the {@code .proto} file:
1162   *
1163   * <pre>
1164   * option java_class = "MyProto";
1165   *
1166   * message Foo {
1167   *   extensions 1000 to max;
1168   * }
1169   *
1170   * extend Foo {
1171   *   optional int32 bar;
1172   * }
1173   * </pre>
1174   *
1175   * <p>Then, {@code MyProto.Foo.bar} has type
1176   * {@code GeneratedExtension<MyProto.Foo, Integer>}.
1177   *
1178   * <p>In general, users should ignore the details of this type, and simply use
1179   * these static singletons as parameters to the extension accessors defined
1180   * in {@link ExtendableMessage} and {@link ExtendableBuilder}.
1181   */
1182  public static final class GeneratedExtension<
1183      ContainingType extends Message, Type> {
1184    // TODO(kenton):  Find ways to avoid using Java reflection within this
1185    //   class.  Also try to avoid suppressing unchecked warnings.
1186
1187    // We can't always initialize the descriptor of a GeneratedExtension when
1188    // we first construct it due to initialization order difficulties (namely,
1189    // the descriptor may not have been constructed yet, since it is often
1190    // constructed by the initializer of a separate module).
1191    //
1192    // In the case of nested extensions, we initialize the
1193    // ExtensionDescriptorRetriever with an instance that uses the scoping
1194    // Message's default instance to retrieve the extension's descriptor.
1195    //
1196    // In the case of non-nested extensions, we initialize the
1197    // ExtensionDescriptorRetriever to null and rely on the outer class's static
1198    // initializer to call internalInit() after the descriptor has been parsed.
1199    private GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever,
1200                               Class singularType,
1201                               Message messageDefaultInstance) {
1202      if (Message.class.isAssignableFrom(singularType) &&
1203          !singularType.isInstance(messageDefaultInstance)) {
1204        throw new IllegalArgumentException(
1205            "Bad messageDefaultInstance for " + singularType.getName());
1206      }
1207      this.descriptorRetriever = descriptorRetriever;
1208      this.singularType = singularType;
1209      this.messageDefaultInstance = messageDefaultInstance;
1210
1211      if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) {
1212        this.enumValueOf = getMethodOrDie(singularType, "valueOf",
1213                                          EnumValueDescriptor.class);
1214        this.enumGetValueDescriptor =
1215            getMethodOrDie(singularType, "getValueDescriptor");
1216      } else {
1217        this.enumValueOf = null;
1218        this.enumGetValueDescriptor = null;
1219      }
1220    }
1221
1222    /** For use by generated code only. */
1223    public void internalInit(final FieldDescriptor descriptor) {
1224      if (descriptorRetriever != null) {
1225        throw new IllegalStateException("Already initialized.");
1226      }
1227      descriptorRetriever = new ExtensionDescriptorRetriever() {
1228          //@Override (Java 1.6 override semantics, but we must support 1.5)
1229          public FieldDescriptor getDescriptor() {
1230            return descriptor;
1231          }
1232        };
1233    }
1234
1235    private ExtensionDescriptorRetriever descriptorRetriever;
1236    private final Class singularType;
1237    private final Message messageDefaultInstance;
1238    private final Method enumValueOf;
1239    private final Method enumGetValueDescriptor;
1240
1241    public FieldDescriptor getDescriptor() {
1242      if (descriptorRetriever == null) {
1243        throw new IllegalStateException(
1244            "getDescriptor() called before internalInit()");
1245      }
1246      return descriptorRetriever.getDescriptor();
1247    }
1248
1249    /**
1250     * If the extension is an embedded message or group, returns the default
1251     * instance of the message.
1252     */
1253    public Message getMessageDefaultInstance() {
1254      return messageDefaultInstance;
1255    }
1256
1257    /**
1258     * Convert from the type used by the reflection accessors to the type used
1259     * by native accessors.  E.g., for enums, the reflection accessors use
1260     * EnumValueDescriptors but the native accessors use the generated enum
1261     * type.
1262     */
1263    @SuppressWarnings("unchecked")
1264    private Object fromReflectionType(final Object value) {
1265      FieldDescriptor descriptor = getDescriptor();
1266      if (descriptor.isRepeated()) {
1267        if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE ||
1268            descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
1269          // Must convert the whole list.
1270          final List result = new ArrayList();
1271          for (final Object element : (List) value) {
1272            result.add(singularFromReflectionType(element));
1273          }
1274          return result;
1275        } else {
1276          return value;
1277        }
1278      } else {
1279        return singularFromReflectionType(value);
1280      }
1281    }
1282
1283    /**
1284     * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
1285     * type, this converts a single element.
1286     */
1287    private Object singularFromReflectionType(final Object value) {
1288      FieldDescriptor descriptor = getDescriptor();
1289      switch (descriptor.getJavaType()) {
1290        case MESSAGE:
1291          if (singularType.isInstance(value)) {
1292            return value;
1293          } else {
1294            // It seems the copy of the embedded message stored inside the
1295            // extended message is not of the exact type the user was
1296            // expecting.  This can happen if a user defines a
1297            // GeneratedExtension manually and gives it a different type.
1298            // This should not happen in normal use.  But, to be nice, we'll
1299            // copy the message to whatever type the caller was expecting.
1300            return messageDefaultInstance.newBuilderForType()
1301                           .mergeFrom((Message) value).build();
1302          }
1303        case ENUM:
1304          return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
1305        default:
1306          return value;
1307      }
1308    }
1309
1310    /**
1311     * Convert from the type used by the native accessors to the type used
1312     * by reflection accessors.  E.g., for enums, the reflection accessors use
1313     * EnumValueDescriptors but the native accessors use the generated enum
1314     * type.
1315     */
1316    @SuppressWarnings("unchecked")
1317    private Object toReflectionType(final Object value) {
1318      FieldDescriptor descriptor = getDescriptor();
1319      if (descriptor.isRepeated()) {
1320        if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
1321          // Must convert the whole list.
1322          final List result = new ArrayList();
1323          for (final Object element : (List) value) {
1324            result.add(singularToReflectionType(element));
1325          }
1326          return result;
1327        } else {
1328          return value;
1329        }
1330      } else {
1331        return singularToReflectionType(value);
1332      }
1333    }
1334
1335    /**
1336     * Like {@link #toReflectionType(Object)}, but if the type is a repeated
1337     * type, this converts a single element.
1338     */
1339    private Object singularToReflectionType(final Object value) {
1340      FieldDescriptor descriptor = getDescriptor();
1341      switch (descriptor.getJavaType()) {
1342        case ENUM:
1343          return invokeOrDie(enumGetValueDescriptor, value);
1344        default:
1345          return value;
1346      }
1347    }
1348  }
1349
1350  // =================================================================
1351
1352  /** Calls Class.getMethod and throws a RuntimeException if it fails. */
1353  @SuppressWarnings("unchecked")
1354  private static Method getMethodOrDie(
1355      final Class clazz, final String name, final Class... params) {
1356    try {
1357      return clazz.getMethod(name, params);
1358    } catch (NoSuchMethodException e) {
1359      throw new RuntimeException(
1360        "Generated message class \"" + clazz.getName() +
1361        "\" missing method \"" + name + "\".", e);
1362    }
1363  }
1364
1365  /** Calls invoke and throws a RuntimeException if it fails. */
1366  private static Object invokeOrDie(
1367      final Method method, final Object object, final Object... params) {
1368    try {
1369      return method.invoke(object, params);
1370    } catch (IllegalAccessException e) {
1371      throw new RuntimeException(
1372        "Couldn't use Java reflection to implement protocol message " +
1373        "reflection.", e);
1374    } catch (InvocationTargetException e) {
1375      final Throwable cause = e.getCause();
1376      if (cause instanceof RuntimeException) {
1377        throw (RuntimeException) cause;
1378      } else if (cause instanceof Error) {
1379        throw (Error) cause;
1380      } else {
1381        throw new RuntimeException(
1382          "Unexpected exception thrown by generated accessor method.", cause);
1383      }
1384    }
1385  }
1386
1387  /**
1388   * Users should ignore this class.  This class provides the implementation
1389   * with access to the fields of a message object using Java reflection.
1390   */
1391  public static final class FieldAccessorTable {
1392
1393    /**
1394     * Construct a FieldAccessorTable for a particular message class.  Only
1395     * one FieldAccessorTable should ever be constructed per class.
1396     *
1397     * @param descriptor     The type's descriptor.
1398     * @param camelCaseNames The camelcase names of all fields in the message.
1399     *                       These are used to derive the accessor method names.
1400     * @param messageClass   The message type.
1401     * @param builderClass   The builder type.
1402     */
1403    public FieldAccessorTable(
1404        final Descriptor descriptor,
1405        final String[] camelCaseNames,
1406        final Class<? extends GeneratedMessage> messageClass,
1407        final Class<? extends Builder> builderClass) {
1408      this.descriptor = descriptor;
1409      fields = new FieldAccessor[descriptor.getFields().size()];
1410
1411      for (int i = 0; i < fields.length; i++) {
1412        final FieldDescriptor field = descriptor.getFields().get(i);
1413        if (field.isRepeated()) {
1414          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
1415            fields[i] = new RepeatedMessageFieldAccessor(
1416              field, camelCaseNames[i], messageClass, builderClass);
1417          } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
1418            fields[i] = new RepeatedEnumFieldAccessor(
1419              field, camelCaseNames[i], messageClass, builderClass);
1420          } else {
1421            fields[i] = new RepeatedFieldAccessor(
1422              field, camelCaseNames[i], messageClass, builderClass);
1423          }
1424        } else {
1425          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
1426            fields[i] = new SingularMessageFieldAccessor(
1427              field, camelCaseNames[i], messageClass, builderClass);
1428          } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
1429            fields[i] = new SingularEnumFieldAccessor(
1430              field, camelCaseNames[i], messageClass, builderClass);
1431          } else {
1432            fields[i] = new SingularFieldAccessor(
1433              field, camelCaseNames[i], messageClass, builderClass);
1434          }
1435        }
1436      }
1437    }
1438
1439    private final Descriptor descriptor;
1440    private final FieldAccessor[] fields;
1441
1442    /** Get the FieldAccessor for a particular field. */
1443    private FieldAccessor getField(final FieldDescriptor field) {
1444      if (field.getContainingType() != descriptor) {
1445        throw new IllegalArgumentException(
1446          "FieldDescriptor does not match message type.");
1447      } else if (field.isExtension()) {
1448        // If this type had extensions, it would subclass ExtendableMessage,
1449        // which overrides the reflection interface to handle extensions.
1450        throw new IllegalArgumentException(
1451          "This type does not have extensions.");
1452      }
1453      return fields[field.getIndex()];
1454    }
1455
1456    /**
1457     * Abstract interface that provides access to a single field.  This is
1458     * implemented differently depending on the field type and cardinality.
1459     */
1460    private interface FieldAccessor {
1461      Object get(GeneratedMessage message);
1462      Object get(GeneratedMessage.Builder builder);
1463      void set(Builder builder, Object value);
1464      Object getRepeated(GeneratedMessage message, int index);
1465      Object getRepeated(GeneratedMessage.Builder builder, int index);
1466      void setRepeated(Builder builder,
1467                       int index, Object value);
1468      void addRepeated(Builder builder, Object value);
1469      boolean has(GeneratedMessage message);
1470      boolean has(GeneratedMessage.Builder builder);
1471      int getRepeatedCount(GeneratedMessage message);
1472      int getRepeatedCount(GeneratedMessage.Builder builder);
1473      void clear(Builder builder);
1474      Message.Builder newBuilder();
1475    }
1476
1477    // ---------------------------------------------------------------
1478
1479    private static class SingularFieldAccessor implements FieldAccessor {
1480      SingularFieldAccessor(
1481          final FieldDescriptor descriptor, final String camelCaseName,
1482          final Class<? extends GeneratedMessage> messageClass,
1483          final Class<? extends Builder> builderClass) {
1484        getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
1485        getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName);
1486        type = getMethod.getReturnType();
1487        setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
1488        hasMethod =
1489            getMethodOrDie(messageClass, "has" + camelCaseName);
1490        hasMethodBuilder =
1491            getMethodOrDie(builderClass, "has" + camelCaseName);
1492        clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
1493      }
1494
1495      // Note:  We use Java reflection to call public methods rather than
1496      //   access private fields directly as this avoids runtime security
1497      //   checks.
1498      protected final Class<?> type;
1499      protected final Method getMethod;
1500      protected final Method getMethodBuilder;
1501      protected final Method setMethod;
1502      protected final Method hasMethod;
1503      protected final Method hasMethodBuilder;
1504      protected final Method clearMethod;
1505
1506      public Object get(final GeneratedMessage message) {
1507        return invokeOrDie(getMethod, message);
1508      }
1509      public Object get(GeneratedMessage.Builder builder) {
1510        return invokeOrDie(getMethodBuilder, builder);
1511      }
1512      public void set(final Builder builder, final Object value) {
1513        invokeOrDie(setMethod, builder, value);
1514      }
1515      public Object getRepeated(final GeneratedMessage message,
1516                                final int index) {
1517        throw new UnsupportedOperationException(
1518          "getRepeatedField() called on a singular field.");
1519      }
1520      public Object getRepeated(GeneratedMessage.Builder builder, int index) {
1521        throw new UnsupportedOperationException(
1522          "getRepeatedField() called on a singular field.");
1523      }
1524      public void setRepeated(final Builder builder,
1525                              final int index, final Object value) {
1526        throw new UnsupportedOperationException(
1527          "setRepeatedField() called on a singular field.");
1528      }
1529      public void addRepeated(final Builder builder, final Object value) {
1530        throw new UnsupportedOperationException(
1531          "addRepeatedField() called on a singular field.");
1532      }
1533      public boolean has(final GeneratedMessage message) {
1534        return (Boolean) invokeOrDie(hasMethod, message);
1535      }
1536      public boolean has(GeneratedMessage.Builder builder) {
1537        return (Boolean) invokeOrDie(hasMethodBuilder, builder);
1538      }
1539      public int getRepeatedCount(final GeneratedMessage message) {
1540        throw new UnsupportedOperationException(
1541          "getRepeatedFieldSize() called on a singular field.");
1542      }
1543      public int getRepeatedCount(GeneratedMessage.Builder builder) {
1544        throw new UnsupportedOperationException(
1545          "getRepeatedFieldSize() called on a singular field.");
1546      }
1547      public void clear(final Builder builder) {
1548        invokeOrDie(clearMethod, builder);
1549      }
1550      public Message.Builder newBuilder() {
1551        throw new UnsupportedOperationException(
1552          "newBuilderForField() called on a non-Message type.");
1553      }
1554    }
1555
1556    private static class RepeatedFieldAccessor implements FieldAccessor {
1557      protected final Class type;
1558      protected final Method getMethod;
1559      protected final Method getMethodBuilder;
1560      protected final Method getRepeatedMethod;
1561      protected final Method getRepeatedMethodBuilder;
1562      protected final Method setRepeatedMethod;
1563      protected final Method addRepeatedMethod;
1564      protected final Method getCountMethod;
1565      protected final Method getCountMethodBuilder;
1566      protected final Method clearMethod;
1567
1568      RepeatedFieldAccessor(
1569          final FieldDescriptor descriptor, final String camelCaseName,
1570          final Class<? extends GeneratedMessage> messageClass,
1571          final Class<? extends Builder> builderClass) {
1572        getMethod = getMethodOrDie(messageClass,
1573                                   "get" + camelCaseName + "List");
1574        getMethodBuilder = getMethodOrDie(builderClass,
1575                                   "get" + camelCaseName + "List");
1576
1577
1578        getRepeatedMethod =
1579            getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
1580        getRepeatedMethodBuilder =
1581            getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
1582        type = getRepeatedMethod.getReturnType();
1583        setRepeatedMethod =
1584            getMethodOrDie(builderClass, "set" + camelCaseName,
1585                           Integer.TYPE, type);
1586        addRepeatedMethod =
1587            getMethodOrDie(builderClass, "add" + camelCaseName, type);
1588        getCountMethod =
1589            getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
1590        getCountMethodBuilder =
1591            getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
1592
1593        clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
1594      }
1595
1596      public Object get(final GeneratedMessage message) {
1597        return invokeOrDie(getMethod, message);
1598      }
1599      public Object get(GeneratedMessage.Builder builder) {
1600        return invokeOrDie(getMethodBuilder, builder);
1601      }
1602      public void set(final Builder builder, final Object value) {
1603        // Add all the elements individually.  This serves two purposes:
1604        // 1) Verifies that each element has the correct type.
1605        // 2) Insures that the caller cannot modify the list later on and
1606        //    have the modifications be reflected in the message.
1607        clear(builder);
1608        for (final Object element : (List<?>) value) {
1609          addRepeated(builder, element);
1610        }
1611      }
1612      public Object getRepeated(final GeneratedMessage message,
1613                                final int index) {
1614        return invokeOrDie(getRepeatedMethod, message, index);
1615      }
1616      public Object getRepeated(GeneratedMessage.Builder builder, int index) {
1617        return invokeOrDie(getRepeatedMethodBuilder, builder, index);
1618      }
1619      public void setRepeated(final Builder builder,
1620                              final int index, final Object value) {
1621        invokeOrDie(setRepeatedMethod, builder, index, value);
1622      }
1623      public void addRepeated(final Builder builder, final Object value) {
1624        invokeOrDie(addRepeatedMethod, builder, value);
1625      }
1626      public boolean has(final GeneratedMessage message) {
1627        throw new UnsupportedOperationException(
1628          "hasField() called on a singular field.");
1629      }
1630      public boolean has(GeneratedMessage.Builder builder) {
1631        throw new UnsupportedOperationException(
1632          "hasField() called on a singular field.");
1633      }
1634      public int getRepeatedCount(final GeneratedMessage message) {
1635        return (Integer) invokeOrDie(getCountMethod, message);
1636      }
1637      public int getRepeatedCount(GeneratedMessage.Builder builder) {
1638        return (Integer) invokeOrDie(getCountMethodBuilder, builder);
1639      }
1640      public void clear(final Builder builder) {
1641        invokeOrDie(clearMethod, builder);
1642      }
1643      public Message.Builder newBuilder() {
1644        throw new UnsupportedOperationException(
1645          "newBuilderForField() called on a non-Message type.");
1646      }
1647    }
1648
1649    // ---------------------------------------------------------------
1650
1651    private static final class SingularEnumFieldAccessor
1652        extends SingularFieldAccessor {
1653      SingularEnumFieldAccessor(
1654          final FieldDescriptor descriptor, final String camelCaseName,
1655          final Class<? extends GeneratedMessage> messageClass,
1656          final Class<? extends Builder> builderClass) {
1657        super(descriptor, camelCaseName, messageClass, builderClass);
1658
1659        valueOfMethod = getMethodOrDie(type, "valueOf",
1660                                       EnumValueDescriptor.class);
1661        getValueDescriptorMethod =
1662          getMethodOrDie(type, "getValueDescriptor");
1663      }
1664
1665      private Method valueOfMethod;
1666      private Method getValueDescriptorMethod;
1667
1668      @Override
1669      public Object get(final GeneratedMessage message) {
1670        return invokeOrDie(getValueDescriptorMethod, super.get(message));
1671      }
1672
1673      @Override
1674      public Object get(final GeneratedMessage.Builder builder) {
1675        return invokeOrDie(getValueDescriptorMethod, super.get(builder));
1676      }
1677
1678      @Override
1679      public void set(final Builder builder, final Object value) {
1680        super.set(builder, invokeOrDie(valueOfMethod, null, value));
1681      }
1682    }
1683
1684    private static final class RepeatedEnumFieldAccessor
1685        extends RepeatedFieldAccessor {
1686      RepeatedEnumFieldAccessor(
1687          final FieldDescriptor descriptor, final String camelCaseName,
1688          final Class<? extends GeneratedMessage> messageClass,
1689          final Class<? extends Builder> builderClass) {
1690        super(descriptor, camelCaseName, messageClass, builderClass);
1691
1692        valueOfMethod = getMethodOrDie(type, "valueOf",
1693                                       EnumValueDescriptor.class);
1694        getValueDescriptorMethod =
1695          getMethodOrDie(type, "getValueDescriptor");
1696      }
1697
1698      private final Method valueOfMethod;
1699      private final Method getValueDescriptorMethod;
1700
1701      @Override
1702      @SuppressWarnings("unchecked")
1703      public Object get(final GeneratedMessage message) {
1704        final List newList = new ArrayList();
1705        for (final Object element : (List) super.get(message)) {
1706          newList.add(invokeOrDie(getValueDescriptorMethod, element));
1707        }
1708        return Collections.unmodifiableList(newList);
1709      }
1710
1711      @Override
1712      @SuppressWarnings("unchecked")
1713      public Object get(final GeneratedMessage.Builder builder) {
1714        final List newList = new ArrayList();
1715        for (final Object element : (List) super.get(builder)) {
1716          newList.add(invokeOrDie(getValueDescriptorMethod, element));
1717        }
1718        return Collections.unmodifiableList(newList);
1719      }
1720
1721      @Override
1722      public Object getRepeated(final GeneratedMessage message,
1723                                final int index) {
1724        return invokeOrDie(getValueDescriptorMethod,
1725          super.getRepeated(message, index));
1726      }
1727      @Override
1728      public Object getRepeated(final GeneratedMessage.Builder builder,
1729                                final int index) {
1730        return invokeOrDie(getValueDescriptorMethod,
1731          super.getRepeated(builder, index));
1732      }
1733      @Override
1734      public void setRepeated(final Builder builder,
1735                              final int index, final Object value) {
1736        super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
1737                          value));
1738      }
1739      @Override
1740      public void addRepeated(final Builder builder, final Object value) {
1741        super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
1742      }
1743    }
1744
1745    // ---------------------------------------------------------------
1746
1747    private static final class SingularMessageFieldAccessor
1748        extends SingularFieldAccessor {
1749      SingularMessageFieldAccessor(
1750          final FieldDescriptor descriptor, final String camelCaseName,
1751          final Class<? extends GeneratedMessage> messageClass,
1752          final Class<? extends Builder> builderClass) {
1753        super(descriptor, camelCaseName, messageClass, builderClass);
1754
1755        newBuilderMethod = getMethodOrDie(type, "newBuilder");
1756      }
1757
1758      private final Method newBuilderMethod;
1759
1760      private Object coerceType(final Object value) {
1761        if (type.isInstance(value)) {
1762          return value;
1763        } else {
1764          // The value is not the exact right message type.  However, if it
1765          // is an alternative implementation of the same type -- e.g. a
1766          // DynamicMessage -- we should accept it.  In this case we can make
1767          // a copy of the message.
1768          return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
1769                  .mergeFrom((Message) value).build();
1770        }
1771      }
1772
1773      @Override
1774      public void set(final Builder builder, final Object value) {
1775        super.set(builder, coerceType(value));
1776      }
1777      @Override
1778      public Message.Builder newBuilder() {
1779        return (Message.Builder) invokeOrDie(newBuilderMethod, null);
1780      }
1781    }
1782
1783    private static final class RepeatedMessageFieldAccessor
1784        extends RepeatedFieldAccessor {
1785      RepeatedMessageFieldAccessor(
1786          final FieldDescriptor descriptor, final String camelCaseName,
1787          final Class<? extends GeneratedMessage> messageClass,
1788          final Class<? extends Builder> builderClass) {
1789        super(descriptor, camelCaseName, messageClass, builderClass);
1790
1791        newBuilderMethod = getMethodOrDie(type, "newBuilder");
1792      }
1793
1794      private final Method newBuilderMethod;
1795
1796      private Object coerceType(final Object value) {
1797        if (type.isInstance(value)) {
1798          return value;
1799        } else {
1800          // The value is not the exact right message type.  However, if it
1801          // is an alternative implementation of the same type -- e.g. a
1802          // DynamicMessage -- we should accept it.  In this case we can make
1803          // a copy of the message.
1804          return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
1805                  .mergeFrom((Message) value).build();
1806        }
1807      }
1808
1809      @Override
1810      public void setRepeated(final Builder builder,
1811                              final int index, final Object value) {
1812        super.setRepeated(builder, index, coerceType(value));
1813      }
1814      @Override
1815      public void addRepeated(final Builder builder, final Object value) {
1816        super.addRepeated(builder, coerceType(value));
1817      }
1818      @Override
1819      public Message.Builder newBuilder() {
1820        return (Message.Builder) invokeOrDie(newBuilderMethod, null);
1821      }
1822    }
1823  }
1824
1825  /**
1826   * Replaces this object in the output stream with a serialized form.
1827   * Part of Java's serialization magic.  Generated sub-classes must override
1828   * this method by calling <code>return super.writeReplace();</code>
1829   * @return a SerializedForm of this message
1830   */
1831  protected Object writeReplace() throws ObjectStreamException {
1832    return new GeneratedMessageLite.SerializedForm(this);
1833  }
1834}
Note: See TracBrowser for help on using the repository browser.