Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
92 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 java.io.IOException;
34
import java.io.ObjectStreamException;
35
import java.io.Serializable;
36
import java.lang.reflect.InvocationTargetException;
37
import java.lang.reflect.Method;
38
import java.util.Collections;
39
import java.util.Iterator;
40
import java.util.List;
41
import java.util.Map;
42
 
43
/**
44
 * Lite version of {@link GeneratedMessage}.
45
 *
46
 * @author kenton@google.com Kenton Varda
47
 */
48
public abstract class GeneratedMessageLite extends AbstractMessageLite
49
    implements Serializable {
50
  private static final long serialVersionUID = 1L;
51
 
52
  protected GeneratedMessageLite() {
53
  }
54
 
55
  protected GeneratedMessageLite(Builder builder) {
56
  }
57
 
58
  @SuppressWarnings("unchecked")
59
  public abstract static class Builder<MessageType extends GeneratedMessageLite,
60
                                       BuilderType extends Builder>
61
      extends AbstractMessageLite.Builder<BuilderType> {
62
    protected Builder() {}
63
 
64
    //@Override (Java 1.6 override semantics, but we must support 1.5)
65
    public BuilderType clear() {
66
      return (BuilderType) this;
67
    }
68
 
69
    // This is implemented here only to work around an apparent bug in the
70
    // Java compiler and/or build system.  See bug #1898463.  The mere presence
71
    // of this dummy clone() implementation makes it go away.
72
    @Override
73
    public BuilderType clone() {
74
      throw new UnsupportedOperationException(
75
          "This is supposed to be overridden by subclasses.");
76
    }
77
 
78
    /** All subclasses implement this. */
79
    public abstract BuilderType mergeFrom(MessageType message);
80
 
81
    // Defined here for return type covariance.
82
    public abstract MessageType getDefaultInstanceForType();
83
 
84
    /**
85
     * Called by subclasses to parse an unknown field.
86
     * @return {@code true} unless the tag is an end-group tag.
87
     */
88
    protected boolean parseUnknownField(
89
        final CodedInputStream input,
90
        final ExtensionRegistryLite extensionRegistry,
91
        final int tag) throws IOException {
92
      return input.skipField(tag);
93
    }
94
  }
95
 
96
  // =================================================================
97
  // Extensions-related stuff
98
 
99
  /**
100
   * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
101
   */
102
  public interface ExtendableMessageOrBuilder<
103
      MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
104
 
105
    /** Check if a singular extension is present. */
106
    <Type> boolean hasExtension(
107
        GeneratedExtension<MessageType, Type> extension);
108
 
109
    /** Get the number of elements in a repeated extension. */
110
    <Type> int getExtensionCount(
111
        GeneratedExtension<MessageType, List<Type>> extension);
112
 
113
    /** Get the value of an extension. */
114
    <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
115
 
116
    /** Get one element of a repeated extension. */
117
    <Type> Type getExtension(
118
        GeneratedExtension<MessageType, List<Type>> extension,
119
        int index);
120
  }
121
 
122
  /**
123
   * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
124
   */
125
  public abstract static class ExtendableMessage<
126
        MessageType extends ExtendableMessage<MessageType>>
127
      extends GeneratedMessageLite
128
      implements ExtendableMessageOrBuilder<MessageType> {
129
 
130
    private final FieldSet<ExtensionDescriptor> extensions;
131
 
132
    protected ExtendableMessage() {
133
      this.extensions = FieldSet.newFieldSet();
134
    }
135
 
136
    protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
137
      this.extensions = builder.buildExtensions();
138
    }
139
 
140
    private void verifyExtensionContainingType(
141
        final GeneratedExtension<MessageType, ?> extension) {
142
      if (extension.getContainingTypeDefaultInstance() !=
143
          getDefaultInstanceForType()) {
144
        // This can only happen if someone uses unchecked operations.
145
        throw new IllegalArgumentException(
146
          "This extension is for a different message type.  Please make " +
147
          "sure that you are not suppressing any generics type warnings.");
148
      }
149
    }
150
 
151
    /** Check if a singular extension is present. */
152
    //@Override (Java 1.6 override semantics, but we must support 1.5)
153
    public final <Type> boolean hasExtension(
154
        final GeneratedExtension<MessageType, Type> extension) {
155
      verifyExtensionContainingType(extension);
156
      return extensions.hasField(extension.descriptor);
157
    }
