Fix a bug that causes DynamicMessage.setField() to not work for repeated

enum fields.
pull/38/head
Feng Xiao 10 years ago
parent 6147768171
commit 345d49a51e
  1. 21
      java/src/main/java/com/google/protobuf/DynamicMessage.java
  2. 16
      java/src/test/java/com/google/protobuf/DynamicMessageTest.java

@ -38,6 +38,7 @@ 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;
/**
@ -483,8 +484,13 @@ 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) {
verifyEnumType(field, value);
verifyEnumValue(field, value);
}
OneofDescriptor oneofDescriptor = field.getContainingOneof();
if (oneofDescriptor != null) {
@ -573,7 +579,7 @@ public final class DynamicMessage extends AbstractMessage {
}
/** Verifies that the value is EnumValueDescriptor and matchs Enum Type. */
private void verifyEnumType(FieldDescriptor field, Object value) {
private void verifySingleEnumValue(FieldDescriptor field, Object value) {
if (value == null) {
throw new NullPointerException();
}
@ -587,6 +593,17 @@ public final class DynamicMessage extends AbstractMessage {
}
}
/** Verifies the value for an enum field. */
private void verifyEnumValue(FieldDescriptor field, Object value) {
if (field.isRepeated()) {
for (Object item : (List) value) {
verifySingleEnumValue(field, item);
}
} else {
verifySingleEnumValue(field, value);
}
}
private void ensureIsMutable() {
if (fields.isImmutable()) {
fields = fields.clone();

@ -30,6 +30,7 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
@ -307,4 +308,19 @@ public class DynamicMessageTest extends TestCase {
message = builder.build();
assertSame(null, message.getOneofFieldDescriptor(oneof));
}
// Regression test for a bug that makes setField() not work for repeated
// enum fields.
public void testSettersForRepeatedEnumField() throws Exception {
DynamicMessage.Builder builder =
DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
FieldDescriptor repeatedEnumField =
TestAllTypes.getDescriptor().findFieldByName(
"repeated_nested_enum");
EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor();
builder.setField(repeatedEnumField, enumDescriptor.getValues());
DynamicMessage message = builder.build();
assertEquals(
enumDescriptor.getValues(), message.getField(repeatedEnumField));
}
}

Loading…
Cancel
Save