Эх сурвалжийг харах

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

* Ignore unknown enum received in json when ignoreUnknownFields flag is set.
vijay-bhatt 7 жил өмнө
parent
commit
0f56f27ffc

+ 13 - 4
java/util/src/main/java/com/google/protobuf/util/JsonFormat.java

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

+ 50 - 2
java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java

@@ -70,7 +70,6 @@ import java.io.StringReader;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
@@ -162,6 +161,10 @@ public class JsonFormatTest extends TestCase {
     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 {
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     setAllFields(builder);
@@ -669,10 +672,22 @@ public class JsonFormatTest extends TestCase {
               + "}",
           builder);
       fail();
+        
     } catch (InvalidProtocolBufferException e) {
       // 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 {
     TestMap.Builder builder = TestMap.newBuilder();
@@ -1173,7 +1188,40 @@ public class JsonFormatTest extends TestCase {
     String json = "{\n" + "  \"unknownField\": \"XXX\"\n" + "}";
     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 {
     TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder();
     mergeFromJson("{\n" + "  \"optionalNestedEnum\": 2\n" + "}", actualBuilder);