158
 
159
    /** Get the number of elements in a repeated extension. */
160
    //@Override (Java 1.6 override semantics, but we must support 1.5)
161
    public final <Type> int getExtensionCount(
162
        final GeneratedExtension<MessageType, List<Type>> extension) {
163
      verifyExtensionContainingType(extension);
164
      return extensions.getRepeatedFieldCount(extension.descriptor);
165
    }
166
 
167
    /** Get the value of an extension. */
168
    //@Override (Java 1.6 override semantics, but we must support 1.5)
169
    @SuppressWarnings("unchecked")
170
    public final <Type> Type getExtension(
171
        final GeneratedExtension<MessageType, Type> extension) {
172
      verifyExtensionContainingType(extension);
173
      final Object value = extensions.getField(extension.descriptor);
174
      if (value == null) {
175
        return extension.defaultValue;
176
      } else {
177
        return (Type) value;
178
      }
179
    }
180
 
181
    /** Get one element of a repeated extension. */
182
    //@Override (Java 1.6 override semantics, but we must support 1.5)
183
    @SuppressWarnings("unchecked")
184
    public final <Type> Type getExtension(
185
        final GeneratedExtension<MessageType, List<Type>> extension,
186
        final int index) {
187
      verifyExtensionContainingType(extension);
188
      return (Type) extensions.getRepeatedField(extension.descriptor, index);
189
    }
190
 
191
    /** Called by subclasses to check if all extensions are initialized. */
192
    protected boolean extensionsAreInitialized() {
193
      return extensions.isInitialized();
194
    }
195
 
196
    /**
197
     * Used by subclasses to serialize extensions.  Extension ranges may be
198
     * interleaved with field numbers, but we must write them in canonical
199
     * (sorted by field number) order.  ExtensionWriter helps us write
200
     * individual ranges of extensions at once.
201
     */
202
    protected class ExtensionWriter {
203
      // Imagine how much simpler this code would be if Java iterators had
204
      // a way to get the next element without advancing the iterator.
205
 
206
      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
207
            extensions.iterator();
208
      private Map.Entry<ExtensionDescriptor, Object> next;
209
      private final boolean messageSetWireFormat;
210
 
211
      private ExtensionWriter(boolean messageSetWireFormat) {
212
        if (iter.hasNext()) {
213
          next = iter.next();
214
        }
215
        this.messageSetWireFormat = messageSetWireFormat;
216
      }
217
 
218
      public void writeUntil(final int end, final CodedOutputStream output)
219
                             throws IOException {
220
        while (next != null && next.getKey().getNumber() < end) {
221
          ExtensionDescriptor extension = next.getKey();
222
          if (messageSetWireFormat && extension.getLiteJavaType() ==
223
                  WireFormat.JavaType.MESSAGE &&
224
              !extension.isRepeated()) {
225
            output.writeMessageSetExtension(extension.getNumber(),
226
                                            (MessageLite) next.getValue());
227
          } else {
228
            FieldSet.writeField(extension, next.getValue(), output);
229
          }
230
          if (iter.hasNext()) {
231
            next = iter.next();
232
          } else {
233
            next = null;
234
          }
235
        }
236
      }
237
    }
238
 
239
    protected ExtensionWriter newExtensionWriter() {
240
      return new ExtensionWriter(false);
241
    }
242
    protected ExtensionWriter newMessageSetExtensionWriter() {
243
      return new ExtensionWriter(true);
244
    }
245
 
246
    /** Called by subclasses to compute the size of extensions. */
247
    protected int extensionsSerializedSize() {
248
      return extensions.getSerializedSize();
249
    }
250
    protected int extensionsSerializedSizeAsMessageSet() {
251
      return extensions.getMessageSetSerializedSize();
252
    }
253
  }
254
 
255
  /**
256
   * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
257
   */
258
  @SuppressWarnings("unchecked")
259
  public abstract static class ExtendableBuilder<
260
        MessageType extends ExtendableMessage<MessageType>,
261
        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
262
      extends Builder<MessageType, BuilderType>
