Home | History | Annotate | Download | only in protobuf
      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 (at) 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   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