Ignore unknown enum received in json when ignoreUnknownFields flag is set (#4825)

* Ignore unknown enum received in json when ignoreUnknownFields flag is set.
This commit is contained in:
vijay-bhatt 2018-07-31 02:06:46 +05:30 committed by Feng Xiao
parent 751bf9783f
commit 0f56f27ffc
2 changed files with 63 additions and 6 deletions

View File

@ -50,6 +50,7 @@ import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor.Type;
import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor;
import com.google.protobuf.DoubleValue; import com.google.protobuf.DoubleValue;
@ -1539,7 +1540,11 @@ public class JsonFormat {
Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder); Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder); Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder);
if (value == null) { if (value == null) {
throw new InvalidProtocolBufferException("Map value cannot be null."); if(ignoringUnknownFields && valueField.getType() == Type.ENUM) {
continue;
} else {
throw new InvalidProtocolBufferException("Map value cannot be null.");
}
} }
entryBuilder.setField(keyField, key); entryBuilder.setField(keyField, key);
entryBuilder.setField(valueField, value); entryBuilder.setField(valueField, value);
@ -1557,8 +1562,12 @@ public class JsonFormat {
for (int i = 0; i < array.size(); ++i) { for (int i = 0; i < array.size(); ++i) {
Object value = parseFieldValue(field, array.get(i), builder); Object value = parseFieldValue(field, array.get(i), builder);
if (value == null) { if (value == null) {
throw new InvalidProtocolBufferException( if(ignoringUnknownFields && field.getType() == Type.ENUM) {
"Repeated field elements cannot be null in field: " + field.getFullName()); continue;
} else {
throw new InvalidProtocolBufferException(
"Repeated field elements cannot be null in field: " + field.getFullName());
}
} }
builder.addRepeatedField(field, value); builder.addRepeatedField(field, value);
} }
@ -1748,7 +1757,7 @@ public class JsonFormat {
// an exception later. // an exception later.
} }
if (result == null) { if (result == null && !ignoringUnknownFields) {
throw new InvalidProtocolBufferException( throw new InvalidProtocolBufferException(
"Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName()); "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
} }

View File

@ -70,7 +70,6 @@ import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
@ -162,6 +161,10 @@ public class JsonFormatTest extends TestCase {
JsonFormat.parser().merge(json, builder); JsonFormat.parser().merge(json, builder);
} }
private void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder) throws IOException {
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
}
public void testAllFields() throws Exception { public void testAllFields() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestAllTypes.Builder builder = TestAllTypes.newBuilder();
setAllFields(builder); setAllFields(builder);
@ -669,10 +672,22 @@ public class JsonFormatTest extends TestCase {
+ "}", + "}",
builder); builder);
fail(); fail();
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
// Exception expected. // Exception expected.
} }
} }
public void testMapEnumNullValueIsIgnored() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
mergeFromJsonIgnoringUnknownFields(
"{\n"
+ " \"int32ToEnumMap\": {\"1\": null}\n"
+ "}",
builder);
TestMap map = builder.build();
assertEquals(0, map.getInt32ToEnumMapMap().entrySet().size());
}
public void testParserAcceptNonQuotedObjectKey() throws Exception { public void testParserAcceptNonQuotedObjectKey() throws Exception {
TestMap.Builder builder = TestMap.newBuilder(); TestMap.Builder builder = TestMap.newBuilder();
@ -1173,7 +1188,40 @@ public class JsonFormatTest extends TestCase {
String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}";
JsonFormat.parser().ignoringUnknownFields().merge(json, builder); JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
} }
public void testParserIgnoringUnknownEnums() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
String json = "{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}";
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
assertEquals(0, builder.getOptionalNestedEnumValue());
}
public void testUnknownEnumMap() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
JsonFormat.parser().ignoringUnknownFields().merge(
"{\n"
+ " \"int32ToEnumMap\": {1: XXX, 2: FOO}"
+ "}",
builder);
assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2));
assertEquals(1, builder.getInt32ToEnumMapMap().size());
}
public void testRepeatedUnknownEnum() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
JsonFormat.parser().ignoringUnknownFields().merge(
"{\n"
+ " \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]"
+ "}",
builder);
assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0));
assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1));
assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2));
assertEquals(3, builder.getRepeatedNestedEnumList().size());
}
public void testParserIntegerEnumValue() throws Exception { public void testParserIntegerEnumValue() throws Exception {
TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder();
mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder); mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder);