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