263
      implements ExtendableMessageOrBuilder<MessageType> {
264
    protected ExtendableBuilder() {}
265
 
266
    private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
267
    private boolean extensionsIsMutable;
268
 
269
    @Override
270
    public BuilderType clear() {
271
      extensions.clear();
272
      extensionsIsMutable = false;
273
      return super.clear();
274
    }
275
 
276
    private void ensureExtensionsIsMutable() {
277
      if (!extensionsIsMutable) {
278
        extensions = extensions.clone();
279
        extensionsIsMutable = true;
280
      }
281
    }
282
 
283
    /**
284
     * Called by the build code path to create a copy of the extensions for
285
     * building the message.
286
     */
287
    private FieldSet<ExtensionDescriptor> buildExtensions() {
288
      extensions.makeImmutable();
289
      extensionsIsMutable = false;
290
      return extensions;
291
    }
292
 
293
    private void verifyExtensionContainingType(
294
        final GeneratedExtension<MessageType, ?> extension) {
295
      if (extension.getContainingTypeDefaultInstance() !=
296
          getDefaultInstanceForType()) {
297
        // This can only happen if someone uses unchecked operations.
298
        throw new IllegalArgumentException(
299
          "This extension is for a different message type.  Please make " +
300
          "sure that you are not suppressing any generics type warnings.");
301
      }
302
    }
303
 
304
    /** Check if a singular extension is present. */
305
    //@Override (Java 1.6 override semantics, but we must support 1.5)
306
    public final <Type> boolean hasExtension(
307
        final GeneratedExtension<MessageType, Type> extension) {
308
      verifyExtensionContainingType(extension);
309
      return extensions.hasField(extension.descriptor);
310
    }
311
 
312
    /** Get the number of elements in a repeated extension. */
313
    //@Override (Java 1.6 override semantics, but we must support 1.5)
314
    public final <Type> int getExtensionCount(
315
        final GeneratedExtension<MessageType, List<Type>> extension) {
316
      verifyExtensionContainingType(extension);
317
      return extensions.getRepeatedFieldCount(extension.descriptor);
318
    }
319
 
320
    /** Get the value of an extension. */
321
    //@Override (Java 1.6 override semantics, but we must support 1.5)
322
    @SuppressWarnings("unchecked")
323
    public final <Type> Type getExtension(
324
        final GeneratedExtension<MessageType, Type> extension) {
325
      verifyExtensionContainingType(extension);
326
      final Object value = extensions.getField(extension.descriptor);
327
      if (value == null) {
328
        return extension.defaultValue;
329
      } else {
330
        return (Type) value;
331
      }
332
    }
333
 
334
    /** Get one element of a repeated extension. */
335
    @SuppressWarnings("unchecked")
336
    //@Override (Java 1.6 override semantics, but we must support 1.5)
337
    public final <Type> Type getExtension(
338
        final GeneratedExtension<MessageType, List<Type>> extension,
339
        final int index) {
340
      verifyExtensionContainingType(extension);
341
      return (Type) extensions.getRepeatedField(extension.descriptor, index);
342
    }
343
 
344
    // This is implemented here only to work around an apparent bug in the
345
    // Java compiler and/or build system.  See bug #1898463.  The mere presence
346
    // of this dummy clone() implementation makes it go away.
347
    @Override
348
    public BuilderType clone() {
349
      throw new UnsupportedOperationException(
350
          "This is supposed to be overridden by subclasses.");
351
    }
352
 
353
    /** Set the value of an extension. */
354
    public final <Type> BuilderType setExtension(
355
        final GeneratedExtension<MessageType, Type> extension,
356
        final Type value) {
357
      verifyExtensionContainingType(extension);
358
      ensureExtensionsIsMutable();
359
      extensions.setField(extension.descriptor, value);
360
      return (BuilderType) this;
361
    }
362
 
363
    /** Set the value of one element of a repeated extension. */
364
    public final <Type> BuilderType setExtension(
365
        final GeneratedExtension<MessageType, List<Type>> extension,
366
        final int index, final Type value) {
367
      verifyExtensionContainingType(extension);
368
      ensureExtensionsIsMutable();
369
      extensions.setRepeatedField(extension.descriptor, index, value);
370
      return (BuilderType) this;
371
    }
372
 
373
    /** Append a value to a repeated extension. */
374
    public final <Type> BuilderType addExtension(
375
        final GeneratedExtension<MessageType, List<Type>> extension,
376
        final Type value) {
377
      verifyExtensionContainingType(extension);
378
      ensureExtensionsIsMutable();
379
      extensions.addRepeatedField(extension.descriptor, value);
380
      return (BuilderType) this;
381
    }
382
 
383
    /** Clear an extension. */
384
    public final <Type> BuilderType clearExtension(
385
        final GeneratedExtension<MessageType, ?> extension) {
386
      verifyExtensionContainingType(extension);
387
      ensureExtensionsIsMutable();
388
      extensions.clearField(extension.descriptor);
389
      return (BuilderType) this;
390
    }
391
 
392
    /** Called by subclasses to check if all extensions are initialized. */
393
    protected boolean extensionsAreInitialized() {
394
      return extensions.isInitialized();
395
    }
396
 
397
    /**
398
     * Called by subclasses to parse an unknown field or an extension.
399
     * @return {@code true} unless the tag is an end-group tag.
400
     */
401
    @Override
402
    protected boolean parseUnknownField(
403
        final CodedInputStream input,
404
        final ExtensionRegistryLite extensionRegistry,
405
        final int tag) throws IOException {
406
      final int wireType = WireFormat.getTagWireType(tag);
407
      final int fieldNumber = WireFormat.getTagFieldNumber(tag);
408
 
409
      final GeneratedExtension<MessageType, ?> extension =
410
        extensionRegistry.findLiteExtensionByNumber(
411
            getDefaultInstanceForType(), fieldNumber);
412
 
413
      boolean unknown = false;
414
      boolean packed = false;
415
      if (extension == null) {
416
        unknown = true;  // Unknown field.
417
      } else if (wireType == FieldSet.getWireFormatForFieldType(
418
                   extension.descriptor.getLiteType(),
419
                   false  /* isPacked */)) {
420
        packed = false;  // Normal, unpacked value.
421
      } else if (extension.descriptor.isRepeated &&
422
                 extension.descriptor.type.isPackable() &&
423
                 wireType == FieldSet.getWireFormatForFieldType(
424
                   extension.descriptor.getLiteType(),
425
                   true  /* isPacked */)) {
426
        packed = true;  // Packed value.
427
      } else {
428
        unknown = true;  // Wrong wire type.
429
      }
430
 
431
      if (unknown) {  // Unknown field or wrong wire type.  Skip.
432
        return input.skipField(tag);
433
      }
434
 
435
      if (packed) {
436
        final int length = input.readRawVarint32();
437
        final int limit = input.pushLimit(length);
438
        if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
439
          while (input.getBytesUntilLimit() > 0) {
440
            final int rawValue = input.readEnum();
441
            final Object value =
442
                extension.descriptor.getEnumType().findValueByNumber(rawValue);
443
            if (value == null) {
444
              // If the number isn't recognized as a valid value for this
445
              // enum, drop it (don't even add it to unknownFields).
446
              return true;
447
            }
448
            ensureExtensionsIsMutable();
449
            extensions.addRepeatedField(extension.descriptor, value);
450
          }
451
        } else {
452
          while (input.getBytesUntilLimit() > 0) {
453
            final Object value =
454
              FieldSet.readPrimitiveField(input,
455
                                          extension.descriptor.getLiteType());
456
            ensureExtensionsIsMutable();
457
            extensions.addRepeatedField(extension.descriptor, value);
458
          }
459
        }
460
        input.popLimit(limit);
461
      } else {
462
        final Object value;
463
        switch (extension.descriptor.getLiteJavaType()) {
464
          case MESSAGE: {
465
            MessageLite.Builder subBuilder = null;
466
            if (!extension.descriptor.isRepeated()) {
467
              MessageLite existingValue =
468
                  (MessageLite) extensions.getField(extension.descriptor);
469
              if (existingValue != null) {
470
                subBuilder = existingValue.toBuilder();
471
              }
472
            }
473
            if (subBuilder == null) {
474
              subBuilder = extension.messageDefaultInstance.newBuilderForType();
475
            }
476
            if (extension.descriptor.getLiteType() ==
477
                WireFormat.FieldType.GROUP) {
478
              input.readGroup(extension.getNumber(),
479
                              subBuilder, extensionRegistry);
480
            } else {
481
              input.readMessage(subBuilder, extensionRegistry);
482
            }
483
            value = subBuilder.build();
484
            break;
485
          }
486
          case ENUM:
487
            final int rawValue = input.readEnum();
488
            value = extension.descriptor.getEnumType()
489
                             .findValueByNumber(rawValue);
490
            // If the number isn't recognized as a valid value for this enum,
491
            // drop it.
492
            if (value == null) {
493
              return true;
494
            }
495
            break;
496
          default:
497
            value = FieldSet.readPrimitiveField(input,
498
                extension.descriptor.getLiteType());
499
            break;
500
        }
501
 
502
        if (extension.descriptor.isRepeated()) {
503
          ensureExtensionsIsMutable();
504
          extensions.addRepeatedField(extension.descriptor, value);
505
        } else {
506
          ensureExtensionsIsMutable();
507
          extensions.setField(extension.descriptor, value);
508
        }
509
      }
510
 
511
      return true;
512
    }
