• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
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.ArrayList;
39 import java.util.Collections;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 
44 /**
45  * Lite version of {@link GeneratedMessage}.
46  *
47  * @author kenton@google.com Kenton Varda
48  */
49 public abstract class GeneratedMessageLite extends AbstractMessageLite
50     implements Serializable {
51   private static final long serialVersionUID = 1L;
52 
GeneratedMessageLite()53   protected GeneratedMessageLite() {
54   }
55 
GeneratedMessageLite(Builder builder)56   protected GeneratedMessageLite(Builder builder) {
57   }
58 
getParserForType()59   public Parser<? extends MessageLite> getParserForType() {
60     throw new UnsupportedOperationException(
61         "This is supposed to be overridden by subclasses.");
62   }
63 
64   /**
65    * Called by subclasses to parse an unknown field.
66    * @return {@code true} unless the tag is an end-group tag.
67    */
parseUnknownField( CodedInputStream input, CodedOutputStream unknownFieldsCodedOutput, ExtensionRegistryLite extensionRegistry, int tag)68   protected boolean parseUnknownField(
69       CodedInputStream input,
70       CodedOutputStream unknownFieldsCodedOutput,
71       ExtensionRegistryLite extensionRegistry,
72       int tag) throws IOException {
73     return input.skipField(tag, unknownFieldsCodedOutput);
74   }
75 
76   /**
77    * Used by parsing constructors in generated classes.
78    */
makeExtensionsImmutable()79   protected void makeExtensionsImmutable() {
80     // Noop for messages without extensions.
81   }
82 
83   @SuppressWarnings("unchecked")
84   public abstract static class Builder<MessageType extends GeneratedMessageLite,
85                                        BuilderType extends Builder>
86       extends AbstractMessageLite.Builder<BuilderType> {
Builder()87     protected Builder() {}
88 
89     //@Override (Java 1.6 override semantics, but we must support 1.5)
clear()90     public BuilderType clear() {
91       unknownFields = ByteString.EMPTY;
92       return (BuilderType) this;
93     }
94 
95     // This is implemented here only to work around an apparent bug in the
96     // Java compiler and/or build system.  See bug #1898463.  The mere presence
97     // of this dummy clone() implementation makes it go away.
98     @Override
clone()99     public BuilderType clone() {
100       throw new UnsupportedOperationException(
101           "This is supposed to be overridden by subclasses.");
102     }
103 
104     /** All subclasses implement this. */
mergeFrom(MessageType message)105     public abstract BuilderType mergeFrom(MessageType message);
106 
107     // Defined here for return type covariance.
getDefaultInstanceForType()108     public abstract MessageType getDefaultInstanceForType();
109 
110     /**
111      * Called by subclasses to parse an unknown field.
112      * @return {@code true} unless the tag is an end-group tag.
113      */
parseUnknownField( CodedInputStream input, CodedOutputStream unknownFieldsCodedOutput, ExtensionRegistryLite extensionRegistry, int tag)114     protected boolean parseUnknownField(
115         CodedInputStream input,
116         CodedOutputStream unknownFieldsCodedOutput,
117         ExtensionRegistryLite extensionRegistry,
118         int tag) throws IOException {
119       return input.skipField(tag, unknownFieldsCodedOutput);
120     }
121 
getUnknownFields()122     public final ByteString getUnknownFields() {
123       return unknownFields;
124     }
125 
setUnknownFields(final ByteString unknownFields)126     public final BuilderType setUnknownFields(final ByteString unknownFields) {
127       this.unknownFields = unknownFields;
128       return (BuilderType) this;
129     }
130 
131     private ByteString unknownFields = ByteString.EMPTY;
132   }
133 
134 
135   // =================================================================
136   // Extensions-related stuff
137 
138   /**
139    * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
140    */
141   public interface ExtendableMessageOrBuilder<
142       MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
143 
144     /** Check if a singular extension is present. */
hasExtension( GeneratedExtension<MessageType, Type> extension)145     <Type> boolean hasExtension(
146         GeneratedExtension<MessageType, Type> extension);
147 
148     /** Get the number of elements in a repeated extension. */
getExtensionCount( GeneratedExtension<MessageType, List<Type>> extension)149     <Type> int getExtensionCount(
150         GeneratedExtension<MessageType, List<Type>> extension);
151 
152     /** Get the value of an extension. */
getExtension(GeneratedExtension<MessageType, Type> extension)153     <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
154 
155     /** Get one element of a repeated extension. */
getExtension( GeneratedExtension<MessageType, List<Type>> extension, int index)156     <Type> Type getExtension(
157         GeneratedExtension<MessageType, List<Type>> extension,
158         int index);
159   }
160 
161   /**
162    * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
163    */
164   public abstract static class ExtendableMessage<
165         MessageType extends ExtendableMessage<MessageType>>
166       extends GeneratedMessageLite
167       implements ExtendableMessageOrBuilder<MessageType> {
168 
169     private final FieldSet<ExtensionDescriptor> extensions;
170 
ExtendableMessage()171     protected ExtendableMessage() {
172       this.extensions = FieldSet.newFieldSet();
173     }
174 
ExtendableMessage(ExtendableBuilder<MessageType, ?> builder)175     protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
176       this.extensions = builder.buildExtensions();
177     }
178 
verifyExtensionContainingType( final GeneratedExtension<MessageType, ?> extension)179     private void verifyExtensionContainingType(
180         final GeneratedExtension<MessageType, ?> extension) {
181       if (extension.getContainingTypeDefaultInstance() !=
182           getDefaultInstanceForType()) {
183         // This can only happen if someone uses unchecked operations.
184         throw new IllegalArgumentException(
185           "This extension is for a different message type.  Please make " +
186           "sure that you are not suppressing any generics type warnings.");
187       }
188     }
189 
190     /** Check if a singular extension is present. */
191     //@Override (Java 1.6 override semantics, but we must support 1.5)
hasExtension( final GeneratedExtension<MessageType, Type> extension)192     public final <Type> boolean hasExtension(
193         final GeneratedExtension<MessageType, Type> extension) {
194       verifyExtensionContainingType(extension);
195       return extensions.hasField(extension.descriptor);
196     }
197 
198     /** Get the number of elements in a repeated extension. */
199     //@Override (Java 1.6 override semantics, but we must support 1.5)
getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)200     public final <Type> int getExtensionCount(
201         final GeneratedExtension<MessageType, List<Type>> extension) {
202       verifyExtensionContainingType(extension);
203       return extensions.getRepeatedFieldCount(extension.descriptor);
204     }
205 
206     /** Get the value of an extension. */
207     //@Override (Java 1.6 override semantics, but we must support 1.5)
208     @SuppressWarnings("unchecked")
getExtension( final GeneratedExtension<MessageType, Type> extension)209     public final <Type> Type getExtension(
210         final GeneratedExtension<MessageType, Type> extension) {
211       verifyExtensionContainingType(extension);
212       final Object value = extensions.getField(extension.descriptor);
213       if (value == null) {
214         return extension.defaultValue;
215       } else {
216         return (Type) extension.fromFieldSetType(value);
217       }
218     }
219 
220     /** Get one element of a repeated extension. */
221     //@Override (Java 1.6 override semantics, but we must support 1.5)
222     @SuppressWarnings("unchecked")
getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)223     public final <Type> Type getExtension(
224         final GeneratedExtension<MessageType, List<Type>> extension,
225         final int index) {
226       verifyExtensionContainingType(extension);
227       return (Type) extension.singularFromFieldSetType(
228           extensions.getRepeatedField(extension.descriptor, index));
229     }
230 
231     /** Called by subclasses to check if all extensions are initialized. */
extensionsAreInitialized()232     protected boolean extensionsAreInitialized() {
233       return extensions.isInitialized();
234     }
235 
236     /**
237      * Called by subclasses to parse an unknown field or an extension.
238      * @return {@code true} unless the tag is an end-group tag.
239      */
240     @Override
parseUnknownField( CodedInputStream input, CodedOutputStream unknownFieldsCodedOutput, ExtensionRegistryLite extensionRegistry, int tag)241     protected boolean parseUnknownField(
242         CodedInputStream input,
243         CodedOutputStream unknownFieldsCodedOutput,
244         ExtensionRegistryLite extensionRegistry,
245         int tag) throws IOException {
246       return GeneratedMessageLite.parseUnknownField(
247           extensions,
248           getDefaultInstanceForType(),
249           input,
250           unknownFieldsCodedOutput,
251           extensionRegistry,
252           tag);
253     }
254 
255 
256     /**
257      * Used by parsing constructors in generated classes.
258      */
259     @Override
makeExtensionsImmutable()260     protected void makeExtensionsImmutable() {
261       extensions.makeImmutable();
262     }
263 
264     /**
265      * Used by subclasses to serialize extensions.  Extension ranges may be
266      * interleaved with field numbers, but we must write them in canonical
267      * (sorted by field number) order.  ExtensionWriter helps us write
268      * individual ranges of extensions at once.
269      */
270     protected class ExtensionWriter {
271       // Imagine how much simpler this code would be if Java iterators had
272       // a way to get the next element without advancing the iterator.
273 
274       private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
275             extensions.iterator();
276       private Map.Entry<ExtensionDescriptor, Object> next;
277       private final boolean messageSetWireFormat;
278 
ExtensionWriter(boolean messageSetWireFormat)279       private ExtensionWriter(boolean messageSetWireFormat) {
280         if (iter.hasNext()) {
281           next = iter.next();
282         }
283         this.messageSetWireFormat = messageSetWireFormat;
284       }
285 
writeUntil(final int end, final CodedOutputStream output)286       public void writeUntil(final int end, final CodedOutputStream output)
287                              throws IOException {
288         while (next != null && next.getKey().getNumber() < end) {
289           ExtensionDescriptor extension = next.getKey();
290           if (messageSetWireFormat && extension.getLiteJavaType() ==
291                   WireFormat.JavaType.MESSAGE &&
292               !extension.isRepeated()) {
293             output.writeMessageSetExtension(extension.getNumber(),
294                                             (MessageLite) next.getValue());
295           } else {
296             FieldSet.writeField(extension, next.getValue(), output);
297           }
298           if (iter.hasNext()) {
299             next = iter.next();
300           } else {
301             next = null;
302           }
303         }
304       }
305     }
306 
newExtensionWriter()307     protected ExtensionWriter newExtensionWriter() {
308       return new ExtensionWriter(false);
309     }
newMessageSetExtensionWriter()310     protected ExtensionWriter newMessageSetExtensionWriter() {
311       return new ExtensionWriter(true);
312     }
313 
314     /** Called by subclasses to compute the size of extensions. */
extensionsSerializedSize()315     protected int extensionsSerializedSize() {
316       return extensions.getSerializedSize();
317     }
extensionsSerializedSizeAsMessageSet()318     protected int extensionsSerializedSizeAsMessageSet() {
319       return extensions.getMessageSetSerializedSize();
320     }
321   }
322 
323   /**
324    * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
325    */
326   @SuppressWarnings("unchecked")
327   public abstract static class ExtendableBuilder<
328         MessageType extends ExtendableMessage<MessageType>,
329         BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
330       extends Builder<MessageType, BuilderType>
331       implements ExtendableMessageOrBuilder<MessageType> {
ExtendableBuilder()332     protected ExtendableBuilder() {}
333 
334     private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
335     private boolean extensionsIsMutable;
336 
337     // For immutable message conversion.
internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions)338     void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
339       this.extensions = extensions;
340     }
341 
342     @Override
clear()343     public BuilderType clear() {
344       extensions.clear();
345       extensionsIsMutable = false;
346       return super.clear();
347     }
348 
ensureExtensionsIsMutable()349     private void ensureExtensionsIsMutable() {
350       if (!extensionsIsMutable) {
351         extensions = extensions.clone();
352         extensionsIsMutable = true;
353       }
354     }
355 
356     /**
357      * Called by the build code path to create a copy of the extensions for
358      * building the message.
359      */
buildExtensions()360     private FieldSet<ExtensionDescriptor> buildExtensions() {
361       extensions.makeImmutable();
362       extensionsIsMutable = false;
363       return extensions;
364     }
365 
verifyExtensionContainingType( final GeneratedExtension<MessageType, ?> extension)366     private void verifyExtensionContainingType(
367         final GeneratedExtension<MessageType, ?> extension) {
368       if (extension.getContainingTypeDefaultInstance() !=
369           getDefaultInstanceForType()) {
370         // This can only happen if someone uses unchecked operations.
371         throw new IllegalArgumentException(
372           "This extension is for a different message type.  Please make " +
373           "sure that you are not suppressing any generics type warnings.");
374       }
375     }
376 
377     /** Check if a singular extension is present. */
378     //@Override (Java 1.6 override semantics, but we must support 1.5)
hasExtension( final GeneratedExtension<MessageType, Type> extension)379     public final <Type> boolean hasExtension(
380         final GeneratedExtension<MessageType, Type> extension) {
381       verifyExtensionContainingType(extension);
382       return extensions.hasField(extension.descriptor);
383     }
384 
385     /** Get the number of elements in a repeated extension. */
386     //@Override (Java 1.6 override semantics, but we must support 1.5)
getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)387     public final <Type> int getExtensionCount(
388         final GeneratedExtension<MessageType, List<Type>> extension) {
389       verifyExtensionContainingType(extension);
390       return extensions.getRepeatedFieldCount(extension.descriptor);
391     }
392 
393     /** Get the value of an extension. */
394     //@Override (Java 1.6 override semantics, but we must support 1.5)
395     @SuppressWarnings("unchecked")
getExtension( final GeneratedExtension<MessageType, Type> extension)396     public final <Type> Type getExtension(
397         final GeneratedExtension<MessageType, Type> extension) {
398       verifyExtensionContainingType(extension);
399       final Object value = extensions.getField(extension.descriptor);
400       if (value == null) {
401         return extension.defaultValue;
402       } else {
403         return (Type) extension.fromFieldSetType(value);
404       }
405     }
406 
407     /** Get one element of a repeated extension. */
408     @SuppressWarnings("unchecked")
409     //@Override (Java 1.6 override semantics, but we must support 1.5)
getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)410     public final <Type> Type getExtension(
411         final GeneratedExtension<MessageType, List<Type>> extension,
412         final int index) {
413       verifyExtensionContainingType(extension);
414       return (Type) extension.singularFromFieldSetType(
415           extensions.getRepeatedField(extension.descriptor, index));
416     }
417 
418     // This is implemented here only to work around an apparent bug in the
419     // Java compiler and/or build system.  See bug #1898463.  The mere presence
420     // of this dummy clone() implementation makes it go away.
421     @Override
clone()422     public BuilderType clone() {
423       throw new UnsupportedOperationException(
424           "This is supposed to be overridden by subclasses.");
425     }
426 
427     /** Set the value of an extension. */
setExtension( final GeneratedExtension<MessageType, Type> extension, final Type value)428     public final <Type> BuilderType setExtension(
429         final GeneratedExtension<MessageType, Type> extension,
430         final Type value) {
431       verifyExtensionContainingType(extension);
432       ensureExtensionsIsMutable();
433       extensions.setField(extension.descriptor,
434                           extension.toFieldSetType(value));
435       return (BuilderType) this;
436     }
437 
438     /** Set the value of one element of a repeated extension. */
setExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index, final Type value)439     public final <Type> BuilderType setExtension(
440         final GeneratedExtension<MessageType, List<Type>> extension,
441         final int index, final Type value) {
442       verifyExtensionContainingType(extension);
443       ensureExtensionsIsMutable();
444       extensions.setRepeatedField(extension.descriptor, index,
445                                   extension.singularToFieldSetType(value));
446       return (BuilderType) this;
447     }
448 
449     /** Append a value to a repeated extension. */
addExtension( final GeneratedExtension<MessageType, List<Type>> extension, final Type value)450     public final <Type> BuilderType addExtension(
451         final GeneratedExtension<MessageType, List<Type>> extension,
452         final Type value) {
453       verifyExtensionContainingType(extension);
454       ensureExtensionsIsMutable();
455       extensions.addRepeatedField(extension.descriptor,
456                                   extension.singularToFieldSetType(value));
457       return (BuilderType) this;
458     }
459 
460     /** Clear an extension. */
clearExtension( final GeneratedExtension<MessageType, ?> extension)461     public final <Type> BuilderType clearExtension(
462         final GeneratedExtension<MessageType, ?> extension) {
463       verifyExtensionContainingType(extension);
464       ensureExtensionsIsMutable();
465       extensions.clearField(extension.descriptor);
466       return (BuilderType) this;
467     }
468 
469     /** Called by subclasses to check if all extensions are initialized. */
extensionsAreInitialized()470     protected boolean extensionsAreInitialized() {
471       return extensions.isInitialized();
472     }
473 
474     /**
475      * Called by subclasses to parse an unknown field or an extension.
476      * @return {@code true} unless the tag is an end-group tag.
477      */
478     @Override
parseUnknownField( CodedInputStream input, CodedOutputStream unknownFieldsCodedOutput, ExtensionRegistryLite extensionRegistry, int tag)479     protected boolean parseUnknownField(
480         CodedInputStream input,
481         CodedOutputStream unknownFieldsCodedOutput,
482         ExtensionRegistryLite extensionRegistry,
483         int tag) throws IOException {
484       ensureExtensionsIsMutable();
485       return GeneratedMessageLite.parseUnknownField(
486           extensions,
487           getDefaultInstanceForType(),
488           input,
489           unknownFieldsCodedOutput,
490           extensionRegistry,
491           tag);
492     }
493 
mergeExtensionFields(final MessageType other)494     protected final void mergeExtensionFields(final MessageType other) {
495       ensureExtensionsIsMutable();
496       extensions.mergeFrom(((ExtendableMessage) other).extensions);
497     }
498   }
499 
500   // -----------------------------------------------------------------
501 
502   /**
503    * Parse an unknown field or an extension.
504    * @return {@code true} unless the tag is an end-group tag.
505    */
506   private static <MessageType extends MessageLite>
parseUnknownField( FieldSet<ExtensionDescriptor> extensions, MessageType defaultInstance, CodedInputStream input, CodedOutputStream unknownFieldsCodedOutput, ExtensionRegistryLite extensionRegistry, int tag)507       boolean parseUnknownField(
508           FieldSet<ExtensionDescriptor> extensions,
509           MessageType defaultInstance,
510           CodedInputStream input,
511           CodedOutputStream unknownFieldsCodedOutput,
512           ExtensionRegistryLite extensionRegistry,
513           int tag) throws IOException {
514     int wireType = WireFormat.getTagWireType(tag);
515     int fieldNumber = WireFormat.getTagFieldNumber(tag);
516 
517     GeneratedExtension<MessageType, ?> extension =
518       extensionRegistry.findLiteExtensionByNumber(
519           defaultInstance, fieldNumber);
520 
521     boolean unknown = false;
522     boolean packed = false;
523     if (extension == null) {
524       unknown = true;  // Unknown field.
525     } else if (wireType == FieldSet.getWireFormatForFieldType(
526                  extension.descriptor.getLiteType(),
527                  false  /* isPacked */)) {
528       packed = false;  // Normal, unpacked value.
529     } else if (extension.descriptor.isRepeated &&
530                extension.descriptor.type.isPackable() &&
531                wireType == FieldSet.getWireFormatForFieldType(
532                  extension.descriptor.getLiteType(),
533                  true  /* isPacked */)) {
534       packed = true;  // Packed value.
535     } else {
536       unknown = true;  // Wrong wire type.
537     }
538 
539     if (unknown) {  // Unknown field or wrong wire type.  Skip.
540       return input.skipField(tag, unknownFieldsCodedOutput);
541     }
542 
543     if (packed) {
544       int length = input.readRawVarint32();
545       int limit = input.pushLimit(length);
546       if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
547         while (input.getBytesUntilLimit() > 0) {
548           int rawValue = input.readEnum();
549           Object value =
550               extension.descriptor.getEnumType().findValueByNumber(rawValue);
551           if (value == null) {
552             // If the number isn't recognized as a valid value for this
553             // enum, drop it (don't even add it to unknownFields).
554             return true;
555           }
556           extensions.addRepeatedField(extension.descriptor,
557                                       extension.singularToFieldSetType(value));
558         }
559       } else {
560         while (input.getBytesUntilLimit() > 0) {
561           Object value =
562               FieldSet.readPrimitiveField(input,
563                                           extension.descriptor.getLiteType(),
564                                           /*checkUtf8=*/ false);
565           extensions.addRepeatedField(extension.descriptor, value);
566         }
567       }
568       input.popLimit(limit);
569     } else {
570       Object value;
571       switch (extension.descriptor.getLiteJavaType()) {
572         case MESSAGE: {
573           MessageLite.Builder subBuilder = null;
574           if (!extension.descriptor.isRepeated()) {
575             MessageLite existingValue =
576                 (MessageLite) extensions.getField(extension.descriptor);
577             if (existingValue != null) {
578               subBuilder = existingValue.toBuilder();
579             }
580           }
581           if (subBuilder == null) {
582             subBuilder = extension.getMessageDefaultInstance()
583                 .newBuilderForType();
584           }
585           if (extension.descriptor.getLiteType() ==
586               WireFormat.FieldType.GROUP) {
587             input.readGroup(extension.getNumber(),
588                             subBuilder, extensionRegistry);
589           } else {
590             input.readMessage(subBuilder, extensionRegistry);
591           }
592           value = subBuilder.build();
593           break;
594         }
595         case ENUM:
596           int rawValue = input.readEnum();
597           value = extension.descriptor.getEnumType()
598                            .findValueByNumber(rawValue);
599           // If the number isn't recognized as a valid value for this enum,
600           // write it to unknown fields object.
601           if (value == null) {
602             unknownFieldsCodedOutput.writeRawVarint32(tag);
603             unknownFieldsCodedOutput.writeUInt32NoTag(rawValue);
604             return true;
605           }
606           break;
607         default:
608           value = FieldSet.readPrimitiveField(input,
609               extension.descriptor.getLiteType(),
610               /*checkUtf8=*/ false);
611           break;
612       }
613 
614       if (extension.descriptor.isRepeated()) {
615         extensions.addRepeatedField(extension.descriptor,
616                                     extension.singularToFieldSetType(value));
617       } else {
618         extensions.setField(extension.descriptor,
619                             extension.singularToFieldSetType(value));
620       }
621     }
622 
623     return true;
624   }
625 
626   // -----------------------------------------------------------------
627 
628   /** For use by generated code only. */
629   public static <ContainingType extends MessageLite, Type>
630       GeneratedExtension<ContainingType, Type>
newSingularGeneratedExtension( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final Class singularType)631           newSingularGeneratedExtension(
632               final ContainingType containingTypeDefaultInstance,
633               final Type defaultValue,
634               final MessageLite messageDefaultInstance,
635               final Internal.EnumLiteMap<?> enumTypeMap,
636               final int number,
637               final WireFormat.FieldType type,
638               final Class singularType) {
639     return new GeneratedExtension<ContainingType, Type>(
640         containingTypeDefaultInstance,
641         defaultValue,
642         messageDefaultInstance,
643         new ExtensionDescriptor(enumTypeMap, number, type,
644                                 false /* isRepeated */,
645                                 false /* isPacked */),
646         singularType);
647   }
648 
649   /** For use by generated code only. */
650   public static <ContainingType extends MessageLite, Type>
651       GeneratedExtension<ContainingType, Type>
newRepeatedGeneratedExtension( final ContainingType containingTypeDefaultInstance, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isPacked, final Class singularType)652           newRepeatedGeneratedExtension(
653               final ContainingType containingTypeDefaultInstance,
654               final MessageLite messageDefaultInstance,
655               final Internal.EnumLiteMap<?> enumTypeMap,
656               final int number,
657               final WireFormat.FieldType type,
658               final boolean isPacked,
659               final Class singularType) {
660     @SuppressWarnings("unchecked")  // Subclasses ensure Type is a List
661     Type emptyList = (Type) Collections.emptyList();
662     return new GeneratedExtension<ContainingType, Type>(
663         containingTypeDefaultInstance,
664         emptyList,
665         messageDefaultInstance,
666         new ExtensionDescriptor(
667             enumTypeMap, number, type, true /* isRepeated */, isPacked),
668         singularType);
669   }
670 
671   static final class ExtensionDescriptor
672       implements FieldSet.FieldDescriptorLite<
673         ExtensionDescriptor> {
ExtensionDescriptor( final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isRepeated, final boolean isPacked)674     ExtensionDescriptor(
675         final Internal.EnumLiteMap<?> enumTypeMap,
676         final int number,
677         final WireFormat.FieldType type,
678         final boolean isRepeated,
679         final boolean isPacked) {
680       this.enumTypeMap = enumTypeMap;
681       this.number = number;
682       this.type = type;
683       this.isRepeated = isRepeated;
684       this.isPacked = isPacked;
685     }
686 
687     final Internal.EnumLiteMap<?> enumTypeMap;
688     final int number;
689     final WireFormat.FieldType type;
690     final boolean isRepeated;
691     final boolean isPacked;
692 
getNumber()693     public int getNumber() {
694       return number;
695     }
696 
getLiteType()697     public WireFormat.FieldType getLiteType() {
698       return type;
699     }
700 
getLiteJavaType()701     public WireFormat.JavaType getLiteJavaType() {
702       return type.getJavaType();
703     }
704 
isRepeated()705     public boolean isRepeated() {
706       return isRepeated;
707     }
708 
isPacked()709     public boolean isPacked() {
710       return isPacked;
711     }
712 
getEnumType()713     public Internal.EnumLiteMap<?> getEnumType() {
714       return enumTypeMap;
715     }
716 
717     @SuppressWarnings("unchecked")
internalMergeFrom( MessageLite.Builder to, MessageLite from)718     public MessageLite.Builder internalMergeFrom(
719         MessageLite.Builder to, MessageLite from) {
720       return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
721     }
722 
723 
compareTo(ExtensionDescriptor other)724     public int compareTo(ExtensionDescriptor other) {
725       return number - other.number;
726     }
727   }
728 
729   // =================================================================
730 
731   /** Calls Class.getMethod and throws a RuntimeException if it fails. */
732   @SuppressWarnings("unchecked")
getMethodOrDie(Class clazz, String name, Class... params)733   static Method getMethodOrDie(Class clazz, String name, Class... params) {
734     try {
735       return clazz.getMethod(name, params);
736     } catch (NoSuchMethodException e) {
737       throw new RuntimeException(
738         "Generated message class \"" + clazz.getName() +
739         "\" missing method \"" + name + "\".", e);
740     }
741   }
742 
743   /** Calls invoke and throws a RuntimeException if it fails. */
invokeOrDie(Method method, Object object, Object... params)744   static Object invokeOrDie(Method method, Object object, Object... params) {
745     try {
746       return method.invoke(object, params);
747     } catch (IllegalAccessException e) {
748       throw new RuntimeException(
749         "Couldn't use Java reflection to implement protocol message " +
750         "reflection.", e);
751     } catch (InvocationTargetException e) {
752       final Throwable cause = e.getCause();
753       if (cause instanceof RuntimeException) {
754         throw (RuntimeException) cause;
755       } else if (cause instanceof Error) {
756         throw (Error) cause;
757       } else {
758         throw new RuntimeException(
759           "Unexpected exception thrown by generated accessor method.", cause);
760       }
761     }
762   }
763 
764   /**
765    * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
766    *
767    * Users should ignore the contents of this class and only use objects of
768    * this type as parameters to extension accessors and ExtensionRegistry.add().
769    */
770   public static class GeneratedExtension<
771       ContainingType extends MessageLite, Type> {
772 
773     /**
774      * Create a new isntance with the given parameters.
775      *
776      * The last parameter {@code singularType} is only needed for enum types.
777      * We store integer values for enum types in a {@link ExtendableMessage}
778      * and use Java reflection to convert an integer value back into a concrete
779      * enum object.
780      */
GeneratedExtension( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final ExtensionDescriptor descriptor, Class singularType)781     GeneratedExtension(
782         final ContainingType containingTypeDefaultInstance,
783         final Type defaultValue,
784         final MessageLite messageDefaultInstance,
785         final ExtensionDescriptor descriptor,
786         Class singularType) {
787       // Defensive checks to verify the correct initialization order of
788       // GeneratedExtensions and their related GeneratedMessages.
789       if (containingTypeDefaultInstance == null) {
790         throw new IllegalArgumentException(
791             "Null containingTypeDefaultInstance");
792       }
793       if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
794           messageDefaultInstance == null) {
795         throw new IllegalArgumentException(
796             "Null messageDefaultInstance");
797       }
798       this.containingTypeDefaultInstance = containingTypeDefaultInstance;
799       this.defaultValue = defaultValue;
800       this.messageDefaultInstance = messageDefaultInstance;
801       this.descriptor = descriptor;
802 
803       // Use Java reflection to invoke the static method {@code valueOf} of
804       // enum types in order to convert integers to concrete enum objects.
805       this.singularType = singularType;
806       if (Internal.EnumLite.class.isAssignableFrom(singularType)) {
807         this.enumValueOf = getMethodOrDie(
808             singularType, "valueOf", int.class);
809       } else {
810         this.enumValueOf = null;
811       }
812     }
813 
814     final ContainingType containingTypeDefaultInstance;
815     final Type defaultValue;
816     final MessageLite messageDefaultInstance;
817     final ExtensionDescriptor descriptor;
818     final Class singularType;
819     final Method enumValueOf;
820 
821     /**
822      * Default instance of the type being extended, used to identify that type.
823      */
getContainingTypeDefaultInstance()824     public ContainingType getContainingTypeDefaultInstance() {
825       return containingTypeDefaultInstance;
826     }
827 
828     /** Get the field number. */
getNumber()829     public int getNumber() {
830       return descriptor.getNumber();
831     }
832 
833 
834     /**
835      * If the extension is an embedded message or group, returns the default
836      * instance of the message.
837      */
getMessageDefaultInstance()838     public MessageLite getMessageDefaultInstance() {
839       return messageDefaultInstance;
840     }
841 
842     @SuppressWarnings("unchecked")
fromFieldSetType(final Object value)843     Object fromFieldSetType(final Object value) {
844       if (descriptor.isRepeated()) {
845         if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
846           final List result = new ArrayList();
847           for (final Object element : (List) value) {
848             result.add(singularFromFieldSetType(element));
849           }
850           return result;
851         } else {
852           return value;
853         }
854       } else {
855         return singularFromFieldSetType(value);
856       }
857     }
858 
singularFromFieldSetType(final Object value)859     Object singularFromFieldSetType(final Object value) {
860       if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
861         return invokeOrDie(enumValueOf, null, (Integer) value);
862       } else {
863         return value;
864       }
865     }
866 
867     @SuppressWarnings("unchecked")
toFieldSetType(final Object value)868     Object toFieldSetType(final Object value) {
869       if (descriptor.isRepeated()) {
870         if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
871           final List result = new ArrayList();
872           for (final Object element : (List) value) {
873             result.add(singularToFieldSetType(element));
874           }
875           return result;
876         } else {
877           return value;
878         }
879       } else {
880         return singularToFieldSetType(value);
881       }
882     }
883 
singularToFieldSetType(final Object value)884     Object singularToFieldSetType(final Object value) {
885       if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
886         return ((Internal.EnumLite) value).getNumber();
887       } else {
888         return value;
889       }
890     }
891   }
892 
893   /**
894    * A serialized (serializable) form of the generated message.  Stores the
895    * message as a class name and a byte array.
896    */
897   static final class SerializedForm implements Serializable {
898     private static final long serialVersionUID = 0L;
899 
900     private String messageClassName;
901     private byte[] asBytes;
902 
903     /**
904      * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
905      * @param regularForm the message to serialize
906      */
SerializedForm(MessageLite regularForm)907     SerializedForm(MessageLite regularForm) {
908       messageClassName = regularForm.getClass().getName();
909       asBytes = regularForm.toByteArray();
910     }
911 
912     /**
913      * When read from an ObjectInputStream, this method converts this object
914      * back to the regular form.  Part of Java's serialization magic.
915      * @return a GeneratedMessage of the type that was serialized
916      */
917     @SuppressWarnings("unchecked")
readResolve()918     protected Object readResolve() throws ObjectStreamException {
919       try {
920         Class messageClass = Class.forName(messageClassName);
921         Method newBuilder = messageClass.getMethod("newBuilder");
922         MessageLite.Builder builder =
923             (MessageLite.Builder) newBuilder.invoke(null);
924         builder.mergeFrom(asBytes);
925         return builder.buildPartial();
926       } catch (ClassNotFoundException e) {
927         throw new RuntimeException("Unable to find proto buffer class", e);
928       } catch (NoSuchMethodException e) {
929         throw new RuntimeException("Unable to find newBuilder method", e);
930       } catch (IllegalAccessException e) {
931         throw new RuntimeException("Unable to call newBuilder method", e);
932       } catch (InvocationTargetException e) {
933         throw new RuntimeException("Error calling newBuilder", e.getCause());
934       } catch (InvalidProtocolBufferException e) {
935         throw new RuntimeException("Unable to understand proto buffer", e);
936       }
937     }
938   }
939 
940   /**
941    * Replaces this object in the output stream with a serialized form.
942    * Part of Java's serialization magic.  Generated sub-classes must override
943    * this method by calling {@code return super.writeReplace();}
944    * @return a SerializedForm of this message
945    */
writeReplace()946   protected Object writeReplace() throws ObjectStreamException {
947     return new SerializedForm(this);
948   }
949 }
950