Blame | Last modification | View Log | Download | RSS feed
// 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 AbstractMessageLiteimplements 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.@Overridepublic 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 GeneratedMessageLiteimplements 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;@Overridepublic 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.@Overridepublic 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.*/@Overrideprotected 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 ListType emptyList = (Type) Collections.emptyList();return new GeneratedExtension<ContainingType, Type>(containingTypeDefaultInstance,emptyList,messageDefaultInstance,new ExtensionDescriptor(enumTypeMap, number, type, true /* isRepeated */, isPacked));}private static final class ExtensionDescriptorimplements 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);}}