diff options
Diffstat (limited to 'java/core/src/main/java/com/google/protobuf/DynamicMessage.java')
-rw-r--r-- | java/core/src/main/java/com/google/protobuf/DynamicMessage.java | 676 |
1 files changed, 0 insertions, 676 deletions
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java deleted file mode 100644 index 859a9e8f..00000000 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ /dev/null @@ -1,676 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 com.google.protobuf.Descriptors.Descriptor; -import com.google.protobuf.Descriptors.EnumValueDescriptor; -import com.google.protobuf.Descriptors.FieldDescriptor; -import com.google.protobuf.Descriptors.OneofDescriptor; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * An implementation of {@link Message} that can represent arbitrary types, - * given a {@link Descriptors.Descriptor}. - * - * @author kenton@google.com Kenton Varda - */ -public final class DynamicMessage extends AbstractMessage { - private final Descriptor type; - private final FieldSet<FieldDescriptor> fields; - private final FieldDescriptor[] oneofCases; - private final UnknownFieldSet unknownFields; - private int memoizedSize = -1; - - /** - * Construct a {@code DynamicMessage} using the given {@code FieldSet}. - * oneofCases stores the FieldDescriptor for each oneof to indicate - * which field is set. Caller should make sure the array is immutable. - * - * This constructor is package private and will be used in - * {@code DynamicMutableMessage} to convert a mutable message to an immutable - * message. - */ - DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields, - FieldDescriptor[] oneofCases, - UnknownFieldSet unknownFields) { - this.type = type; - this.fields = fields; - this.oneofCases = oneofCases; - this.unknownFields = unknownFields; - } - - /** - * Get a {@code DynamicMessage} representing the default instance of the - * given type. - */ - public static DynamicMessage getDefaultInstance(Descriptor type) { - int oneofDeclCount = type.toProto().getOneofDeclCount(); - FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount]; - return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(), - oneofCases, - UnknownFieldSet.getDefaultInstance()); - } - - - /** Parse a message of the given type from the given input stream. */ - public static DynamicMessage parseFrom(Descriptor type, - CodedInputStream input) - throws IOException { - return newBuilder(type).mergeFrom(input).buildParsed(); - } - - /** Parse a message of the given type from the given input stream. */ - public static DynamicMessage parseFrom( - Descriptor type, - CodedInputStream input, - ExtensionRegistry extensionRegistry) - throws IOException { - return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed(); - } - - /** Parse {@code data} as a message of the given type and return it. */ - public static DynamicMessage parseFrom(Descriptor type, ByteString data) - throws InvalidProtocolBufferException { - return newBuilder(type).mergeFrom(data).buildParsed(); - } - - /** Parse {@code data} as a message of the given type and return it. */ - public static DynamicMessage parseFrom(Descriptor type, ByteString data, - ExtensionRegistry extensionRegistry) - throws InvalidProtocolBufferException { - return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed(); - } - - /** Parse {@code data} as a message of the given type and return it. */ - public static DynamicMessage parseFrom(Descriptor type, byte[] data) - throws InvalidProtocolBufferException { - return newBuilder(type).mergeFrom(data).buildParsed(); - } - - /** Parse {@code data} as a message of the given type and return it. */ - public static DynamicMessage parseFrom(Descriptor type, byte[] data, - ExtensionRegistry extensionRegistry) - throws InvalidProtocolBufferException { - return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed(); - } - - /** Parse a message of the given type from {@code input} and return it. */ - public static DynamicMessage parseFrom(Descriptor type, InputStream input) - throws IOException { - return newBuilder(type).mergeFrom(input).buildParsed(); - } - - /** Parse a message of the given type from {@code input} and return it. */ - public static DynamicMessage parseFrom(Descriptor type, InputStream input, - ExtensionRegistry extensionRegistry) - throws IOException { - return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed(); - } - - /** Construct a {@link Message.Builder} for the given type. */ - public static Builder newBuilder(Descriptor type) { - return new Builder(type); - } - - /** - * Construct a {@link Message.Builder} for a message of the same type as - * {@code prototype}, and initialize it with {@code prototype}'s contents. - */ - public static Builder newBuilder(Message prototype) { - return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype); - } - - // ----------------------------------------------------------------- - // Implementation of Message interface. - - @Override - public Descriptor getDescriptorForType() { - return type; - } - - @Override - public DynamicMessage getDefaultInstanceForType() { - return getDefaultInstance(type); - } - - @Override - public Map<FieldDescriptor, Object> getAllFields() { - return fields.getAllFields(); - } - - @Override - public boolean hasOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field == null) { - return false; - } - return true; - } - - @Override - public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - return oneofCases[oneof.getIndex()]; - } - - @Override - public boolean hasField(FieldDescriptor field) { - verifyContainingType(field); - return fields.hasField(field); - } - - @Override - public Object getField(FieldDescriptor field) { - verifyContainingType(field); - Object result = fields.getField(field); - if (result == null) { - if (field.isRepeated()) { - result = Collections.emptyList(); - } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - result = getDefaultInstance(field.getMessageType()); - } else { - result = field.getDefaultValue(); - } - } - return result; - } - - @Override - public int getRepeatedFieldCount(FieldDescriptor field) { - verifyContainingType(field); - return fields.getRepeatedFieldCount(field); - } - - @Override - public Object getRepeatedField(FieldDescriptor field, int index) { - verifyContainingType(field); - return fields.getRepeatedField(field, index); - } - - @Override - public UnknownFieldSet getUnknownFields() { - return unknownFields; - } - - static boolean isInitialized(Descriptor type, - FieldSet<FieldDescriptor> fields) { - // Check that all required fields are present. - for (final FieldDescriptor field : type.getFields()) { - if (field.isRequired()) { - if (!fields.hasField(field)) { - return false; - } - } - } - - // Check that embedded messages are initialized. - return fields.isInitialized(); - } - - @Override - public boolean isInitialized() { - return isInitialized(type, fields); - } - - @Override - public void writeTo(CodedOutputStream output) throws IOException { - if (type.getOptions().getMessageSetWireFormat()) { - fields.writeMessageSetTo(output); - unknownFields.writeAsMessageSetTo(output); - } else { - fields.writeTo(output); - unknownFields.writeTo(output); - } - } - - @Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - if (type.getOptions().getMessageSetWireFormat()) { - size = fields.getMessageSetSerializedSize(); - size += unknownFields.getSerializedSizeAsMessageSet(); - } else { - size = fields.getSerializedSize(); - size += unknownFields.getSerializedSize(); - } - - memoizedSize = size; - return size; - } - - @Override - public Builder newBuilderForType() { - return new Builder(type); - } - - @Override - public Builder toBuilder() { - return newBuilderForType().mergeFrom(this); - } - - @Override - public Parser<DynamicMessage> getParserForType() { - return new AbstractParser<DynamicMessage>() { - @Override - public DynamicMessage parsePartialFrom( - CodedInputStream input, ExtensionRegistryLite extensionRegistry) - throws InvalidProtocolBufferException { - Builder builder = newBuilder(type); - try { - builder.mergeFrom(input, extensionRegistry); - } catch (InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (IOException e) { - throw new InvalidProtocolBufferException(e.getMessage()) - .setUnfinishedMessage(builder.buildPartial()); - } - return builder.buildPartial(); - } - }; - } - - /** Verifies that the field is a field of this message. */ - private void verifyContainingType(FieldDescriptor field) { - if (field.getContainingType() != type) { - throw new IllegalArgumentException( - "FieldDescriptor does not match message type."); - } - } - - /** Verifies that the oneof is an oneof of this message. */ - private void verifyOneofContainingType(OneofDescriptor oneof) { - if (oneof.getContainingType() != type) { - throw new IllegalArgumentException( - "OneofDescriptor does not match message type."); - } - } - - // ================================================================= - - /** - * Builder for {@link DynamicMessage}s. - */ - public static final class Builder extends AbstractMessage.Builder<Builder> { - private final Descriptor type; - private FieldSet<FieldDescriptor> fields; - private final FieldDescriptor[] oneofCases; - private UnknownFieldSet unknownFields; - - /** Construct a {@code Builder} for the given type. */ - private Builder(Descriptor type) { - this.type = type; - this.fields = FieldSet.newFieldSet(); - this.unknownFields = UnknownFieldSet.getDefaultInstance(); - this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()]; - } - - // --------------------------------------------------------------- - // Implementation of Message.Builder interface. - - @Override - public Builder clear() { - if (fields.isImmutable()) { - fields = FieldSet.newFieldSet(); - } else { - fields.clear(); - } - unknownFields = UnknownFieldSet.getDefaultInstance(); - return this; - } - - @Override - public Builder mergeFrom(Message other) { - if (other instanceof DynamicMessage) { - // This should be somewhat faster than calling super.mergeFrom(). - DynamicMessage otherDynamicMessage = (DynamicMessage) other; - if (otherDynamicMessage.type != type) { - throw new IllegalArgumentException( - "mergeFrom(Message) can only merge messages of the same type."); - } - ensureIsMutable(); - fields.mergeFrom(otherDynamicMessage.fields); - mergeUnknownFields(otherDynamicMessage.unknownFields); - for (int i = 0; i < oneofCases.length; i++) { - if (oneofCases[i] == null) { - oneofCases[i] = otherDynamicMessage.oneofCases[i]; - } else { - if ((otherDynamicMessage.oneofCases[i] != null) - && (oneofCases[i] != otherDynamicMessage.oneofCases[i])) { - fields.clearField(oneofCases[i]); - oneofCases[i] = otherDynamicMessage.oneofCases[i]; - } - } - } - return this; - } else { - return super.mergeFrom(other); - } - } - - @Override - public DynamicMessage build() { - if (!isInitialized()) { - throw newUninitializedMessageException( - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)); - } - return buildPartial(); - } - - /** - * Helper for DynamicMessage.parseFrom() methods to call. Throws - * {@link InvalidProtocolBufferException} instead of - * {@link UninitializedMessageException}. - */ - private DynamicMessage buildParsed() throws InvalidProtocolBufferException { - if (!isInitialized()) { - throw newUninitializedMessageException( - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)) - .asInvalidProtocolBufferException(); - } - return buildPartial(); - } - - @Override - public DynamicMessage buildPartial() { - fields.makeImmutable(); - DynamicMessage result = - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields); - return result; - } - - @Override - public Builder clone() { - Builder result = new Builder(type); - result.fields.mergeFrom(fields); - result.mergeUnknownFields(unknownFields); - System.arraycopy(oneofCases, 0, result.oneofCases, 0 , oneofCases.length); - return result; - } - - @Override - public boolean isInitialized() { - return DynamicMessage.isInitialized(type, fields); - } - - @Override - public Descriptor getDescriptorForType() { - return type; - } - - @Override - public DynamicMessage getDefaultInstanceForType() { - return getDefaultInstance(type); - } - - @Override - public Map<FieldDescriptor, Object> getAllFields() { - return fields.getAllFields(); - } - - @Override - public Builder newBuilderForField(FieldDescriptor field) { - verifyContainingType(field); - - if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { - throw new IllegalArgumentException( - "newBuilderForField is only valid for fields with message type."); - } - - return new Builder(field.getMessageType()); - } - - @Override - public boolean hasOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field == null) { - return false; - } - return true; - } - - @Override - public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - return oneofCases[oneof.getIndex()]; - } - - @Override - public Builder clearOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field != null) { - clearField(field); - } - return this; - } - - @Override - public boolean hasField(FieldDescriptor field) { - verifyContainingType(field); - return fields.hasField(field); - } - - @Override - public Object getField(FieldDescriptor field) { - verifyContainingType(field); - Object result = fields.getField(field); - if (result == null) { - if (field.isRepeated()) { - result = Collections.emptyList(); - } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - result = getDefaultInstance(field.getMessageType()); - } else { - result = field.getDefaultValue(); - } - } - return result; - } - - @Override - public Builder setField(FieldDescriptor field, Object value) { - verifyContainingType(field); - ensureIsMutable(); - // TODO(xiaofeng): This check should really be put in FieldSet.setField() - // where all other such checks are done. However, currently - // FieldSet.setField() permits Integer value for enum fields probably - // because of some internal features we support. Should figure it out - // and move this check to a more appropriate place. - if (field.getType() == FieldDescriptor.Type.ENUM) { - ensureEnumValueDescriptor(field, value); - } - OneofDescriptor oneofDescriptor = field.getContainingOneof(); - if (oneofDescriptor != null) { - int index = oneofDescriptor.getIndex(); - FieldDescriptor oldField = oneofCases[index]; - if ((oldField != null) && (oldField != field)) { - fields.clearField(oldField); - } - oneofCases[index] = field; - } - fields.setField(field, value); - return this; - } - - @Override - public Builder clearField(FieldDescriptor field) { - verifyContainingType(field); - ensureIsMutable(); - OneofDescriptor oneofDescriptor = field.getContainingOneof(); - if (oneofDescriptor != null) { - int index = oneofDescriptor.getIndex(); - if (oneofCases[index] == field) { - oneofCases[index] = null; - } - } - fields.clearField(field); - return this; - } - - @Override - public int getRepeatedFieldCount(FieldDescriptor field) { - verifyContainingType(field); - return fields.getRepeatedFieldCount(field); - } - - @Override - public Object getRepeatedField(FieldDescriptor field, int index) { - verifyContainingType(field); - return fields.getRepeatedField(field, index); - } - - @Override - public Builder setRepeatedField(FieldDescriptor field, int index, Object value) { - verifyContainingType(field); - ensureIsMutable(); - fields.setRepeatedField(field, index, value); - return this; - } - - @Override - public Builder addRepeatedField(FieldDescriptor field, Object value) { - verifyContainingType(field); - ensureIsMutable(); - fields.addRepeatedField(field, value); - return this; - } - - @Override - public UnknownFieldSet getUnknownFields() { - return unknownFields; - } - - @Override - public Builder setUnknownFields(UnknownFieldSet unknownFields) { - if (getDescriptorForType().getFile().getSyntax() - == Descriptors.FileDescriptor.Syntax.PROTO3) { - // Proto3 discards unknown fields. - return this; - } - this.unknownFields = unknownFields; - return this; - } - - @Override - public Builder mergeUnknownFields(UnknownFieldSet unknownFields) { - if (getDescriptorForType().getFile().getSyntax() - == Descriptors.FileDescriptor.Syntax.PROTO3) { - // Proto3 discards unknown fields. - return this; - } - this.unknownFields = - UnknownFieldSet.newBuilder(this.unknownFields) - .mergeFrom(unknownFields) - .build(); - return this; - } - - /** Verifies that the field is a field of this message. */ - private void verifyContainingType(FieldDescriptor field) { - if (field.getContainingType() != type) { - throw new IllegalArgumentException( - "FieldDescriptor does not match message type."); - } - } - - /** Verifies that the oneof is an oneof of this message. */ - private void verifyOneofContainingType(OneofDescriptor oneof) { - if (oneof.getContainingType() != type) { - throw new IllegalArgumentException( - "OneofDescriptor does not match message type."); - } - } - - /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */ - private void ensureSingularEnumValueDescriptor( - FieldDescriptor field, Object value) { - if (value == null) { - throw new NullPointerException(); - } - if (!(value instanceof EnumValueDescriptor)) { - throw new IllegalArgumentException( - "DynamicMessage should use EnumValueDescriptor to set Enum Value."); - } - // TODO(xiaofeng): Re-enable this check after Orgstore is fixed to not - // set incorrect EnumValueDescriptors. - // EnumDescriptor fieldType = field.getEnumType(); - // EnumDescriptor fieldValueType = ((EnumValueDescriptor) value).getType(); - // if (fieldType != fieldValueType) { - // throw new IllegalArgumentException(String.format( - // "EnumDescriptor %s of field doesn't match EnumDescriptor %s of field value", - // fieldType.getFullName(), fieldValueType.getFullName())); - // } - } - - /** Verifies the value for an enum field. */ - private void ensureEnumValueDescriptor( - FieldDescriptor field, Object value) { - if (field.isRepeated()) { - for (Object item : (List) value) { - ensureSingularEnumValueDescriptor(field, item); - } - } else { - ensureSingularEnumValueDescriptor(field, value); - } - } - - private void ensureIsMutable() { - if (fields.isImmutable()) { - fields = fields.clone(); - } - } - - @Override - public com.google.protobuf.Message.Builder getFieldBuilder(FieldDescriptor field) { - // TODO(xiangl): need implementation for dynamic message - throw new UnsupportedOperationException( - "getFieldBuilder() called on a dynamic message type."); - } - - @Override - public com.google.protobuf.Message.Builder getRepeatedFieldBuilder(FieldDescriptor field, - int index) { - throw new UnsupportedOperationException( - "getRepeatedFieldBuilder() called on a dynamic message type."); - } - } -} |