Automated rollback of commit 58baeb4c3b.

PiperOrigin-RevId: 602770552
pull/15647/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 2b86c3d9ed
commit 44ec9d9e86
  1. 198
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  2. 217
      java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
  3. 4
      java/util/src/test/proto/com/google/protobuf/util/json_test.proto
  4. 80
      java/util/src/test/proto/com/google/protobuf/util/json_test_proto2.proto

@ -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.<FieldDescriptor>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<FieldDescriptor> 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<FieldDescriptor>) 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<FieldDescriptor> 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<FieldDescriptor> 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.
*
* <p>Note that this does print Proto2 Optional but does not print Proto3 Optional fields, as
* the latter is represented using a synthetic oneof.
*
* <p>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.<FieldDescriptor>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<FieldDescriptor> 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<FieldDescriptor> 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<FieldDescriptor> 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<FieldDescriptor> 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<FieldDescriptor, Object> fieldsToPrint;
if (shouldPrintDefaults == ShouldPrintDefaults.ONLY_IF_PRESENT) {
fieldsToPrint = message.getAllFields();
} else {
Map<FieldDescriptor, Object> fieldsToPrint = null;
if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) {
fieldsToPrint = new TreeMap<FieldDescriptor, Object>(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<FieldDescriptor, Object> field : fieldsToPrint.entrySet()) {
if (printedField) {
// Add line-endings for the previous field.

@ -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<FieldDescriptor> 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<FieldDescriptor> 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<FieldDescriptor> 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

@ -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 {

@ -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;
}
Loading…
Cancel
Save