diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index 9291683955..5092588132 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -178,34 +178,6 @@ public class JsonFormat { sortingMapKeys); } - /** - * Creates a new {@link Printer} that will always print fields unless they are a message type or - * in a oneof. - * - *

Note that this does print Proto2 Optional but does not print Proto3 Optional fields, as - * the latter is represented using a synthetic oneof. - * - *

The new Printer clones all other configurations from the current {@link Printer}. - * - * @deprecated Prefer {@link #alwaysPrintFieldsWithNoPresence} - */ - @Deprecated - public Printer includingDefaultValueFields() { - if (shouldPrintDefaults != ShouldPrintDefaults.ONLY_IF_PRESENT) { - throw new IllegalStateException( - "JsonFormat includingDefaultValueFields has already been set."); - } - return new Printer( - registry, - oldRegistry, - ShouldPrintDefaults.ALWAYS_PRINT_EXCEPT_MESSAGES_AND_ONEOFS, - ImmutableSet.of(), - preservingProtoFieldNames, - omittingInsignificantWhitespace, - printingEnumsAsInts, - sortingMapKeys); - } - /** * Creates a new {@link Printer} that will also print default-valued fields if their * FieldDescriptors are found in the supplied set. Empty repeated fields and map fields will be diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index 287eff9b20..ae345b4aa5 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -1527,312 +1527,10 @@ public class JsonFormatTest { + " \"repeatedRecursive\": []\n" + "}"; - // includingDefaultValueFields() and alwaysPrintFieldsWithNoPresence() should - // behave identically on the proto3 test message: - assertThat(JsonFormat.printer().includingDefaultValueFields().print(message)) - .isEqualTo(expectedJsonWithDefaults); assertThat(JsonFormat.printer().alwaysPrintFieldsWithNoPresence().print(message)) .isEqualTo(expectedJsonWithDefaults); } - @Test - public void testDefaultValueForSpecificFieldsOptionProto3() throws Exception { - TestAllTypes message = TestAllTypes.getDefaultInstance(); - Set fixedFields = new HashSet<>(); - for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { - if (fieldDesc.getName().contains("_fixed")) { - fixedFields.add(fieldDesc); - } - } - - assertThat(JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message)) - .isEqualTo( - "{\n" - + " \"optionalFixed32\": 0,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": []\n" - + "}"); - - TestAllTypes messageNonDefaults = - message.toBuilder().setOptionalInt64(1234).setOptionalFixed32(3232).build(); - assertThat( - JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults)) - .isEqualTo( - "{\n" - + " \"optionalInt64\": \"1234\",\n" - + " \"optionalFixed32\": 3232,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": []\n" - + "}"); - } - - @Test - public void testDefaultValueForSpecificFieldsProto3_doesntHonorMessageFields() throws Exception { - TestAllTypes message = TestAllTypes.getDefaultInstance(); - Set fixedFields = - ImmutableSet.of( - TestAllTypes.getDescriptor().findFieldByName("optional_bool"), - TestAllTypes.getDescriptor().findFieldByName("optional_recursive")); - - assertThat(JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message)) - .isEqualTo("{\n \"optionalBool\": false\n}"); - } - - @Test - public void testRejectChangingDefaultFieldOptionMultipleTimes() throws Exception { - Set fixedFields = new HashSet<>(); - for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { - if (fieldDesc.getName().contains("_fixed")) { - fixedFields.add(fieldDesc); - } - } - try { - JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(); - assertWithMessage("IllegalStateException is expected.").fail(); - } catch (IllegalStateException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - try { - JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(fixedFields); - assertWithMessage("IllegalStateException is expected.").fail(); - } catch (IllegalStateException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - try { - JsonFormat.printer().includingDefaultValueFields(fixedFields).includingDefaultValueFields(); - assertWithMessage("IllegalStateException is expected.").fail(); - } catch (IllegalStateException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - try { - JsonFormat.printer() - .includingDefaultValueFields(fixedFields) - .includingDefaultValueFields(fixedFields); - assertWithMessage("IllegalStateException is expected.").fail(); - } catch (IllegalStateException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - Set intFields = new HashSet<>(); - for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { - if (fieldDesc.getName().contains("_int")) { - intFields.add(fieldDesc); - } - } - - try { - JsonFormat.printer() - .includingDefaultValueFields(intFields) - .includingDefaultValueFields(fixedFields); - assertWithMessage("IllegalStateException is expected.").fail(); - } catch (IllegalStateException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - try { - JsonFormat.printer().includingDefaultValueFields(null); - assertWithMessage("IllegalArgumentException is expected.").fail(); - } catch (IllegalArgumentException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - - try { - JsonFormat.printer().includingDefaultValueFields(Collections.emptySet()); - assertWithMessage("IllegalArgumentException is expected.").fail(); - } catch (IllegalArgumentException e) { - // Expected. - assertWithMessage("Exception message should mention includingDefaultValueFields.") - .that(e.getMessage().contains("includingDefaultValueFields")) - .isTrue(); - } - } - - @Test - public void testDefaultValuesOptionProto3Maps() throws Exception { - TestMap mapMessage = TestMap.getDefaultInstance(); - assertThat(JsonFormat.printer().print(mapMessage)).isEqualTo("{\n}"); - assertThat(JsonFormat.printer().includingDefaultValueFields().print(mapMessage)) - .isEqualTo( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " },\n" - + " \"int64ToInt32Map\": {\n" - + " },\n" - + " \"uint32ToInt32Map\": {\n" - + " },\n" - + " \"uint64ToInt32Map\": {\n" - + " },\n" - + " \"sint32ToInt32Map\": {\n" - + " },\n" - + " \"sint64ToInt32Map\": {\n" - + " },\n" - + " \"fixed32ToInt32Map\": {\n" - + " },\n" - + " \"fixed64ToInt32Map\": {\n" - + " },\n" - + " \"sfixed32ToInt32Map\": {\n" - + " },\n" - + " \"sfixed64ToInt32Map\": {\n" - + " },\n" - + " \"boolToInt32Map\": {\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " },\n" - + " \"int32ToInt64Map\": {\n" - + " },\n" - + " \"int32ToUint32Map\": {\n" - + " },\n" - + " \"int32ToUint64Map\": {\n" - + " },\n" - + " \"int32ToSint32Map\": {\n" - + " },\n" - + " \"int32ToSint64Map\": {\n" - + " },\n" - + " \"int32ToFixed32Map\": {\n" - + " },\n" - + " \"int32ToFixed64Map\": {\n" - + " },\n" - + " \"int32ToSfixed32Map\": {\n" - + " },\n" - + " \"int32ToSfixed64Map\": {\n" - + " },\n" - + " \"int32ToFloatMap\": {\n" - + " },\n" - + " \"int32ToDoubleMap\": {\n" - + " },\n" - + " \"int32ToBoolMap\": {\n" - + " },\n" - + " \"int32ToStringMap\": {\n" - + " },\n" - + " \"int32ToBytesMap\": {\n" - + " },\n" - + " \"int32ToMessageMap\": {\n" - + " },\n" - + " \"int32ToEnumMap\": {\n" - + " }\n" - + "}"); - } - - @Test - public void testDefaultValueOptionsProto3Oneofs() throws Exception { - TestOneof oneofMessage = TestOneof.getDefaultInstance(); - assertThat(JsonFormat.printer().print(oneofMessage)).isEqualTo("{\n}"); - assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) - .isEqualTo("{\n}"); - assertThat(JsonFormat.printer().alwaysPrintFieldsWithNoPresence().print(oneofMessage)) - .isEqualTo("{\n}"); - - oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build(); - assertThat(JsonFormat.printer().print(oneofMessage)).isEqualTo("{\n \"oneofInt32\": 42\n}"); - assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) - .isEqualTo("{\n \"oneofInt32\": 42\n}"); - assertThat(JsonFormat.printer().alwaysPrintFieldsWithNoPresence().print(oneofMessage)) - .isEqualTo("{\n \"oneofInt32\": 42\n}"); - - TestOneof.Builder oneofBuilder = TestOneof.newBuilder(); - mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder); - oneofMessage = oneofBuilder.build(); - assertThat(JsonFormat.printer().print(oneofMessage)) - .isEqualTo("{\n \"oneofNullValue\": null\n}"); - assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) - .isEqualTo("{\n \"oneofNullValue\": null\n}"); - assertThat(JsonFormat.printer().alwaysPrintFieldsWithNoPresence().print(oneofMessage)) - .isEqualTo("{\n \"oneofNullValue\": null\n}"); - } - - @Test - public void testIncludingDefaultValueOptionsWithProto2Optional() throws Exception { - TestAllTypesProto2 message = TestAllTypesProto2.getDefaultInstance(); - assertThat(JsonFormat.printer().print(message)).isEqualTo("{\n}"); - // includingDefaultValueFields() and alwaysPrintFieldsWithNoPresence() - // behave differently on a proto2 message: the former includes the proto2 explicit presence - // fields and the latter does not. - assertThat(JsonFormat.printer().includingDefaultValueFields().print(message)) - .isEqualTo( - "{\n" - + " \"optionalInt32\": 0,\n" - + " \"optionalInt64\": \"0\",\n" - + " \"optionalUint32\": 0,\n" - + " \"optionalUint64\": \"0\",\n" - + " \"optionalSint32\": 0,\n" - + " \"optionalSint64\": \"0\",\n" - + " \"optionalFixed32\": 0,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"optionalSfixed32\": 0,\n" - + " \"optionalSfixed64\": \"0\",\n" - + " \"optionalFloat\": 0.0,\n" - + " \"optionalDouble\": 0.0,\n" - + " \"optionalBool\": false,\n" - + " \"optionalString\": \"\",\n" - + " \"optionalBytes\": \"\",\n" - + " \"optionalNestedEnum\": \"FOO\",\n" - + " \"repeatedInt32\": [],\n" - + " \"repeatedInt64\": [],\n" - + " \"repeatedUint32\": [],\n" - + " \"repeatedUint64\": [],\n" - + " \"repeatedSint32\": [],\n" - + " \"repeatedSint64\": [],\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": [],\n" - + " \"repeatedSfixed32\": [],\n" - + " \"repeatedSfixed64\": [],\n" - + " \"repeatedFloat\": [],\n" - + " \"repeatedDouble\": [],\n" - + " \"repeatedBool\": [],\n" - + " \"repeatedString\": [],\n" - + " \"repeatedBytes\": [],\n" - + " \"repeatedNestedMessage\": [],\n" - + " \"repeatedNestedEnum\": [],\n" - + " \"optionalAliasedEnum\": \"ALIAS_FOO\",\n" - + " \"repeatedRecursive\": []\n" - + "}"); - assertThat(JsonFormat.printer().alwaysPrintFieldsWithNoPresence().print(message)) - .isEqualTo( - "{\n" - + " \"repeatedInt32\": [],\n" - + " \"repeatedInt64\": [],\n" - + " \"repeatedUint32\": [],\n" - + " \"repeatedUint64\": [],\n" - + " \"repeatedSint32\": [],\n" - + " \"repeatedSint64\": [],\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": [],\n" - + " \"repeatedSfixed32\": [],\n" - + " \"repeatedSfixed64\": [],\n" - + " \"repeatedFloat\": [],\n" - + " \"repeatedDouble\": [],\n" - + " \"repeatedBool\": [],\n" - + " \"repeatedString\": [],\n" - + " \"repeatedBytes\": [],\n" - + " \"repeatedNestedMessage\": [],\n" - + " \"repeatedNestedEnum\": [],\n" - + " \"repeatedRecursive\": []\n" - + "}"); - } - @Test public void testDefaultValueForSpecificFieldsOptionProto2() throws Exception { TestAllTypesProto2 message = TestAllTypesProto2.getDefaultInstance(); diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index e46622b5ea..d1a0777d15 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -266,65 +266,6 @@ class JsonFormatTest(JsonFormatBase): json_format.Parse(text, message) self.assertEqual(message.int32_value, 1) - def testAlwaysSeriliaze(self): - message = json_format_proto3_pb2.TestMessage(string_value='foo') - self.assertEqual( - json.loads( - json_format.MessageToJson( - message, including_default_value_fields=True - ) - ), - json.loads( - '{' - '"repeatedStringValue": [],' - '"stringValue": "foo",' - '"repeatedBoolValue": [],' - '"repeatedUint32Value": [],' - '"repeatedInt32Value": [],' - '"enumValue": "FOO",' - '"int32Value": 0,' - '"floatValue": 0,' - '"int64Value": "0",' - '"uint32Value": 0,' - '"repeatedBytesValue": [],' - '"repeatedUint64Value": [],' - '"repeatedDoubleValue": [],' - '"bytesValue": "",' - '"boolValue": false,' - '"repeatedEnumValue": [],' - '"uint64Value": "0",' - '"doubleValue": 0,' - '"repeatedFloatValue": [],' - '"repeatedInt64Value": [],' - '"repeatedMessageValue": []}' - ), - ) - parsed_message = json_format_proto3_pb2.TestMessage() - self.CheckParseBack(message, parsed_message) - - def testProto3Optional_IncludingDefaultValueFields(self): - message = test_proto3_optional_pb2.TestProto3Optional() - self.assertEqual( - json.loads( - json_format.MessageToJson( - message, including_default_value_fields=True - ) - ), - json.loads('{"repeatedInt32": [], "repeatedNestedMessage": []}'), - ) - message.optional_int32 = 0 - self.assertEqual( - json.loads( - json_format.MessageToJson( - message, including_default_value_fields=True - ) - ), - json.loads( - '{"optionalInt32": 0,"repeatedInt32": [],' - ' "repeatedNestedMessage": []}' - ), - ) - def testProto3Optional_IncludingDefaultValueWithoutPresenceFields(self): message = test_proto3_optional_pb2.TestProto3Optional() self.assertEqual( @@ -348,44 +289,6 @@ class JsonFormatTest(JsonFormatBase): ), ) - def testProto2_IncludingDefaultValueFields(self): - message = test_proto2_pb2.TestProto2() - self.assertEqual( - json.loads( - json_format.MessageToJson( - message, including_default_value_fields=True - ) - ), - json.loads("""{ - "optionalBool":false, - "optionalBytes":"", - "optionalDouble":0.0, - "optionalInt32":0, - "optionalNestedEnum":"UNSPECIFIED", - "optionalString":"", - "repeatedInt32":[], - "repeatedNestedMessage": [] - }"""), - ) - message.optional_int32 = 99 - self.assertEqual( - json.loads( - json_format.MessageToJson( - message, including_default_value_fields=True - ) - ), - json.loads("""{ - "optionalBool":false, - "optionalBytes":"", - "optionalDouble":0.0, - "optionalInt32":99, - "optionalNestedEnum":"UNSPECIFIED", - "optionalString":"", - "repeatedInt32":[], - "repeatedNestedMessage": [] - }"""), - ) - def testProto2_IncludingDefaultValueWithoutPresenceFields(self): message = test_proto2_pb2.TestProto2() self.assertEqual( @@ -423,7 +326,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -454,7 +357,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False ) ), json.loads( @@ -476,12 +379,16 @@ class JsonFormatTest(JsonFormatBase): message = json_format_proto3_pb2.TestOneof() # Always print does not affect oneof fields. self.assertEqual( - json_format.MessageToJson(message, including_default_value_fields=True), + json_format.MessageToJson( + message, always_print_fields_with_no_presence=True + ), '{}', ) message.oneof_int32_value = 0 self.assertEqual( - json_format.MessageToJson(message, including_default_value_fields=True), + json_format.MessageToJson( + message, always_print_fields_with_no_presence=True + ), '{\n "oneofInt32Value": 0\n}', ) parsed_message = json_format_proto3_pb2.TestOneof() @@ -526,7 +433,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -570,7 +477,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -594,7 +501,9 @@ class JsonFormatTest(JsonFormatBase): message.value.paths.append('foo.bar') message.value.paths.append('bar') self.assertEqual( - json_format.MessageToJson(message, including_default_value_fields=True), + json_format.MessageToJson( + message, always_print_fields_with_no_presence=True + ), '{\n "value": "foo.bar,bar"\n}', ) parsed_message = json_format_proto3_pb2.TestFieldMask() @@ -602,7 +511,9 @@ class JsonFormatTest(JsonFormatBase): message.value.Clear() self.assertEqual( - json_format.MessageToJson(message, including_default_value_fields=True), + json_format.MessageToJson( + message, always_print_fields_with_no_presence=True + ), '{\n "value": ""\n}', ) self.CheckParseBack(message, parsed_message) @@ -619,7 +530,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -661,7 +572,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False ) ), json.loads( @@ -698,7 +609,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False ) ), json.loads( @@ -712,7 +623,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False ) ), json.loads( @@ -754,7 +665,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False ) ), json.loads( @@ -793,7 +704,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -829,7 +740,7 @@ class JsonFormatTest(JsonFormatBase): message.value.Pack(test_message) self.assertEqual( json_format.MessageToJson( - message, including_default_value_fields=False + message, always_print_fields_with_no_presence=False )[0:68], '{\n' ' "value": {\n' @@ -845,7 +756,7 @@ class JsonFormatTest(JsonFormatBase): with self.assertRaises(TypeError) as cm: json_format.MessageToJson( message, - including_default_value_fields=True, + always_print_fields_with_no_presence=True, descriptor_pool=empty_pool, ) self.assertEqual( @@ -862,7 +773,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -880,7 +791,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -898,7 +809,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -917,7 +828,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -935,7 +846,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -954,7 +865,7 @@ class JsonFormatTest(JsonFormatBase): self.assertEqual( json.loads( json_format.MessageToJson( - message, including_default_value_fields=True + message, always_print_fields_with_no_presence=True ) ), json.loads( @@ -1489,24 +1400,24 @@ class JsonFormatTest(JsonFormatBase): '{\n "int32_value": 12345\n}', json_format.MessageToJson( message, - including_default_value_fields=False, + always_print_fields_with_no_presence=False, preserving_proto_field_name=True, ), ) - # When including_default_value_fields is True. + # When always_print_fields_with_no_presence is True. message = json_format_proto3_pb2.TestTimestamp() self.assertEqual( '{\n "repeatedValue": []\n}', json_format.MessageToJson( message, - including_default_value_fields=True, + always_print_fields_with_no_presence=True, ), ) self.assertEqual( '{\n "repeated_value": []\n}', json_format.MessageToJson( message, - including_default_value_fields=True, + always_print_fields_with_no_presence=True, preserving_proto_field_name=True, ), ) diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 558b6aa587..79f5078fa5 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -72,7 +72,6 @@ class ParseError(Error): def MessageToJson( message, - including_default_value_fields=False, preserving_proto_field_name=False, indent=2, sort_keys=False, @@ -86,12 +85,6 @@ def MessageToJson( Args: message: The protocol buffers message instance to serialize. - including_default_value_fields: (DEPRECATED: use - always_print_fields_with_no_presence which correctly treats proto2 - and proto3 optionals the same). If True, fields without presence (implicit - presence scalars, repeated fields, and map fields) and Proto2 optional - scalars will always be serialized. Singular message fields, oneof fields - and Proto3 optional scalars are not affected by this option. always_print_fields_with_no_presence: If True, fields without presence (implicit presence scalars, repeated fields, and map fields) will always be serialized. Any field that supports presence is not affected by @@ -114,7 +107,6 @@ def MessageToJson( A string containing the JSON formatted protocol buffer message. """ printer = _Printer( - including_default_value_fields, preserving_proto_field_name, use_integers_for_enums, descriptor_pool, @@ -126,7 +118,6 @@ def MessageToJson( def MessageToDict( message, - including_default_value_fields=False, always_print_fields_with_no_presence=False, preserving_proto_field_name=False, use_integers_for_enums=False, @@ -139,12 +130,6 @@ def MessageToDict( Args: message: The protocol buffers message instance to serialize. - including_default_value_fields: (DEPRECATED: use - always_print_fields_with_no_presence to correctly treats proto2 - and proto3 optional the same). If True, fields without presence (implicit - presence scalars, repeated fields, and map fields) and Proto2 optional - scalars will always be serialized. Singular message fields, oneof fields - and Proto3 optional scalars are not affected by this option. always_print_fields_with_no_presence: If True, fields without presence (implicit presence scalars, repeated fields, and map fields) will always be serialized. Any field that supports presence is not affected by @@ -161,7 +146,6 @@ def MessageToDict( A dict representation of the protocol buffer message. """ printer = _Printer( - including_default_value_fields, preserving_proto_field_name, use_integers_for_enums, descriptor_pool, @@ -185,14 +169,12 @@ class _Printer(object): def __init__( self, - including_default_value_fields=False, preserving_proto_field_name=False, use_integers_for_enums=False, descriptor_pool=None, float_precision=None, always_print_fields_with_no_presence=False, ): - self.including_default_value_fields = including_default_value_fields self.always_print_fields_with_no_presence = ( always_print_fields_with_no_presence ) @@ -256,23 +238,10 @@ class _Printer(object): # Serialize default value if including_default_value_fields is True. if ( - self.including_default_value_fields - or self.always_print_fields_with_no_presence + self.always_print_fields_with_no_presence ): message_descriptor = message.DESCRIPTOR for field in message_descriptor.fields: - # including_default_value doesn't apply to singular messages or any - # field with a containing oneof (including proto3 optionals which use - # a synthetic oneof). - if self.including_default_value_fields and ( - ( - field.label != descriptor.FieldDescriptor.LABEL_REPEATED - and field.cpp_type - == descriptor.FieldDescriptor.CPPTYPE_MESSAGE - ) - or field.containing_oneof - ): - continue # always_print_fields_with_no_presence doesn't apply to # any field which supports presence. diff --git a/src/google/protobuf/json/internal/unparser.cc b/src/google/protobuf/json/internal/unparser.cc index a7dcf920a2..33e4505d13 100644 --- a/src/google/protobuf/json/internal/unparser.cc +++ b/src/google/protobuf/json/internal/unparser.cc @@ -433,9 +433,6 @@ absl::Status WriteField(JsonWriter& writer, const Msg& msg, } else if (Traits::IsRepeated(field)) { return WriteRepeated(writer, msg, field); } else if (Traits::GetSize(field, msg) == 0) { - // We can only get here if one of the always_print options is true. - ABSL_DCHECK(writer.options().always_print_primitive_fields || - writer.options().always_print_fields_with_no_presence); if (Traits::FieldType(field) == FieldDescriptor::TYPE_GROUP) { // We do not yet have full group support, but this is required so that we @@ -459,12 +456,7 @@ absl::Status WriteFields(JsonWriter& writer, const Msg& msg, Field field = Traits::FieldByIndex(desc, i); bool has = Traits::GetSize(field, msg) > 0; - if (writer.options().always_print_primitive_fields) { - bool is_singular_message = - !Traits::IsRepeated(field) && - Traits::FieldType(field) == FieldDescriptor::TYPE_MESSAGE; - has |= !is_singular_message && !Traits::IsOneof(field); - } + if (writer.options().always_print_fields_with_no_presence) { has |= Traits::IsRepeated(field) || Traits::IsImplicitPresence(field); } diff --git a/src/google/protobuf/json/internal/writer.h b/src/google/protobuf/json/internal/writer.h index 902792fc55..ba4139f8b7 100644 --- a/src/google/protobuf/json/internal/writer.h +++ b/src/google/protobuf/json/internal/writer.h @@ -36,16 +36,6 @@ struct WriterOptions { // Whether to add spaces, line breaks and indentation to make the JSON output // easy to read. bool add_whitespace = false; - // Whether to always print the following types of fields even if they would - // otherwise be omitted: - // - Implicit presence fields set to their 0 value - // - Empty lists and maps - // - Proto2 optional and required scalar fields which are not present (but not - // Proto3 optional scalar fields). - // Note: This option is deprecated in favor of - // always_print_fields_with_no_presence which treats proto2 and proto3 - // optionals the same and will be removed in an upcoming release. - bool always_print_primitive_fields = false; // Whether to always print fields which do not support presence if they would // otherwise be omitted, namely: // - Implicit presence fields set to their 0 value diff --git a/src/google/protobuf/json/json.cc b/src/google/protobuf/json/json.cc index 903b4a273c..cd8743d151 100644 --- a/src/google/protobuf/json/json.cc +++ b/src/google/protobuf/json/json.cc @@ -33,7 +33,6 @@ absl::Status BinaryToJsonStream(google::protobuf::util::TypeResolver* resolver, opts.add_whitespace = options.add_whitespace; opts.preserve_proto_field_names = options.preserve_proto_field_names; opts.always_print_enums_as_ints = options.always_print_enums_as_ints; - opts.always_print_primitive_fields = options.always_print_primitive_fields; opts.always_print_fields_with_no_presence = options.always_print_fields_with_no_presence; opts.unquote_int64_if_possible = options.unquote_int64_if_possible; @@ -89,7 +88,6 @@ absl::Status MessageToJsonString(const Message& message, std::string* output, opts.add_whitespace = options.add_whitespace; opts.preserve_proto_field_names = options.preserve_proto_field_names; opts.always_print_enums_as_ints = options.always_print_enums_as_ints; - opts.always_print_primitive_fields = options.always_print_primitive_fields; opts.always_print_fields_with_no_presence = options.always_print_fields_with_no_presence; opts.unquote_int64_if_possible = options.unquote_int64_if_possible; diff --git a/src/google/protobuf/json/json.h b/src/google/protobuf/json/json.h index 8543fb5fbd..c025a2a5a8 100644 --- a/src/google/protobuf/json/json.h +++ b/src/google/protobuf/json/json.h @@ -39,16 +39,6 @@ struct PrintOptions { // Whether to add spaces, line breaks and indentation to make the JSON output // easy to read. bool add_whitespace = false; - // Whether to always print the following types of fields even if they would - // otherwise be omitted: - // - Implicit presence fields set to their 0 value - // - Empty lists and maps - // - Proto2 optional and required scalar fields which are not present (but not - // Proto3 optional scalar fields). - // Note: This option is deprecated in favor of - // always_print_fields_with_no_presence which treats proto2 and proto3 - // optionals the same and will be removed in an upcoming release. - bool always_print_primitive_fields = false; // Whether to always print fields which do not support presence if they would // otherwise be omitted, namely: // - Implicit presence fields set to their 0 value diff --git a/src/google/protobuf/json/json_test.cc b/src/google/protobuf/json/json_test.cc index bf19dbfa86..b656ec00ce 100644 --- a/src/google/protobuf/json/json_test.cc +++ b/src/google/protobuf/json/json_test.cc @@ -173,107 +173,8 @@ TEST_P(JsonTest, TestWhitespaces) { )")); } -TEST_P(JsonTest, TestDefaultValues) { - TestMessage m; - EXPECT_THAT(ToJson(m), IsOkAndHolds("{}")); - - PrintOptions options; - options.always_print_primitive_fields = true; - EXPECT_THAT(ToJson(m, options), IsOkAndHolds(R"({"boolValue":false,)" - R"("int32Value":0,)" - R"("int64Value":"0",)" - R"("uint32Value":0,)" - R"("uint64Value":"0",)" - R"("floatValue":0,)" - R"("doubleValue":0,)" - R"("stringValue":"",)" - R"("bytesValue":"",)" - R"("enumValue":"FOO",)" - R"("repeatedBoolValue":[],)" - R"("repeatedInt32Value":[],)" - R"("repeatedInt64Value":[],)" - R"("repeatedUint32Value":[],)" - R"("repeatedUint64Value":[],)" - R"("repeatedFloatValue":[],)" - R"("repeatedDoubleValue":[],)" - R"("repeatedStringValue":[],)" - R"("repeatedBytesValue":[],)" - R"("repeatedEnumValue":[],)" - R"("repeatedMessageValue":[])" - "}")); - - m.set_string_value("i am a test string value"); - m.set_bytes_value("i am a test bytes value"); - m.set_optional_bool_value(false); - m.set_optional_string_value(""); - m.set_optional_bytes_value(""); - EXPECT_THAT(ToJson(m, options), - IsOkAndHolds(R"({"boolValue":false,)" - R"("int32Value":0,)" - R"("int64Value":"0",)" - R"("uint32Value":0,)" - R"("uint64Value":"0",)" - R"("floatValue":0,)" - R"("doubleValue":0,)" - R"("stringValue":"i am a test string value",)" - R"("bytesValue":"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=",)" - R"("enumValue":"FOO",)" - R"("repeatedBoolValue":[],)" - R"("repeatedInt32Value":[],)" - R"("repeatedInt64Value":[],)" - R"("repeatedUint32Value":[],)" - R"("repeatedUint64Value":[],)" - R"("repeatedFloatValue":[],)" - R"("repeatedDoubleValue":[],)" - R"("repeatedStringValue":[],)" - R"("repeatedBytesValue":[],)" - R"("repeatedEnumValue":[],)" - R"("repeatedMessageValue":[],)" - R"("optionalBoolValue":false,)" - R"("optionalStringValue":"",)" - R"("optionalBytesValue":"")" - "}")); - EXPECT_THAT( - ToJson(protobuf_unittest::TestAllTypes(), options), - IsOkAndHolds( - R"({"optionalInt32":0,"optionalInt64":"0","optionalUint32":0,)" - R"("optionalUint64":"0","optionalSint32":0,"optionalSint64":"0","optionalFixed32":0,)" - R"("optionalFixed64":"0","optionalSfixed32":0,"optionalSfixed64":"0",)" - R"("optionalFloat":0,"optionalDouble":0,"optionalBool":false,"optionalString":"",)" - R"("optionalBytes":"","optionalgroup":null,"optionalNestedEnum":"FOO","optionalForeignEnum":"FOREIGN_FOO",)" - R"("optionalImportEnum":"IMPORT_FOO","optionalStringPiece":"","optionalCord":"",)" - R"("repeatedInt32":[],"repeatedInt64":[],"repeatedUint32":[],"repeatedUint64":[],)" - R"("repeatedSint32":[],"repeatedSint64":[],"repeatedFixed32":[],"repeatedFixed64":[],)" - R"("repeatedSfixed32":[],"repeatedSfixed64":[],"repeatedFloat":[],"repeatedDouble":[],)" - R"("repeatedBool":[],"repeatedString":[],"repeatedBytes":[],"repeatedgroup":[],)" - R"("repeatedNestedMessage":[],"repeatedForeignMessage":[],"repeatedImportMessage":[],)" - R"("repeatedNestedEnum":[],"repeatedForeignEnum":[],"repeatedImportEnum":[],)" - R"("repeatedStringPiece":[],"repeatedCord":[],"repeatedLazyMessage":[],"defaultInt32":41,)" - R"("defaultInt64":"42","defaultUint32":43,"defaultUint64":"44","defaultSint32":-45,)" - R"("defaultSint64":"46","defaultFixed32":47,"defaultFixed64":"48","defaultSfixed32":49,)" - R"("defaultSfixed64":"-50","defaultFloat":51.5,"defaultDouble":52000,"defaultBool":true,)" - R"("defaultString":"hello","defaultBytes":"d29ybGQ=","defaultNestedEnum":"BAR",)" - R"("defaultForeignEnum":"FOREIGN_BAR","defaultImportEnum":"IMPORT_BAR",)" - R"("defaultStringPiece":"abc","defaultCord":"123"})")); - - EXPECT_THAT( - ToJson(protobuf_unittest::TestExtremeDefaultValues(), options), - IsOkAndHolds( - R"({"escapedBytes":"XDAwMFwwMDFcMDA3XDAxMFwwMTRcblxyXHRcMDEzXFxcJ1wiXDM3Ng==")" - R"(,"largeUint32":4294967295,"largeUint64":"18446744073709551615",)" - R"("smallInt32":-2147483647,"smallInt64":"-9223372036854775807",)" - R"("utf8String":"ሴ","zeroFloat":0,"oneFloat":1,"smallFloat":1.5,)" - R"("negativeOneFloat":-1,"negativeFloat":-1.5,"largeFloat":2e+08,)" - R"("smallNegativeFloat":-8e-28,"infDouble":0,"negInfDouble":0,)" - R"("nanDouble":0,"infFloat":0,"negInfFloat":0,"nanFloat":0,)" - R"("cppTrigraph":"? ? ?? ?? ??? ??/ ??-","reallySmallInt32":-2147483648)" - R"(,"reallySmallInt64":"-9223372036854775808","stringWithZero":"hel\u0000lo")" - R"(,"bytesWithZero":"d29yXDAwMGxk","stringPieceWithZero":"ab\u0000c")" - R"(,"cordWithZero":"12\u00003","replacementString":"${unknown}"})")); -} - -TEST_P(JsonTest, TestAlwaysPrintWithoutPresenceFields) { +TEST_P(JsonTest, TestAlwaysPrintFieldsWithNoPresence) { TestMessage m; EXPECT_THAT(ToJson(m), IsOkAndHolds("{}")); @@ -423,7 +324,7 @@ TEST_P(JsonTest, TestPrintEnumsAsIntsWithDefaultValue) { PrintOptions print_options; print_options.always_print_enums_as_ints = true; - print_options.always_print_primitive_fields = true; + print_options.always_print_fields_with_no_presence = true; auto printed = ToJson(orig, print_options); ASSERT_THAT( @@ -437,21 +338,6 @@ TEST_P(JsonTest, TestPrintEnumsAsIntsWithDefaultValue) { EXPECT_EQ(parsed->enum_value3(), proto3::BAR); } -TEST_P(JsonTest, TestPrintProto2EnumAsIntWithDefaultValue) { - protobuf_unittest::TestDefaultEnumValue orig; - - PrintOptions print_options; - print_options.always_print_enums_as_ints = true; - print_options.always_print_primitive_fields = true; - - auto printed = ToJson(orig, print_options); - ASSERT_THAT(printed, IsOkAndHolds("{\"enumValue\":2}")); - - auto parsed = ToProto(*printed); - ASSERT_OK(parsed); - - EXPECT_EQ(parsed->enum_value(), protobuf_unittest::DEFAULT); -} TEST_P(JsonTest, QuotedEnumValue) { auto m = ToProto(R"json( @@ -634,7 +520,7 @@ TEST_P(JsonTest, RepeatedMapKey) { TEST_P(JsonTest, ParsePrimitiveMapIn) { MapIn message; PrintOptions print_options; - print_options.always_print_primitive_fields = true; + print_options.always_print_fields_with_no_presence = true; auto printed = ToJson(message, print_options); ASSERT_THAT( ToJson(message, print_options), @@ -648,7 +534,7 @@ TEST_P(JsonTest, ParsePrimitiveMapIn) { TEST_P(JsonTest, PrintPrimitiveOneof) { TestOneof message; PrintOptions options; - options.always_print_primitive_fields = true; + options.always_print_fields_with_no_presence = true; message.mutable_oneof_message_value(); EXPECT_THAT(ToJson(message, options), IsOkAndHolds(R"({"oneofMessageValue":{"value":0}})")); @@ -1375,15 +1261,6 @@ TEST_P(JsonTest, HtmlEscape) { EXPECT_THAT(ToJson(m), IsOkAndHolds(R"({"stringValue":"\u003c/script\u003e"})")); - proto3::TestEvilJson m2; - PrintOptions opts; - opts.always_print_primitive_fields = true; - EXPECT_THAT( - ToJson(m2, opts), - IsOkAndHolds( - R"({"regular_name":0,"\u003c/script\u003e":0,)" - R"("unbalanced\"quotes":0,)" - R"("\"\u003cscript\u003ealert('hello!);\u003c/script\u003e":0})")); } TEST_P(JsonTest, FieldOrder) {