diff options
Diffstat (limited to 'java/src/main/java/com/google/protobuf/DynamicMessage.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/DynamicMessage.java | 226 |
1 files changed, 21 insertions, 205 deletions
diff --git a/java/src/main/java/com/google/protobuf/DynamicMessage.java b/java/src/main/java/com/google/protobuf/DynamicMessage.java index c9ce667..c106b66 100644 --- a/java/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/src/main/java/com/google/protobuf/DynamicMessage.java @@ -1,6 +1,6 @@ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ +// 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 @@ -31,14 +31,10 @@ 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.InputStream; import java.io.IOException; -import java.util.Collections; -import java.util.List; import java.util.Map; /** @@ -50,25 +46,16 @@ import java.util.Map; 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 contructor 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) { + private DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields, + UnknownFieldSet unknownFields) { this.type = type; this.fields = fields; - this.oneofCases = oneofCases; this.unknownFields = unknownFields; } @@ -77,14 +64,10 @@ public final class DynamicMessage extends AbstractMessage { * 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) @@ -168,20 +151,6 @@ public final class DynamicMessage extends AbstractMessage { return fields.getAllFields(); } - public boolean hasOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field == null) { - return false; - } - return true; - } - - public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - return oneofCases[oneof.getIndex()]; - } - public boolean hasField(FieldDescriptor field) { verifyContainingType(field); return fields.hasField(field); @@ -191,9 +160,7 @@ public final class DynamicMessage extends AbstractMessage { verifyContainingType(field); Object result = fields.getField(field); if (result == null) { - if (field.isRepeated()) { - result = Collections.emptyList(); - } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { result = getDefaultInstance(field.getMessageType()); } else { result = field.getDefaultValue(); @@ -216,8 +183,8 @@ public final class DynamicMessage extends AbstractMessage { return unknownFields; } - static boolean isInitialized(Descriptor type, - FieldSet<FieldDescriptor> fields) { + private static boolean isInitialized(Descriptor type, + FieldSet<FieldDescriptor> fields) { // Check that all required fields are present. for (final FieldDescriptor field : type.getFields()) { if (field.isRequired()) { @@ -231,12 +198,10 @@ public final class DynamicMessage extends AbstractMessage { 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); @@ -247,7 +212,6 @@ public final class DynamicMessage extends AbstractMessage { } } - @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -272,26 +236,6 @@ public final class DynamicMessage extends AbstractMessage { return newBuilderForType().mergeFrom(this); } - public Parser<DynamicMessage> getParserForType() { - return new AbstractParser<DynamicMessage>() { - 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) { @@ -300,14 +244,6 @@ public final class DynamicMessage extends AbstractMessage { } } - /** 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."); - } - } - // ================================================================= /** @@ -316,7 +252,6 @@ public final class DynamicMessage extends AbstractMessage { 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. */ @@ -324,24 +259,19 @@ public final class DynamicMessage extends AbstractMessage { 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(); + if (fields == null) { + throw new IllegalStateException("Cannot call clear() after build()."); } - unknownFields = UnknownFieldSet.getDefaultInstance(); + fields.clear(); return this; } - @Override public Builder mergeFrom(Message other) { if (other instanceof DynamicMessage) { // This should be somewhat faster than calling super.mergeFrom(). @@ -350,20 +280,8 @@ public final class DynamicMessage extends AbstractMessage { 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); @@ -371,10 +289,10 @@ public final class DynamicMessage extends AbstractMessage { } public DynamicMessage build() { - if (!isInitialized()) { + // If fields == null, we'll throw an appropriate exception later. + if (fields != null && !isInitialized()) { throw newUninitializedMessageException( - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)); + new DynamicMessage(type, fields, unknownFields)); } return buildPartial(); } @@ -387,27 +305,28 @@ public final class DynamicMessage extends AbstractMessage { private DynamicMessage buildParsed() throws InvalidProtocolBufferException { if (!isInitialized()) { throw newUninitializedMessageException( - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields)) + new DynamicMessage(type, fields, unknownFields)) .asInvalidProtocolBufferException(); } return buildPartial(); } public DynamicMessage buildPartial() { + if (fields == null) { + throw new IllegalStateException( + "build() has already been called on this Builder."); + } fields.makeImmutable(); DynamicMessage result = - new DynamicMessage(type, fields, - java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields); + new DynamicMessage(type, fields, unknownFields); + fields = null; + unknownFields = null; 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; } @@ -438,29 +357,6 @@ public final class DynamicMessage extends AbstractMessage { return new Builder(field.getMessageType()); } - public boolean hasOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field == null) { - return false; - } - return true; - } - - public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - return oneofCases[oneof.getIndex()]; - } - - public Builder clearOneof(OneofDescriptor oneof) { - verifyOneofContainingType(oneof); - FieldDescriptor field = oneofCases[oneof.getIndex()]; - if (field != null) { - clearField(field); - } - return this; - } - public boolean hasField(FieldDescriptor field) { verifyContainingType(field); return fields.hasField(field); @@ -470,9 +366,7 @@ public final class DynamicMessage extends AbstractMessage { verifyContainingType(field); Object result = fields.getField(field); if (result == null) { - if (field.isRepeated()) { - result = Collections.emptyList(); - } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { result = getDefaultInstance(field.getMessageType()); } else { result = field.getDefaultValue(); @@ -483,38 +377,12 @@ public final class DynamicMessage extends AbstractMessage { 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; } 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; } @@ -532,14 +400,12 @@ public final class DynamicMessage extends AbstractMessage { public Builder setRepeatedField(FieldDescriptor field, int index, Object value) { verifyContainingType(field); - ensureIsMutable(); fields.setRepeatedField(field, index, value); return this; } public Builder addRepeatedField(FieldDescriptor field, Object value) { verifyContainingType(field); - ensureIsMutable(); fields.addRepeatedField(field, value); return this; } @@ -553,7 +419,6 @@ public final class DynamicMessage extends AbstractMessage { return this; } - @Override public Builder mergeUnknownFields(UnknownFieldSet unknownFields) { this.unknownFields = UnknownFieldSet.newBuilder(this.unknownFields) @@ -569,54 +434,5 @@ public final class DynamicMessage extends AbstractMessage { "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."); - } - if (field.getEnumType() != ((EnumValueDescriptor) value).getType()) { - throw new IllegalArgumentException( - "EnumValueDescriptor doesn't much Enum Field."); - } - } - - /** 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."); - } } } |