1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 package com.google.protobuf;
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;
45 * Lite version of {@link GeneratedMessage}.
47 * @author kenton@google.com Kenton Varda
49 public abstract class GeneratedMessageLite extends AbstractMessageLite
50 implements Serializable {
51 private static final long serialVersionUID = 1L;
53 protected GeneratedMessageLite() {
56 protected GeneratedMessageLite(Builder builder) {
59 public Parser<? extends MessageLite> getParserForType() {
60 throw new UnsupportedOperationException(
61 "This is supposed to be overridden by subclasses.");
65 * Called by subclasses to parse an unknown field.
66 * @return {@code true} unless the tag is an end-group 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);
77 * Used by parsing constructors in generated classes.
79 protected void makeExtensionsImmutable() {
80 // Noop for messages without extensions.
83 @SuppressWarnings("unchecked")
84 public abstract static class Builder<MessageType extends GeneratedMessageLite,
85 BuilderType extends Builder>
86 extends AbstractMessageLite.Builder<BuilderType> {
87 protected Builder() {}
89 //@Override (Java 1.6 override semantics, but we must support 1.5)
90 public BuilderType clear() {
91 unknownFields = ByteString.EMPTY;
92 return (BuilderType) this;
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.
99 public BuilderType clone() {
100 throw new UnsupportedOperationException(
101 "This is supposed to be overridden by subclasses.");
104 /** All subclasses implement this. */
105 public abstract BuilderType mergeFrom(MessageType message);
107 // Defined here for return type covariance.
108 public abstract MessageType getDefaultInstanceForType();
111 * Called by subclasses to parse an unknown field.
112 * @return {@code true} unless the tag is an end-group 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);
122 public final ByteString getUnknownFields() {
123 return unknownFields;
126 public final BuilderType setUnknownFields(final ByteString unknownFields) {
127 this.unknownFields = unknownFields;
128 return (BuilderType) this;
131 private ByteString unknownFields = ByteString.EMPTY;
135 // =================================================================
136 // Extensions-related stuff
139 * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
141 public interface ExtendableMessageOrBuilder<
142 MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
144 /** Check if a singular extension is present. */
145 <Type> boolean hasExtension(
146 GeneratedExtension<MessageType, Type> extension);
148 /** Get the number of elements in a repeated extension. */
149 <Type> int getExtensionCount(
150 GeneratedExtension<MessageType, List<Type>> extension);
152 /** Get the value of an extension. */
153 <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
155 /** Get one element of a repeated extension. */
156 <Type> Type getExtension(
157 GeneratedExtension<MessageType, List<Type>> extension,
162 * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
164 public abstract static class ExtendableMessage<
165 MessageType extends ExtendableMessage<MessageType>>
166 extends GeneratedMessageLite
167 implements ExtendableMessageOrBuilder<MessageType> {
169 private final FieldSet<ExtensionDescriptor> extensions;
171 protected ExtendableMessage() {
172 this.extensions = FieldSet.newFieldSet();
175 protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
176 this.extensions = builder.buildExtensions();
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.");
190 /** Check if a singular extension is present. */
191 //@Override (Java 1.6 override semantics, but we must support 1.5)
192 public final <Type> boolean hasExtension(
193 final GeneratedExtension<MessageType, Type> extension) {
194 verifyExtensionContainingType(extension);
195 return extensions.hasField(extension.descriptor);
198 /** Get the number of elements in a repeated extension. */
199 //@Override (Java 1.6 override semantics, but we must support 1.5)
200 public final <Type> int getExtensionCount(
201 final GeneratedExtension<MessageType, List<Type>> extension) {
202 verifyExtensionContainingType(extension);
203 return extensions.getRepeatedFieldCount(extension.descriptor);
206 /** Get the value of an extension. */
207 //@Override (Java 1.6 override semantics, but we must support 1.5)
208 @SuppressWarnings("unchecked")
209 public final <Type> Type getExtension(
210 final GeneratedExtension<MessageType, Type> extension) {
211 verifyExtensionContainingType(extension);
212 final Object value = extensions.getField(extension.descriptor);
214 return extension.defaultValue;
216 return (Type) extension.fromFieldSetType(value);
220 /** Get one element of a repeated extension. */
221 //@Override (Java 1.6 override semantics, but we must support 1.5)
222 @SuppressWarnings("unchecked")
223 public final <Type> Type getExtension(
224 final GeneratedExtension<MessageType, List<Type>> extension,
226 verifyExtensionContainingType(extension);
227 return (Type) extension.singularFromFieldSetType(
228 extensions.getRepeatedField(extension.descriptor, index));
231 /** Called by subclasses to check if all extensions are initialized. */
232 protected boolean extensionsAreInitialized() {
233 return extensions.isInitialized();
237 * Called by subclasses to parse an unknown field or an extension.
238 * @return {@code true} unless the tag is an end-group tag.
241 protected boolean parseUnknownField(
242 CodedInputStream input,
243 CodedOutputStream unknownFieldsCodedOutput,
244 ExtensionRegistryLite extensionRegistry,
245 int tag) throws IOException {
246 return GeneratedMessageLite.parseUnknownField(
248 getDefaultInstanceForType(),
250 unknownFieldsCodedOutput,
257 * Used by parsing constructors in generated classes.
260 protected void makeExtensionsImmutable() {
261 extensions.makeImmutable();
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.
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.
274 private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
275 extensions.iterator();
276 private Map.Entry<ExtensionDescriptor, Object> next;
277 private final boolean messageSetWireFormat;
279 private ExtensionWriter(boolean messageSetWireFormat) {
280 if (iter.hasNext()) {
283 this.messageSetWireFormat = messageSetWireFormat;
286 public void writeUntil(final int end, final CodedOutputStream output)
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());
296 FieldSet.writeField(extension, next.getValue(), output);
298 if (iter.hasNext()) {
307 protected ExtensionWriter newExtensionWriter() {
308 return new ExtensionWriter(false);
310 protected ExtensionWriter newMessageSetExtensionWriter() {
311 return new ExtensionWriter(true);
314 /** Called by subclasses to compute the size of extensions. */
315 protected int extensionsSerializedSize() {
316 return extensions.getSerializedSize();
318 protected int extensionsSerializedSizeAsMessageSet() {
319 return extensions.getMessageSetSerializedSize();
324 * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
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> {
332 protected ExtendableBuilder() {}
334 private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
335 private boolean extensionsIsMutable;
337 // For immutable message conversion.
338 void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
339 this.extensions = extensions;
343 public BuilderType clear() {
345 extensionsIsMutable = false;
346 return super.clear();
349 private void ensureExtensionsIsMutable() {
350 if (!extensionsIsMutable) {
351 extensions = extensions.clone();
352 extensionsIsMutable = true;
357 * Called by the build code path to create a copy of the extensions for
358 * building the message.
360 private FieldSet<ExtensionDescriptor> buildExtensions() {
361 extensions.makeImmutable();
362 extensionsIsMutable = false;
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.");
377 /** Check if a singular extension is present. */
378 //@Override (Java 1.6 override semantics, but we must support 1.5)
379 public final <Type> boolean hasExtension(
380 final GeneratedExtension<MessageType, Type> extension) {
381 verifyExtensionContainingType(extension);
382 return extensions.hasField(extension.descriptor);
385 /** Get the number of elements in a repeated extension. */
386 //@Override (Java 1.6 override semantics, but we must support 1.5)
387 public final <Type> int getExtensionCount(
388 final GeneratedExtension<MessageType, List<Type>> extension) {
389 verifyExtensionContainingType(extension);
390 return extensions.getRepeatedFieldCount(extension.descriptor);
393 /** Get the value of an extension. */
394 //@Override (Java 1.6 override semantics, but we must support 1.5)
395 @SuppressWarnings("unchecked")
396 public final <Type> Type getExtension(
397 final GeneratedExtension<MessageType, Type> extension) {
398 verifyExtensionContainingType(extension);
399 final Object value = extensions.getField(extension.descriptor);
401 return extension.defaultValue;
403 return (Type) extension.fromFieldSetType(value);
407 /** Get one element of a repeated extension. */
408 @SuppressWarnings("unchecked")
409 //@Override (Java 1.6 override semantics, but we must support 1.5)
410 public final <Type> Type getExtension(
411 final GeneratedExtension<MessageType, List<Type>> extension,
413 verifyExtensionContainingType(extension);
414 return (Type) extension.singularFromFieldSetType(
415 extensions.getRepeatedField(extension.descriptor, index));
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.
422 public BuilderType clone() {
423 throw new UnsupportedOperationException(
424 "This is supposed to be overridden by subclasses.");
427 /** Set the value of an extension. */
428 public final <Type> BuilderType setExtension(
429 final GeneratedExtension<MessageType, Type> extension,
431 verifyExtensionContainingType(extension);
432 ensureExtensionsIsMutable();
433 extensions.setField(extension.descriptor,
434 extension.toFieldSetType(value));
435 return (BuilderType) this;
438 /** Set the value of one element of a repeated extension. */
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;
449 /** Append a value to a repeated extension. */
450 public final <Type> BuilderType addExtension(
451 final GeneratedExtension<MessageType, List<Type>> extension,
453 verifyExtensionContainingType(extension);
454 ensureExtensionsIsMutable();
455 extensions.addRepeatedField(extension.descriptor,
456 extension.singularToFieldSetType(value));
457 return (BuilderType) this;
460 /** Clear an 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;
469 /** Called by subclasses to check if all extensions are initialized. */
470 protected boolean extensionsAreInitialized() {
471 return extensions.isInitialized();
475 * Called by subclasses to parse an unknown field or an extension.
476 * @return {@code true} unless the tag is an end-group 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(
487 getDefaultInstanceForType(),
489 unknownFieldsCodedOutput,
494 protected final void mergeExtensionFields(final MessageType other) {
495 ensureExtensionsIsMutable();
496 extensions.mergeFrom(((ExtendableMessage) other).extensions);
500 // -----------------------------------------------------------------
503 * Parse an unknown field or an extension.
504 * @return {@code true} unless the tag is an end-group tag.
506 private static <MessageType extends MessageLite>
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);
517 GeneratedExtension<MessageType, ?> extension =
518 extensionRegistry.findLiteExtensionByNumber(
519 defaultInstance, fieldNumber);
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.
536 unknown = true; // Wrong wire type.
539 if (unknown) { // Unknown field or wrong wire type. Skip.
540 return input.skipField(tag, unknownFieldsCodedOutput);
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();
550 extension.descriptor.getEnumType().findValueByNumber(rawValue);
552 // If the number isn't recognized as a valid value for this
553 // enum, drop it (don't even add it to unknownFields).
556 extensions.addRepeatedField(extension.descriptor,
557 extension.singularToFieldSetType(value));
560 while (input.getBytesUntilLimit() > 0) {
562 FieldSet.readPrimitiveField(input,
563 extension.descriptor.getLiteType(),
564 /*checkUtf8=*/ false);
565 extensions.addRepeatedField(extension.descriptor, value);
568 input.popLimit(limit);
571 switch (extension.descriptor.getLiteJavaType()) {
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();
581 if (subBuilder == null) {
582 subBuilder = extension.getMessageDefaultInstance()
583 .newBuilderForType();
585 if (extension.descriptor.getLiteType() ==
586 WireFormat.FieldType.GROUP) {
587 input.readGroup(extension.getNumber(),
588 subBuilder, extensionRegistry);
590 input.readMessage(subBuilder, extensionRegistry);
592 value = subBuilder.build();
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.
602 unknownFieldsCodedOutput.writeRawVarint32(tag);
603 unknownFieldsCodedOutput.writeUInt32NoTag(rawValue);
608 value = FieldSet.readPrimitiveField(input,
609 extension.descriptor.getLiteType(),
610 /*checkUtf8=*/ false);
614 if (extension.descriptor.isRepeated()) {
615 extensions.addRepeatedField(extension.descriptor,
616 extension.singularToFieldSetType(value));
618 extensions.setField(extension.descriptor,
619 extension.singularToFieldSetType(value));
626 // -----------------------------------------------------------------
628 /** For use by generated code only. */
629 public static <ContainingType extends MessageLite, Type>
630 GeneratedExtension<ContainingType, Type>
631 newSingularGeneratedExtension(
632 final ContainingType containingTypeDefaultInstance,
633 final Type defaultValue,
634 final MessageLite messageDefaultInstance,
635 final Internal.EnumLiteMap<?> enumTypeMap,
637 final WireFormat.FieldType type,
638 final Class singularType) {
639 return new GeneratedExtension<ContainingType, Type>(
640 containingTypeDefaultInstance,
642 messageDefaultInstance,
643 new ExtensionDescriptor(enumTypeMap, number, type,
644 false /* isRepeated */,
645 false /* isPacked */),
649 /** For use by generated code only. */
650 public static <ContainingType extends MessageLite, Type>
651 GeneratedExtension<ContainingType, Type>
652 newRepeatedGeneratedExtension(
653 final ContainingType containingTypeDefaultInstance,
654 final MessageLite messageDefaultInstance,
655 final Internal.EnumLiteMap<?> enumTypeMap,
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,
665 messageDefaultInstance,
666 new ExtensionDescriptor(
667 enumTypeMap, number, type, true /* isRepeated */, isPacked),
671 static final class ExtensionDescriptor
672 implements FieldSet.FieldDescriptorLite<
673 ExtensionDescriptor> {
675 final Internal.EnumLiteMap<?> enumTypeMap,
677 final WireFormat.FieldType type,
678 final boolean isRepeated,
679 final boolean isPacked) {
680 this.enumTypeMap = enumTypeMap;
681 this.number = number;
683 this.isRepeated = isRepeated;
684 this.isPacked = isPacked;
687 final Internal.EnumLiteMap<?> enumTypeMap;
689 final WireFormat.FieldType type;
690 final boolean isRepeated;
691 final boolean isPacked;
693 public int getNumber() {
697 public WireFormat.FieldType getLiteType() {
701 public WireFormat.JavaType getLiteJavaType() {
702 return type.getJavaType();
705 public boolean isRepeated() {
709 public boolean isPacked() {
713 public Internal.EnumLiteMap<?> getEnumType() {
717 @SuppressWarnings("unchecked")
718 public MessageLite.Builder internalMergeFrom(
719 MessageLite.Builder to, MessageLite from) {
720 return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
724 public int compareTo(ExtensionDescriptor other) {
725 return number - other.number;
729 // =================================================================
731 /** Calls Class.getMethod and throws a RuntimeException if it fails. */
732 @SuppressWarnings("unchecked")
733 static Method getMethodOrDie(Class clazz, String name, Class... params) {
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);
743 /** Calls invoke and throws a RuntimeException if it fails. */
744 static Object invokeOrDie(Method method, Object object, Object... params) {
746 return method.invoke(object, params);
747 } catch (IllegalAccessException e) {
748 throw new RuntimeException(
749 "Couldn't use Java reflection to implement protocol message " +
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) {
758 throw new RuntimeException(
759 "Unexpected exception thrown by generated accessor method.", cause);
765 * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
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().
770 public static class GeneratedExtension<
771 ContainingType extends MessageLite, Type> {
774 * Create a new isntance with the given parameters.
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
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");
793 if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
794 messageDefaultInstance == null) {
795 throw new IllegalArgumentException(
796 "Null messageDefaultInstance");
798 this.containingTypeDefaultInstance = containingTypeDefaultInstance;
799 this.defaultValue = defaultValue;
800 this.messageDefaultInstance = messageDefaultInstance;
801 this.descriptor = descriptor;
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);
810 this.enumValueOf = null;
814 final ContainingType containingTypeDefaultInstance;
815 final Type defaultValue;
816 final MessageLite messageDefaultInstance;
817 final ExtensionDescriptor descriptor;
818 final Class singularType;
819 final Method enumValueOf;
822 * Default instance of the type being extended, used to identify that type.
824 public ContainingType getContainingTypeDefaultInstance() {
825 return containingTypeDefaultInstance;
828 /** Get the field number. */
829 public int getNumber() {
830 return descriptor.getNumber();
835 * If the extension is an embedded message or group, returns the default
836 * instance of the message.
838 public MessageLite getMessageDefaultInstance() {
839 return messageDefaultInstance;
842 @SuppressWarnings("unchecked")
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));
855 return singularFromFieldSetType(value);
859 Object singularFromFieldSetType(final Object value) {
860 if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
861 return invokeOrDie(enumValueOf, null, (Integer) value);
867 @SuppressWarnings("unchecked")
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));
880 return singularToFieldSetType(value);
884 Object singularToFieldSetType(final Object value) {
885 if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
886 return ((Internal.EnumLite) value).getNumber();
894 * A serialized (serializable) form of the generated message. Stores the
895 * message as a class name and a byte array.
897 static final class SerializedForm implements Serializable {
898 private static final long serialVersionUID = 0L;
900 private String messageClassName;
901 private byte[] asBytes;
904 * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
905 * @param regularForm the message to serialize
907 SerializedForm(MessageLite regularForm) {
908 messageClassName = regularForm.getClass().getName();
909 asBytes = regularForm.toByteArray();
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
917 @SuppressWarnings("unchecked")
918 protected Object readResolve() throws ObjectStreamException {
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);
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
946 protected Object writeReplace() throws ObjectStreamException {
947 return new SerializedForm(this);