summaryrefslogtreecommitdiffstats
path: root/java/src/main/java/com/google/protobuf/DynamicMessage.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/main/java/com/google/protobuf/DynamicMessage.java')
-rw-r--r--java/src/main/java/com/google/protobuf/DynamicMessage.java226
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.");
- }
}
}