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