513
 
514
    protected final void mergeExtensionFields(final MessageType other) {
515
      ensureExtensionsIsMutable();
516
      extensions.mergeFrom(((ExtendableMessage) other).extensions);
517
    }
518
  }
519
 
520
  // -----------------------------------------------------------------
521
 
522
  /** For use by generated code only. */
523
  public static <ContainingType extends MessageLite, Type>
524
      GeneratedExtension<ContainingType, Type>
525
          newSingularGeneratedExtension(
526
              final ContainingType containingTypeDefaultInstance,
527
              final Type defaultValue,
528
              final MessageLite messageDefaultInstance,
529
              final Internal.EnumLiteMap<?> enumTypeMap,
530
              final int number,
531
              final WireFormat.FieldType type) {
532
    return new GeneratedExtension<ContainingType, Type>(
533
        containingTypeDefaultInstance,
534
        defaultValue,
535
        messageDefaultInstance,
536
        new ExtensionDescriptor(enumTypeMap, number, type,
537
                                false /* isRepeated */,
538
                                false /* isPacked */));
539
  }
540
 
541
  /** For use by generated code only. */
542
  public static <ContainingType extends MessageLite, Type>
543
      GeneratedExtension<ContainingType, Type>
544
          newRepeatedGeneratedExtension(
545
              final ContainingType containingTypeDefaultInstance,
546
              final MessageLite messageDefaultInstance,
547
              final Internal.EnumLiteMap<?> enumTypeMap,
548
              final int number,
549
              final WireFormat.FieldType type,
550
              final boolean isPacked) {
551
    @SuppressWarnings("unchecked")  // Subclasses ensure Type is a List
552
    Type emptyList = (Type) Collections.emptyList();
553
    return new GeneratedExtension<ContainingType, Type>(
554
        containingTypeDefaultInstance,
555
        emptyList,
556
        messageDefaultInstance,
557
        new ExtensionDescriptor(
558
            enumTypeMap, number, type, true /* isRepeated */, isPacked));
559
  }
