Index: third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java |
diff --git a/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1813e9b3eda0a3b18c72d0b0316fa447114df2e4 |
--- /dev/null |
+++ b/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java |
@@ -0,0 +1,731 @@ |
+// Protocol Buffers - Google's data interchange format |
+// Copyright 2008 Google Inc. All rights reserved. |
+// http://code.google.com/p/protobuf/ |
+// |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following disclaimer |
+// in the documentation and/or other materials provided with the |
+// distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived from |
+// this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+package com.google.protobuf; |
+ |
+import java.io.IOException; |
+import java.io.ObjectStreamException; |
+import java.io.Serializable; |
+import java.lang.reflect.InvocationTargetException; |
+import java.lang.reflect.Method; |
+import java.util.Collections; |
+import java.util.Iterator; |
+import java.util.List; |
+import java.util.Map; |
+ |
+/** |
+ * Lite version of {@link GeneratedMessage}. |
+ * |
+ * @author kenton@google.com Kenton Varda |
+ */ |
+public abstract class GeneratedMessageLite extends AbstractMessageLite |
+ implements Serializable { |
+ private static final long serialVersionUID = 1L; |
+ |
+ protected GeneratedMessageLite() { |
+ } |
+ |
+ protected GeneratedMessageLite(Builder builder) { |
+ } |
+ |
+ @SuppressWarnings("unchecked") |
+ public abstract static class Builder<MessageType extends GeneratedMessageLite, |
+ BuilderType extends Builder> |
+ extends AbstractMessageLite.Builder<BuilderType> { |
+ protected Builder() {} |
+ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public BuilderType clear() { |
+ return (BuilderType) this; |
+ } |
+ |
+ // This is implemented here only to work around an apparent bug in the |
+ // Java compiler and/or build system. See bug #1898463. The mere presence |
+ // of this dummy clone() implementation makes it go away. |
+ @Override |
+ public BuilderType clone() { |
+ throw new UnsupportedOperationException( |
+ "This is supposed to be overridden by subclasses."); |
+ } |
+ |
+ /** All subclasses implement this. */ |
+ public abstract BuilderType mergeFrom(MessageType message); |
+ |
+ // Defined here for return type covariance. |
+ public abstract MessageType getDefaultInstanceForType(); |
+ |
+ /** |
+ * Called by subclasses to parse an unknown field. |
+ * @return {@code true} unless the tag is an end-group tag. |
+ */ |
+ protected boolean parseUnknownField( |
+ final CodedInputStream input, |
+ final ExtensionRegistryLite extensionRegistry, |
+ final int tag) throws IOException { |
+ return input.skipField(tag); |
+ } |
+ } |
+ |
+ // ================================================================= |
+ // Extensions-related stuff |
+ |
+ /** |
+ * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}. |
+ */ |
+ public interface ExtendableMessageOrBuilder< |
+ MessageType extends ExtendableMessage> extends MessageLiteOrBuilder { |
+ |
+ /** Check if a singular extension is present. */ |
+ <Type> boolean hasExtension( |
+ GeneratedExtension<MessageType, Type> extension); |
+ |
+ /** Get the number of elements in a repeated extension. */ |
+ <Type> int getExtensionCount( |
+ GeneratedExtension<MessageType, List<Type>> extension); |
+ |
+ /** Get the value of an extension. */ |
+ <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension); |
+ |
+ /** Get one element of a repeated extension. */ |
+ <Type> Type getExtension( |
+ GeneratedExtension<MessageType, List<Type>> extension, |
+ int index); |
+ } |
+ |
+ /** |
+ * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. |
+ */ |
+ public abstract static class ExtendableMessage< |
+ MessageType extends ExtendableMessage<MessageType>> |
+ extends GeneratedMessageLite |
+ implements ExtendableMessageOrBuilder<MessageType> { |
+ |
+ private final FieldSet<ExtensionDescriptor> extensions; |
+ |
+ protected ExtendableMessage() { |
+ this.extensions = FieldSet.newFieldSet(); |
+ } |
+ |
+ protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) { |
+ this.extensions = builder.buildExtensions(); |
+ } |
+ |
+ private void verifyExtensionContainingType( |
+ final GeneratedExtension<MessageType, ?> extension) { |
+ if (extension.getContainingTypeDefaultInstance() != |
+ getDefaultInstanceForType()) { |
+ // This can only happen if someone uses unchecked operations. |
+ throw new IllegalArgumentException( |
+ "This extension is for a different message type. Please make " + |
+ "sure that you are not suppressing any generics type warnings."); |
+ } |
+ } |
+ |
+ /** Check if a singular extension is present. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public final <Type> boolean hasExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ verifyExtensionContainingType(extension); |
+ return extensions.hasField(extension.descriptor); |
+ } |
+ |
+ /** Get the number of elements in a repeated extension. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public final <Type> int getExtensionCount( |
+ final GeneratedExtension<MessageType, List<Type>> extension) { |
+ verifyExtensionContainingType(extension); |
+ return extensions.getRepeatedFieldCount(extension.descriptor); |
+ } |
+ |
+ /** Get the value of an extension. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ @SuppressWarnings("unchecked") |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ verifyExtensionContainingType(extension); |
+ final Object value = extensions.getField(extension.descriptor); |
+ if (value == null) { |
+ return extension.defaultValue; |
+ } else { |
+ return (Type) value; |
+ } |
+ } |
+ |
+ /** Get one element of a repeated extension. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ @SuppressWarnings("unchecked") |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, |
+ final int index) { |
+ verifyExtensionContainingType(extension); |
+ return (Type) extensions.getRepeatedField(extension.descriptor, index); |
+ } |
+ |
+ /** Called by subclasses to check if all extensions are initialized. */ |
+ protected boolean extensionsAreInitialized() { |
+ return extensions.isInitialized(); |
+ } |
+ |
+ /** |
+ * Used by subclasses to serialize extensions. Extension ranges may be |
+ * interleaved with field numbers, but we must write them in canonical |
+ * (sorted by field number) order. ExtensionWriter helps us write |
+ * individual ranges of extensions at once. |
+ */ |
+ protected class ExtensionWriter { |
+ // Imagine how much simpler this code would be if Java iterators had |
+ // a way to get the next element without advancing the iterator. |
+ |
+ private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter = |
+ extensions.iterator(); |
+ private Map.Entry<ExtensionDescriptor, Object> next; |
+ private final boolean messageSetWireFormat; |
+ |
+ private ExtensionWriter(boolean messageSetWireFormat) { |
+ if (iter.hasNext()) { |
+ next = iter.next(); |
+ } |
+ this.messageSetWireFormat = messageSetWireFormat; |
+ } |
+ |
+ public void writeUntil(final int end, final CodedOutputStream output) |
+ throws IOException { |
+ while (next != null && next.getKey().getNumber() < end) { |
+ ExtensionDescriptor extension = next.getKey(); |
+ if (messageSetWireFormat && extension.getLiteJavaType() == |
+ WireFormat.JavaType.MESSAGE && |
+ !extension.isRepeated()) { |
+ output.writeMessageSetExtension(extension.getNumber(), |
+ (MessageLite) next.getValue()); |
+ } else { |
+ FieldSet.writeField(extension, next.getValue(), output); |
+ } |
+ if (iter.hasNext()) { |
+ next = iter.next(); |
+ } else { |
+ next = null; |
+ } |
+ } |
+ } |
+ } |
+ |
+ protected ExtensionWriter newExtensionWriter() { |
+ return new ExtensionWriter(false); |
+ } |
+ protected ExtensionWriter newMessageSetExtensionWriter() { |
+ return new ExtensionWriter(true); |
+ } |
+ |
+ /** Called by subclasses to compute the size of extensions. */ |
+ protected int extensionsSerializedSize() { |
+ return extensions.getSerializedSize(); |
+ } |
+ protected int extensionsSerializedSizeAsMessageSet() { |
+ return extensions.getMessageSetSerializedSize(); |
+ } |
+ } |
+ |
+ /** |
+ * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. |
+ */ |
+ @SuppressWarnings("unchecked") |
+ public abstract static class ExtendableBuilder< |
+ MessageType extends ExtendableMessage<MessageType>, |
+ BuilderType extends ExtendableBuilder<MessageType, BuilderType>> |
+ extends Builder<MessageType, BuilderType> |
+ implements ExtendableMessageOrBuilder<MessageType> { |
+ protected ExtendableBuilder() {} |
+ |
+ private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet(); |
+ private boolean extensionsIsMutable; |
+ |
+ @Override |
+ public BuilderType clear() { |
+ extensions.clear(); |
+ extensionsIsMutable = false; |
+ return super.clear(); |
+ } |
+ |
+ private void ensureExtensionsIsMutable() { |
+ if (!extensionsIsMutable) { |
+ extensions = extensions.clone(); |
+ extensionsIsMutable = true; |
+ } |
+ } |
+ |
+ /** |
+ * Called by the build code path to create a copy of the extensions for |
+ * building the message. |
+ */ |
+ private FieldSet<ExtensionDescriptor> buildExtensions() { |
+ extensions.makeImmutable(); |
+ extensionsIsMutable = false; |
+ return extensions; |
+ } |
+ |
+ private void verifyExtensionContainingType( |
+ final GeneratedExtension<MessageType, ?> extension) { |
+ if (extension.getContainingTypeDefaultInstance() != |
+ getDefaultInstanceForType()) { |
+ // This can only happen if someone uses unchecked operations. |
+ throw new IllegalArgumentException( |
+ "This extension is for a different message type. Please make " + |
+ "sure that you are not suppressing any generics type warnings."); |
+ } |
+ } |
+ |
+ /** Check if a singular extension is present. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public final <Type> boolean hasExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ verifyExtensionContainingType(extension); |
+ return extensions.hasField(extension.descriptor); |
+ } |
+ |
+ /** Get the number of elements in a repeated extension. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public final <Type> int getExtensionCount( |
+ final GeneratedExtension<MessageType, List<Type>> extension) { |
+ verifyExtensionContainingType(extension); |
+ return extensions.getRepeatedFieldCount(extension.descriptor); |
+ } |
+ |
+ /** Get the value of an extension. */ |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ @SuppressWarnings("unchecked") |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ verifyExtensionContainingType(extension); |
+ final Object value = extensions.getField(extension.descriptor); |
+ if (value == null) { |
+ return extension.defaultValue; |
+ } else { |
+ return (Type) value; |
+ } |
+ } |
+ |
+ /** Get one element of a repeated extension. */ |
+ @SuppressWarnings("unchecked") |
+ //@Override (Java 1.6 override semantics, but we must support 1.5) |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, |
+ final int index) { |
+ verifyExtensionContainingType(extension); |
+ return (Type) extensions.getRepeatedField(extension.descriptor, index); |
+ } |
+ |
+ // This is implemented here only to work around an apparent bug in the |
+ // Java compiler and/or build system. See bug #1898463. The mere presence |
+ // of this dummy clone() implementation makes it go away. |
+ @Override |
+ public BuilderType clone() { |
+ throw new UnsupportedOperationException( |
+ "This is supposed to be overridden by subclasses."); |
+ } |
+ |
+ /** Set the value of an extension. */ |
+ public final <Type> BuilderType setExtension( |
+ final GeneratedExtension<MessageType, Type> extension, |
+ final Type value) { |
+ verifyExtensionContainingType(extension); |
+ ensureExtensionsIsMutable(); |
+ extensions.setField(extension.descriptor, value); |
+ return (BuilderType) this; |
+ } |
+ |
+ /** Set the value of one element of a repeated extension. */ |
+ public final <Type> BuilderType setExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, |
+ final int index, final Type value) { |
+ verifyExtensionContainingType(extension); |
+ ensureExtensionsIsMutable(); |
+ extensions.setRepeatedField(extension.descriptor, index, value); |
+ return (BuilderType) this; |
+ } |
+ |
+ /** Append a value to a repeated extension. */ |
+ public final <Type> BuilderType addExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, |
+ final Type value) { |
+ verifyExtensionContainingType(extension); |
+ ensureExtensionsIsMutable(); |
+ extensions.addRepeatedField(extension.descriptor, value); |
+ return (BuilderType) this; |
+ } |
+ |
+ /** Clear an extension. */ |
+ public final <Type> BuilderType clearExtension( |
+ final GeneratedExtension<MessageType, ?> extension) { |
+ verifyExtensionContainingType(extension); |
+ ensureExtensionsIsMutable(); |
+ extensions.clearField(extension.descriptor); |
+ return (BuilderType) this; |
+ } |
+ |
+ /** Called by subclasses to check if all extensions are initialized. */ |
+ protected boolean extensionsAreInitialized() { |
+ return extensions.isInitialized(); |
+ } |
+ |
+ /** |
+ * Called by subclasses to parse an unknown field or an extension. |
+ * @return {@code true} unless the tag is an end-group tag. |
+ */ |
+ @Override |
+ protected boolean parseUnknownField( |
+ final CodedInputStream input, |
+ final ExtensionRegistryLite extensionRegistry, |
+ final int tag) throws IOException { |
+ final int wireType = WireFormat.getTagWireType(tag); |
+ final int fieldNumber = WireFormat.getTagFieldNumber(tag); |
+ |
+ final GeneratedExtension<MessageType, ?> extension = |
+ extensionRegistry.findLiteExtensionByNumber( |
+ getDefaultInstanceForType(), fieldNumber); |
+ |
+ boolean unknown = false; |
+ boolean packed = false; |
+ if (extension == null) { |
+ unknown = true; // Unknown field. |
+ } else if (wireType == FieldSet.getWireFormatForFieldType( |
+ extension.descriptor.getLiteType(), |
+ false /* isPacked */)) { |
+ packed = false; // Normal, unpacked value. |
+ } else if (extension.descriptor.isRepeated && |
+ extension.descriptor.type.isPackable() && |
+ wireType == FieldSet.getWireFormatForFieldType( |
+ extension.descriptor.getLiteType(), |
+ true /* isPacked */)) { |
+ packed = true; // Packed value. |
+ } else { |
+ unknown = true; // Wrong wire type. |
+ } |
+ |
+ if (unknown) { // Unknown field or wrong wire type. Skip. |
+ return input.skipField(tag); |
+ } |
+ |
+ if (packed) { |
+ final int length = input.readRawVarint32(); |
+ final int limit = input.pushLimit(length); |
+ if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { |
+ while (input.getBytesUntilLimit() > 0) { |
+ final int rawValue = input.readEnum(); |
+ final Object value = |
+ extension.descriptor.getEnumType().findValueByNumber(rawValue); |
+ if (value == null) { |
+ // If the number isn't recognized as a valid value for this |
+ // enum, drop it (don't even add it to unknownFields). |
+ return true; |
+ } |
+ ensureExtensionsIsMutable(); |
+ extensions.addRepeatedField(extension.descriptor, value); |
+ } |
+ } else { |
+ while (input.getBytesUntilLimit() > 0) { |
+ final Object value = |
+ FieldSet.readPrimitiveField(input, |
+ extension.descriptor.getLiteType()); |
+ ensureExtensionsIsMutable(); |
+ extensions.addRepeatedField(extension.descriptor, value); |
+ } |
+ } |
+ input.popLimit(limit); |
+ } else { |
+ final Object value; |
+ switch (extension.descriptor.getLiteJavaType()) { |
+ case MESSAGE: { |
+ MessageLite.Builder subBuilder = null; |
+ if (!extension.descriptor.isRepeated()) { |
+ MessageLite existingValue = |
+ (MessageLite) extensions.getField(extension.descriptor); |
+ if (existingValue != null) { |
+ subBuilder = existingValue.toBuilder(); |
+ } |
+ } |
+ if (subBuilder == null) { |
+ subBuilder = extension.messageDefaultInstance.newBuilderForType(); |
+ } |
+ if (extension.descriptor.getLiteType() == |
+ WireFormat.FieldType.GROUP) { |
+ input.readGroup(extension.getNumber(), |
+ subBuilder, extensionRegistry); |
+ } else { |
+ input.readMessage(subBuilder, extensionRegistry); |
+ } |
+ value = subBuilder.build(); |
+ break; |
+ } |
+ case ENUM: |
+ final int rawValue = input.readEnum(); |
+ value = extension.descriptor.getEnumType() |
+ .findValueByNumber(rawValue); |
+ // If the number isn't recognized as a valid value for this enum, |
+ // drop it. |
+ if (value == null) { |
+ return true; |
+ } |
+ break; |
+ default: |
+ value = FieldSet.readPrimitiveField(input, |
+ extension.descriptor.getLiteType()); |
+ break; |
+ } |
+ |
+ if (extension.descriptor.isRepeated()) { |
+ ensureExtensionsIsMutable(); |
+ extensions.addRepeatedField(extension.descriptor, value); |
+ } else { |
+ ensureExtensionsIsMutable(); |
+ extensions.setField(extension.descriptor, value); |
+ } |
+ } |
+ |
+ return true; |
+ } |
+ |
+ protected final void mergeExtensionFields(final MessageType other) { |
+ ensureExtensionsIsMutable(); |
+ extensions.mergeFrom(((ExtendableMessage) other).extensions); |
+ } |
+ } |
+ |
+ // ----------------------------------------------------------------- |
+ |
+ /** For use by generated code only. */ |
+ public static <ContainingType extends MessageLite, Type> |
+ GeneratedExtension<ContainingType, Type> |
+ newSingularGeneratedExtension( |
+ final ContainingType containingTypeDefaultInstance, |
+ final Type defaultValue, |
+ final MessageLite messageDefaultInstance, |
+ final Internal.EnumLiteMap<?> enumTypeMap, |
+ final int number, |
+ final WireFormat.FieldType type) { |
+ return new GeneratedExtension<ContainingType, Type>( |
+ containingTypeDefaultInstance, |
+ defaultValue, |
+ messageDefaultInstance, |
+ new ExtensionDescriptor(enumTypeMap, number, type, |
+ false /* isRepeated */, |
+ false /* isPacked */)); |
+ } |
+ |
+ /** For use by generated code only. */ |
+ public static <ContainingType extends MessageLite, Type> |
+ GeneratedExtension<ContainingType, Type> |
+ newRepeatedGeneratedExtension( |
+ final ContainingType containingTypeDefaultInstance, |
+ final MessageLite messageDefaultInstance, |
+ final Internal.EnumLiteMap<?> enumTypeMap, |
+ final int number, |
+ final WireFormat.FieldType type, |
+ final boolean isPacked) { |
+ @SuppressWarnings("unchecked") // Subclasses ensure Type is a List |
+ Type emptyList = (Type) Collections.emptyList(); |
+ return new GeneratedExtension<ContainingType, Type>( |
+ containingTypeDefaultInstance, |
+ emptyList, |
+ messageDefaultInstance, |
+ new ExtensionDescriptor( |
+ enumTypeMap, number, type, true /* isRepeated */, isPacked)); |
+ } |
+ |
+ private static final class ExtensionDescriptor |
+ implements FieldSet.FieldDescriptorLite< |
+ ExtensionDescriptor> { |
+ private ExtensionDescriptor( |
+ final Internal.EnumLiteMap<?> enumTypeMap, |
+ final int number, |
+ final WireFormat.FieldType type, |
+ final boolean isRepeated, |
+ final boolean isPacked) { |
+ this.enumTypeMap = enumTypeMap; |
+ this.number = number; |
+ this.type = type; |
+ this.isRepeated = isRepeated; |
+ this.isPacked = isPacked; |
+ } |
+ |
+ private final Internal.EnumLiteMap<?> enumTypeMap; |
+ private final int number; |
+ private final WireFormat.FieldType type; |
+ private final boolean isRepeated; |
+ private final boolean isPacked; |
+ |
+ public int getNumber() { |
+ return number; |
+ } |
+ |
+ public WireFormat.FieldType getLiteType() { |
+ return type; |
+ } |
+ |
+ public WireFormat.JavaType getLiteJavaType() { |
+ return type.getJavaType(); |
+ } |
+ |
+ public boolean isRepeated() { |
+ return isRepeated; |
+ } |
+ |
+ public boolean isPacked() { |
+ return isPacked; |
+ } |
+ |
+ public Internal.EnumLiteMap<?> getEnumType() { |
+ return enumTypeMap; |
+ } |
+ |
+ @SuppressWarnings("unchecked") |
+ public MessageLite.Builder internalMergeFrom( |
+ MessageLite.Builder to, MessageLite from) { |
+ return ((Builder) to).mergeFrom((GeneratedMessageLite) from); |
+ } |
+ |
+ public int compareTo(ExtensionDescriptor other) { |
+ return number - other.number; |
+ } |
+ } |
+ |
+ /** |
+ * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}. |
+ * |
+ * Users should ignore the contents of this class and only use objects of |
+ * this type as parameters to extension accessors and ExtensionRegistry.add(). |
+ */ |
+ public static final class GeneratedExtension< |
+ ContainingType extends MessageLite, Type> { |
+ |
+ private GeneratedExtension( |
+ final ContainingType containingTypeDefaultInstance, |
+ final Type defaultValue, |
+ final MessageLite messageDefaultInstance, |
+ final ExtensionDescriptor descriptor) { |
+ // Defensive checks to verify the correct initialization order of |
+ // GeneratedExtensions and their related GeneratedMessages. |
+ if (containingTypeDefaultInstance == null) { |
+ throw new IllegalArgumentException( |
+ "Null containingTypeDefaultInstance"); |
+ } |
+ if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE && |
+ messageDefaultInstance == null) { |
+ throw new IllegalArgumentException( |
+ "Null messageDefaultInstance"); |
+ } |
+ this.containingTypeDefaultInstance = containingTypeDefaultInstance; |
+ this.defaultValue = defaultValue; |
+ this.messageDefaultInstance = messageDefaultInstance; |
+ this.descriptor = descriptor; |
+ } |
+ |
+ private final ContainingType containingTypeDefaultInstance; |
+ private final Type defaultValue; |
+ private final MessageLite messageDefaultInstance; |
+ private final ExtensionDescriptor descriptor; |
+ |
+ /** |
+ * Default instance of the type being extended, used to identify that type. |
+ */ |
+ public ContainingType getContainingTypeDefaultInstance() { |
+ return containingTypeDefaultInstance; |
+ } |
+ |
+ /** Get the field number. */ |
+ public int getNumber() { |
+ return descriptor.getNumber(); |
+ } |
+ |
+ /** |
+ * If the extension is an embedded message, this is the default instance of |
+ * that type. |
+ */ |
+ public MessageLite getMessageDefaultInstance() { |
+ return messageDefaultInstance; |
+ } |
+ } |
+ |
+ /** |
+ * A serialized (serializable) form of the generated message. Stores the |
+ * message as a class name and a byte array. |
+ */ |
+ static final class SerializedForm implements Serializable { |
+ private static final long serialVersionUID = 0L; |
+ |
+ private String messageClassName; |
+ private byte[] asBytes; |
+ |
+ /** |
+ * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}. |
+ * @param regularForm the message to serialize |
+ */ |
+ SerializedForm(MessageLite regularForm) { |
+ messageClassName = regularForm.getClass().getName(); |
+ asBytes = regularForm.toByteArray(); |
+ } |
+ |
+ /** |
+ * When read from an ObjectInputStream, this method converts this object |
+ * back to the regular form. Part of Java's serialization magic. |
+ * @return a GeneratedMessage of the type that was serialized |
+ */ |
+ @SuppressWarnings("unchecked") |
+ protected Object readResolve() throws ObjectStreamException { |
+ try { |
+ Class messageClass = Class.forName(messageClassName); |
+ Method newBuilder = messageClass.getMethod("newBuilder"); |
+ MessageLite.Builder builder = |
+ (MessageLite.Builder) newBuilder.invoke(null); |
+ builder.mergeFrom(asBytes); |
+ return builder.buildPartial(); |
+ } catch (ClassNotFoundException e) { |
+ throw new RuntimeException("Unable to find proto buffer class", e); |
+ } catch (NoSuchMethodException e) { |
+ throw new RuntimeException("Unable to find newBuilder method", e); |
+ } catch (IllegalAccessException e) { |
+ throw new RuntimeException("Unable to call newBuilder method", e); |
+ } catch (InvocationTargetException e) { |
+ throw new RuntimeException("Error calling newBuilder", e.getCause()); |
+ } catch (InvalidProtocolBufferException e) { |
+ throw new RuntimeException("Unable to understand proto buffer", e); |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Replaces this object in the output stream with a serialized form. |
+ * Part of Java's serialization magic. Generated sub-classes must override |
+ * this method by calling <code>return super.writeReplace();</code> |
+ * @return a SerializedForm of this message |
+ */ |
+ protected Object writeReplace() throws ObjectStreamException { |
+ return new SerializedForm(this); |
+ } |
+} |