Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
90 Kevin 1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
// http://code.google.com/p/protobuf/
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
7
// met:
8
//
9
//     * Redistributions of source code must retain the above copyright
10
// notice, this list of conditions and the following disclaimer.
11
//     * Redistributions in binary form must reproduce the above
12
// copyright notice, this list of conditions and the following disclaimer
13
// in the documentation and/or other materials provided with the
14
// distribution.
15
//     * Neither the name of Google Inc. nor the names of its
16
// contributors may be used to endorse or promote products derived from
17
// this software without specific prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
31
package com.google.protobuf;
32
 
33
import com.google.protobuf.Descriptors.Descriptor;
34
import com.google.protobuf.Descriptors.EnumValueDescriptor;
35
import com.google.protobuf.Descriptors.FieldDescriptor;
36
 
37
import java.io.IOException;
38
import java.io.ObjectStreamException;
39
import java.io.Serializable;
40
import java.lang.reflect.InvocationTargetException;
41
import java.lang.reflect.Method;
42
import java.util.ArrayList;
43
import java.util.Collections;
44
import java.util.Iterator;
45
import java.util.List;
46
import java.util.Map;
47
import 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
 */
57
public 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
}