560
 
561
  private static final class ExtensionDescriptor
562
      implements FieldSet.FieldDescriptorLite<
563
        ExtensionDescriptor> {
564
    private ExtensionDescriptor(
565
        final Internal.EnumLiteMap<?> enumTypeMap,
566
        final int number,
567
        final WireFormat.FieldType type,
568
        final boolean isRepeated,
569
        final boolean isPacked) {
570
      this.enumTypeMap = enumTypeMap;
571
      this.number = number;
572
      this.type = type;
573
      this.isRepeated = isRepeated;
574
      this.isPacked = isPacked;
575
    }
576
 
577
    private final Internal.EnumLiteMap<?> enumTypeMap;
578
    private final int number;
579
    private final WireFormat.FieldType type;
580
    private final boolean isRepeated;
581
    private final boolean isPacked;
582
 
583
    public int getNumber() {
584
      return number;
585
    }
586
 
587
    public WireFormat.FieldType getLiteType() {
588
      return type;
589
    }
590
 
591
    public WireFormat.JavaType getLiteJavaType() {
592
      return type.getJavaType();
593
    }
594
 
595
    public boolean isRepeated() {
596
      return isRepeated;
597
    }
598
 
599
    public boolean isPacked() {
600
      return isPacked;
601
    }
602
 
603
    public Internal.EnumLiteMap<?> getEnumType() {
604
      return enumTypeMap;
605
    }
606
 
607
    @SuppressWarnings("unchecked")
608
    public MessageLite.Builder internalMergeFrom(
609
        MessageLite.Builder to, MessageLite from) {
610
      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
611
    }
612
 
613
    public int compareTo(ExtensionDescriptor other) {
614
      return number - other.number;
615
    }
616
  }
