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 9e89d6eace..cdcc8d9ccf 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 @@ -8,7 +8,6 @@ package com.google.protobuf.util; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; import com.google.common.io.BaseEncoding; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.gson.Gson; @@ -30,6 +29,7 @@ import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.DoubleValue; import com.google.protobuf.Duration; import com.google.protobuf.DynamicMessage; @@ -86,30 +86,30 @@ public class JsonFormat { return new Printer( com.google.protobuf.TypeRegistry.getEmptyTypeRegistry(), TypeRegistry.getEmptyTypeRegistry(), - ShouldPrintDefaults.ONLY_IF_PRESENT, - /* includingDefaultValueFields */ ImmutableSet.of(), + /* alwaysOutputDefaultValueFields */ false, + /* includingDefaultValueFields */ Collections.emptySet(), /* preservingProtoFieldNames */ false, /* omittingInsignificantWhitespace */ false, /* printingEnumsAsInts */ false, /* sortingMapKeys */ false); } - private enum ShouldPrintDefaults { - ONLY_IF_PRESENT, // The "normal" behavior; the others add more compared to this baseline. - ALWAYS_PRINT_EXCEPT_MESSAGES_AND_ONEOFS, - ALWAYS_PRINT_WITHOUT_PRESENCE_FIELDS, - ALWAYS_PRINT_SPECIFIED_FIELDS - } - - /** A Printer converts a protobuf message to the proto3 JSON format. */ + /** + * A Printer converts a protobuf message to the proto3 JSON format. + */ public static class Printer { private final com.google.protobuf.TypeRegistry registry; private final TypeRegistry oldRegistry; - private final ShouldPrintDefaults shouldPrintDefaults; - - // Empty unless shouldPrintDefaults is set to ALWAYS_PRINT_SPECIFIED_FIELDS. - private final Set includingDefaultValueFields; - + // NOTE: There are 3 states for these *defaultValueFields variables: + // 1) Default - alwaysOutput is false & including is empty set. Fields only output if they are + // set to non-default values. + // 2) No-args includingDefaultValueFields() called - alwaysOutput is true & including is + // irrelevant (but set to empty set). All fields are output regardless of their values. + // 3) includingDefaultValueFields(Set) called - alwaysOutput is false & + // including is set to the specified set. Fields in that set are always output & fields not + // in that set are only output if set to non-default values. + private boolean alwaysOutputDefaultValueFields; + private Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; private final boolean omittingInsignificantWhitespace; private final boolean printingEnumsAsInts; @@ -118,7 +118,7 @@ public class JsonFormat { private Printer( com.google.protobuf.TypeRegistry registry, TypeRegistry oldRegistry, - ShouldPrintDefaults shouldOutputDefaults, + boolean alwaysOutputDefaultValueFields, Set includingDefaultValueFields, boolean preservingProtoFieldNames, boolean omittingInsignificantWhitespace, @@ -126,7 +126,7 @@ public class JsonFormat { boolean sortingMapKeys) { this.registry = registry; this.oldRegistry = oldRegistry; - this.shouldPrintDefaults = shouldOutputDefaults; + this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; this.omittingInsignificantWhitespace = omittingInsignificantWhitespace; @@ -148,7 +148,7 @@ public class JsonFormat { return new Printer( com.google.protobuf.TypeRegistry.getEmptyTypeRegistry(), oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace, @@ -170,7 +170,7 @@ public class JsonFormat { return new Printer( registry, oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace, @@ -179,27 +179,18 @@ public class JsonFormat { } /** - * 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 #includingDefaultValueWithoutPresenceFields} + * Creates a new {@link Printer} that will also print fields set to their + * defaults. Empty repeated fields and map fields will be printed as well. + * The new Printer clones all other configurations from the current + * {@link Printer}. */ - @Deprecated public Printer includingDefaultValueFields() { - if (shouldPrintDefaults != ShouldPrintDefaults.ONLY_IF_PRESENT) { - throw new IllegalStateException( - "JsonFormat includingDefaultValueFields has already been set."); - } + checkUnsetIncludingDefaultValueFields(); return new Printer( registry, oldRegistry, - ShouldPrintDefaults.ALWAYS_PRINT_EXCEPT_MESSAGES_AND_ONEOFS, - ImmutableSet.of(), + true, + Collections.emptySet(), preservingProtoFieldNames, omittingInsignificantWhitespace, printingEnumsAsInts, @@ -207,73 +198,56 @@ public class JsonFormat { } /** - * 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 - * printed as well, if they match. The new Printer clones all other configurations from the - * current {@link Printer}. Call includingDefaultValueFields() with no args to unconditionally - * output all fields. + * Creates a new {@link Printer} that prints enum field values as integers instead of as + * string. The new Printer clones all other configurations from the current {@link Printer}. */ - public Printer includingDefaultValueFields(Set fieldsToAlwaysOutput) { - Preconditions.checkArgument( - null != fieldsToAlwaysOutput && !fieldsToAlwaysOutput.isEmpty(), - "Non-empty Set must be supplied for includingDefaultValueFields."); - if (shouldPrintDefaults != ShouldPrintDefaults.ONLY_IF_PRESENT) { - throw new IllegalStateException( - "JsonFormat includingDefaultValueFields has already been set."); - } + public Printer printingEnumsAsInts() { + checkUnsetPrintingEnumsAsInts(); return new Printer( registry, oldRegistry, - ShouldPrintDefaults.ALWAYS_PRINT_SPECIFIED_FIELDS, - ImmutableSet.copyOf(fieldsToAlwaysOutput), + alwaysOutputDefaultValueFields, + includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace, - printingEnumsAsInts, + true, sortingMapKeys); } - /** - * Creates a new {@link Printer} that will print any field that does not support presence even - * if it would not otherwise be printed (empty repeated fields, empty map fields, and implicit - * presence scalars set to their default value). The new Printer clones all other configurations - * from the current {@link Printer}. - */ - public Printer includingDefaultValueWithoutPresenceFields() { - if (shouldPrintDefaults != ShouldPrintDefaults.ONLY_IF_PRESENT) { - throw new IllegalStateException( - "JsonFormat includingDefaultValueFields has already been set."); + private void checkUnsetPrintingEnumsAsInts() { + if (printingEnumsAsInts) { + throw new IllegalStateException("JsonFormat printingEnumsAsInts has already been set."); } - return new Printer( - registry, - oldRegistry, - ShouldPrintDefaults.ALWAYS_PRINT_WITHOUT_PRESENCE_FIELDS, - ImmutableSet.of(), - preservingProtoFieldNames, - omittingInsignificantWhitespace, - printingEnumsAsInts, - sortingMapKeys); } /** - * Creates a new {@link Printer} that prints enum field values as integers instead of as string. - * The new Printer clones all other configurations from the current {@link Printer}. + * 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 + * printed as well, if they match. The new Printer clones all other configurations from the + * current {@link Printer}. Call includingDefaultValueFields() with no args to unconditionally + * output all fields. */ - public Printer printingEnumsAsInts() { - checkUnsetPrintingEnumsAsInts(); + public Printer includingDefaultValueFields(Set fieldsToAlwaysOutput) { + Preconditions.checkArgument( + null != fieldsToAlwaysOutput && !fieldsToAlwaysOutput.isEmpty(), + "Non-empty Set must be supplied for includingDefaultValueFields."); + + checkUnsetIncludingDefaultValueFields(); return new Printer( registry, oldRegistry, - shouldPrintDefaults, - includingDefaultValueFields, + false, + Collections.unmodifiableSet(new HashSet<>(fieldsToAlwaysOutput)), preservingProtoFieldNames, omittingInsignificantWhitespace, - true, + printingEnumsAsInts, sortingMapKeys); } - private void checkUnsetPrintingEnumsAsInts() { - if (printingEnumsAsInts) { - throw new IllegalStateException("JsonFormat printingEnumsAsInts has already been set."); + private void checkUnsetIncludingDefaultValueFields() { + if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) { + throw new IllegalStateException( + "JsonFormat includingDefaultValueFields has already been set."); } } @@ -287,7 +261,7 @@ public class JsonFormat { return new Printer( registry, oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, true, omittingInsignificantWhitespace, @@ -316,7 +290,7 @@ public class JsonFormat { return new Printer( registry, oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, true, @@ -339,7 +313,7 @@ public class JsonFormat { return new Printer( registry, oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace, @@ -360,7 +334,7 @@ public class JsonFormat { new PrinterImpl( registry, oldRegistry, - shouldPrintDefaults, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, output, @@ -711,7 +685,7 @@ public class JsonFormat { private static final class PrinterImpl { private final com.google.protobuf.TypeRegistry registry; private final TypeRegistry oldRegistry; - private final ShouldPrintDefaults shouldPrintDefaults; + private final boolean alwaysOutputDefaultValueFields; private final Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; private final boolean printingEnumsAsInts; @@ -729,7 +703,7 @@ public class JsonFormat { PrinterImpl( com.google.protobuf.TypeRegistry registry, TypeRegistry oldRegistry, - ShouldPrintDefaults shouldPrintDefaults, + boolean alwaysOutputDefaultValueFields, Set includingDefaultValueFields, boolean preservingProtoFieldNames, Appendable jsonOutput, @@ -738,7 +712,7 @@ public class JsonFormat { boolean sortingMapKeys) { this.registry = registry; this.oldRegistry = oldRegistry; - this.shouldPrintDefaults = shouldPrintDefaults; + this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; this.printingEnumsAsInts = printingEnumsAsInts; @@ -991,24 +965,6 @@ public class JsonFormat { printRepeatedFieldValue(field, message.getField(field)); } - // Whether a set option means the corresponding field should be printed even if it normally - // wouldn't be. - private boolean shouldSpeciallyPrint(FieldDescriptor field) { - switch (shouldPrintDefaults) { - case ONLY_IF_PRESENT: - return false; - case ALWAYS_PRINT_EXCEPT_MESSAGES_AND_ONEOFS: - return !field.hasPresence() - || (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE - && field.getContainingOneof() == null); - case ALWAYS_PRINT_WITHOUT_PRESENCE_FIELDS: - return !field.hasPresence(); - case ALWAYS_PRINT_SPECIFIED_FIELDS: - return includingDefaultValueFields.contains(field); - } - throw new AssertionError("Unknown shouldPrintDefaults: " + shouldPrintDefaults); - } - /** Prints a regular message with an optional type URL. */ private void print(MessageOrBuilder message, @Nullable String typeUrl) throws IOException { generator.print("{" + blankOrNewLine); @@ -1019,23 +975,31 @@ public class JsonFormat { generator.print("\"@type\":" + blankOrSpace + gson.toJson(typeUrl)); printedField = true; } - - // message.getAllFields() will already contain all of the fields that would be - // printed normally (non-empty repeated fields, with-presence fields that are set, implicit - // presence fields that have a nonzero value). Loop over all of the fields to add any more - // fields that should be printed based on the shouldPrintDefaults setting. - Map fieldsToPrint; - if (shouldPrintDefaults == ShouldPrintDefaults.ONLY_IF_PRESENT) { - fieldsToPrint = message.getAllFields(); - } else { + Map fieldsToPrint = null; + if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) { fieldsToPrint = new TreeMap(message.getAllFields()); for (FieldDescriptor field : message.getDescriptorForType().getFields()) { - if (shouldSpeciallyPrint(field)) { + if (field.isOptional()) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE + && !message.hasField(field)) { + // Always skip empty optional message fields. If not we will recurse indefinitely if + // a message has itself as a sub-field. + continue; + } + OneofDescriptor oneof = field.getContainingOneof(); + if (oneof != null && !message.hasField(field)) { + // Skip all oneof fields except the one that is actually set + continue; + } + } + if (!fieldsToPrint.containsKey(field) + && (alwaysOutputDefaultValueFields || includingDefaultValueFields.contains(field))) { fieldsToPrint.put(field, message.getField(field)); } } + } else { + fieldsToPrint = message.getAllFields(); } - for (Map.Entry field : fieldsToPrint.entrySet()) { if (printedField) { // Add line-endings for the previous field. 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 36c31f49a0..6d75edb611 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 @@ -46,7 +46,6 @@ import com.google.protobuf.util.proto.JsonTestProto.TestRecursive; import com.google.protobuf.util.proto.JsonTestProto.TestStruct; import com.google.protobuf.util.proto.JsonTestProto.TestTimestamp; import com.google.protobuf.util.proto.JsonTestProto.TestWrappers; -import com.google.protobuf.util.proto.JsonTestProto2.TestAllTypesProto2; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -1484,60 +1483,48 @@ public class JsonFormatTest { } @Test - public void testDefaultValueOptionsProto3() throws Exception { + public void testIncludingDefaultValueFields() throws Exception { TestAllTypes message = TestAllTypes.getDefaultInstance(); assertThat(JsonFormat.printer().print(message)).isEqualTo("{\n}"); - - String expectedJsonWithDefaults = - "{\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" - + "}"; - - // includingDefaultValueFields() and includingDefaultValueWithoutPresenceFields() should - // behave identically on the proto3 test message: assertThat(JsonFormat.printer().includingDefaultValueFields().print(message)) - .isEqualTo(expectedJsonWithDefaults); - assertThat(JsonFormat.printer().includingDefaultValueWithoutPresenceFields().print(message)) - .isEqualTo(expectedJsonWithDefaults); - } + .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" + + "}"); - @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")) { @@ -1566,16 +1553,7 @@ public class JsonFormatTest { + " \"repeatedFixed32\": [],\n" + " \"repeatedFixed64\": []\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(); @@ -1656,10 +1634,7 @@ public class JsonFormatTest { .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)) @@ -1722,25 +1697,16 @@ public class JsonFormatTest { + " \"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().includingDefaultValueWithoutPresenceFields().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().includingDefaultValueWithoutPresenceFields().print(oneofMessage)) - .isEqualTo("{\n \"oneofInt32\": 42\n}"); TestOneof.Builder oneofBuilder = TestOneof.newBuilder(); mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder); @@ -1749,113 +1715,6 @@ public class JsonFormatTest { .isEqualTo("{\n \"oneofNullValue\": null\n}"); assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) .isEqualTo("{\n \"oneofNullValue\": null\n}"); - assertThat( - JsonFormat.printer().includingDefaultValueWithoutPresenceFields().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 includingDefaultValueWithoutPresenceFields() - // 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().includingDefaultValueWithoutPresenceFields().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(); - - Set fixedFields = new HashSet<>(); - for (FieldDescriptor fieldDesc : TestAllTypesProto2.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" - + "}"); - - TestAllTypesProto2 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 diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto index 28831198fb..34c951005b 100644 --- a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto +++ b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto @@ -58,9 +58,6 @@ message TestAllTypes { NestedMessage optional_nested_message = 18; NestedEnum optional_nested_enum = 21; AliasedEnum optional_aliased_enum = 52; - TestRecursive optional_recursive = 53; - - optional int32 explicit_presence_int32 = 54; // Repeated repeated int32 repeated_int32 = 31; @@ -80,7 +77,6 @@ message TestAllTypes { repeated bytes repeated_bytes = 45; repeated NestedMessage repeated_nested_message = 48; repeated NestedEnum repeated_nested_enum = 51; - repeated TestRecursive repeated_recursive = 55; } message TestOneof { diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test_proto2.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test_proto2.proto deleted file mode 100644 index 5cec400057..0000000000 --- a/java/util/src/test/proto/com/google/protobuf/util/json_test_proto2.proto +++ /dev/null @@ -1,80 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -syntax = "proto2"; - -package json_test_proto2; - -option java_package = "com.google.protobuf.util.proto"; -option java_outer_classname = "JsonTestProto2"; - -message TestAllTypesProto2 { - enum NestedEnum { - FOO = 0; - BAR = 1; - BAZ = 2; - } - - enum AliasedEnum { - option allow_alias = true; - - ALIAS_FOO = 0; - ALIAS_BAR = 1; - ALIAS_BAZ = 2; - QUX = 2; - qux = 2; - bAz = 2; - } - message NestedMessage { - optional int32 value = 1; - } - - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - optional NestedMessage optional_nested_message = 18; - optional NestedEnum optional_nested_enum = 21; - optional AliasedEnum optional_aliased_enum = 52; - optional TestRecursive optional_recursive = 53; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - repeated NestedMessage repeated_nested_message = 48; - repeated NestedEnum repeated_nested_enum = 51; - repeated TestRecursive repeated_recursive = 55; -} - -message TestRecursive { - optional int32 value = 1; - optional TestRecursive nested = 2; -}