617
 
618
  /**
619
   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
620
   *
621
   * Users should ignore the contents of this class and only use objects of
622
   * this type as parameters to extension accessors and ExtensionRegistry.add().
623
   */
624
  public static final class GeneratedExtension<
625
      ContainingType extends MessageLite, Type> {
626
 
627
    private GeneratedExtension(
628
        final ContainingType containingTypeDefaultInstance,
629
        final Type defaultValue,
630
        final MessageLite messageDefaultInstance,
631
        final ExtensionDescriptor descriptor) {
632
      // Defensive checks to verify the correct initialization order of
633
      // GeneratedExtensions and their related GeneratedMessages.
634
      if (containingTypeDefaultInstance == null) {
635
        throw new IllegalArgumentException(
636
            "Null containingTypeDefaultInstance");
637
      }
638
      if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
639
          messageDefaultInstance == null) {
640
        throw new IllegalArgumentException(
641
            "Null messageDefaultInstance");
642
      }
643
      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
644
      this.defaultValue = defaultValue;
645
      this.messageDefaultInstance = messageDefaultInstance;
646
      this.descriptor = descriptor;
647
    }
648
 
649
    private final ContainingType containingTypeDefaultInstance;
650
    private final Type defaultValue;
651
    private final MessageLite messageDefaultInstance;
652
    private final ExtensionDescriptor descriptor;
653
 
654
    /**
655
     * Default instance of the type being extended, used to identify that type.
656
     */
657
    public ContainingType getContainingTypeDefaultInstance() {
658
      return containingTypeDefaultInstance;
659
    }
660
 
661
    /** Get the field number. */
662
    public int getNumber() {
663
      return descriptor.getNumber();
664
    }
665
 
666
    /**
667
     * If the extension is an embedded message, this is the default instance of
668
     * that type.
669
     */
670
    public MessageLite getMessageDefaultInstance() {
671
      return messageDefaultInstance;
672
    }
673
  }
674
 
675
  /**
676
   * A serialized (serializable) form of the generated message.  Stores the
677
   * message as a class name and a byte array.
678
   */
679
  static final class SerializedForm implements Serializable {
680
    private static final long serialVersionUID = 0L;
681
 
682
    private String messageClassName;
683
    private byte[] asBytes;
684
 
685
    /**
686
     * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
687
     * @param regularForm the message to serialize
688
     */
689
    SerializedForm(MessageLite regularForm) {
690
      messageClassName = regularForm.getClass().getName();
691
      asBytes = regularForm.toByteArray();
692
    }
693
 
694
    /**
695
     * When read from an ObjectInputStream, this method converts this object
696
     * back to the regular form.  Part of Java's serialization magic.
697
     * @return a GeneratedMessage of the type that was serialized
698
     */
699
    @SuppressWarnings("unchecked")
700
    protected Object readResolve() throws ObjectStreamException {
701
      try {
702
        Class messageClass = Class.forName(messageClassName);
703
        Method newBuilder = messageClass.getMethod("newBuilder");
704
        MessageLite.Builder builder =
705
            (MessageLite.Builder) newBuilder.invoke(null);
706
        builder.mergeFrom(asBytes);
707
        return builder.buildPartial();
708
      } catch (ClassNotFoundException e) {
709
        throw new RuntimeException("Unable to find proto buffer class", e);
710
      } catch (NoSuchMethodException e) {
711
        throw new RuntimeException("Unable to find newBuilder method", e);
712
      } catch (IllegalAccessException e) {
713
        throw new RuntimeException("Unable to call newBuilder method", e);
714
      } catch (InvocationTargetException e) {
715
        throw new RuntimeException("Error calling newBuilder", e.getCause());
716
      } catch (InvalidProtocolBufferException e) {
717
        throw new RuntimeException("Unable to understand proto buffer", e);
718
      }
719
    }
720
  }
721
 
722
  /**
723
   * Replaces this object in the output stream with a serialized form.
724
   * Part of Java's serialization magic.  Generated sub-classes must override
725
   * this method by calling <code>return super.writeReplace();</code>
726
   * @return a SerializedForm of this message
727
   */
728
  protected Object writeReplace() throws ObjectStreamException {
729
    return new SerializedForm(this);
730
  }
731
}