From 92a7e778e7394386f413cec28d67a07630f784b1 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 1 Dec 2017 10:05:10 -0800 Subject: Integrated internal changes from Google --- .../java/com/google/protobuf/util/JsonFormat.java | 57 +++++++++++++++++----- .../java/com/google/protobuf/util/Timestamps.java | 11 ++++- .../com/google/protobuf/util/JsonFormatTest.java | 15 ++++++ 3 files changed, 70 insertions(+), 13 deletions(-) (limited to 'java/util') 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 a26dbc2d..7f69ee68 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 @@ -105,7 +105,7 @@ public class JsonFormat { public static Printer printer() { return new Printer( TypeRegistry.getEmptyTypeRegistry(), false, Collections.emptySet(), - false, false); + false, false, false); } /** @@ -125,18 +125,21 @@ public class JsonFormat { private Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; private final boolean omittingInsignificantWhitespace; + private final boolean printingEnumsAsInts; private Printer( TypeRegistry registry, boolean alwaysOutputDefaultValueFields, Set includingDefaultValueFields, boolean preservingProtoFieldNames, - boolean omittingInsignificantWhitespace) { + boolean omittingInsignificantWhitespace, + boolean printingEnumsAsInts) { this.registry = registry; this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; this.omittingInsignificantWhitespace = omittingInsignificantWhitespace; + this.printingEnumsAsInts = printingEnumsAsInts; } /** @@ -154,7 +157,8 @@ public class JsonFormat { alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, - omittingInsignificantWhitespace); + omittingInsignificantWhitespace, + printingEnumsAsInts); } /** @@ -170,7 +174,31 @@ public class JsonFormat { true, Collections.emptySet(), preservingProtoFieldNames, - omittingInsignificantWhitespace); + omittingInsignificantWhitespace, + printingEnumsAsInts); + } + + /** + * Creates a new {@link Printer} that will print enum field values as integers instead of as + * string. + * The new Printer clones all other configurations from the current + * {@link Printer}. + */ + public Printer printingEnumsAsInts() { + checkUnsetPrintingEnumsAsInts(); + return new Printer( + registry, + alwaysOutputDefaultValueFields, + Collections.emptySet(), + preservingProtoFieldNames, + omittingInsignificantWhitespace, + true); + } + + private void checkUnsetPrintingEnumsAsInts() { + if (printingEnumsAsInts) { + throw new IllegalStateException("JsonFormat printingEnumsAsInts has already been set."); + } } /** @@ -191,7 +219,8 @@ public class JsonFormat { false, fieldsToAlwaysOutput, preservingProtoFieldNames, - omittingInsignificantWhitespace); + omittingInsignificantWhitespace, + printingEnumsAsInts); } private void checkUnsetIncludingDefaultValueFields() { @@ -213,7 +242,8 @@ public class JsonFormat { alwaysOutputDefaultValueFields, includingDefaultValueFields, true, - omittingInsignificantWhitespace); + omittingInsignificantWhitespace, + printingEnumsAsInts); } @@ -240,7 +270,8 @@ public class JsonFormat { alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, - true); + true, + printingEnumsAsInts); } /** @@ -259,7 +290,8 @@ public class JsonFormat { includingDefaultValueFields, preservingProtoFieldNames, output, - omittingInsignificantWhitespace) + omittingInsignificantWhitespace, + printingEnumsAsInts) .print(message); } @@ -416,7 +448,7 @@ public class JsonFormat { */ public Builder add(Iterable messageTypes) { if (types == null) { - throw new IllegalStateException("A TypeRegistry.Builer can only be used once."); + throw new IllegalStateException("A TypeRegistry.Builder can only be used once."); } for (Descriptor type : messageTypes) { addFile(type.getFile()); @@ -570,6 +602,7 @@ public class JsonFormat { private final boolean alwaysOutputDefaultValueFields; private final Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; + private final boolean printingEnumsAsInts; private final TextGenerator generator; // We use Gson to help handle string escapes. private final Gson gson; @@ -586,11 +619,13 @@ public class JsonFormat { Set includingDefaultValueFields, boolean preservingProtoFieldNames, Appendable jsonOutput, - boolean omittingInsignificantWhitespace) { + boolean omittingInsignificantWhitespace, + boolean printingEnumsAsInts) { this.registry = registry; this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; + this.printingEnumsAsInts = printingEnumsAsInts; this.gson = GsonHolder.DEFAULT_GSON; // json format related properties, determined by printerType if (omittingInsignificantWhitespace) { @@ -1069,7 +1104,7 @@ public class JsonFormat { generator.print("\""); } } else { - if (((EnumValueDescriptor) value).getIndex() == -1) { + if (printingEnumsAsInts || ((EnumValueDescriptor) value).getIndex() == -1) { generator.print(String.valueOf(((EnumValueDescriptor) value).getNumber())); } else { generator.print("\"" + ((EnumValueDescriptor) value).getName() + "\""); diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 7a1f2014..9e528d4a 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -74,6 +74,11 @@ public final class Timestamps { public static final Timestamp MAX_VALUE = Timestamp.newBuilder().setSeconds(TIMESTAMP_SECONDS_MAX).setNanos(999999999).build(); + /** + * A constant holding the {@link Timestamp} of epoch time, {@code 1970-01-01T00:00:00.000000000Z}. + */ + public static final Timestamp EPOCH = Timestamp.newBuilder().setSeconds(0).setNanos(0).build(); + private static final ThreadLocal timestampFormat = new ThreadLocal() { @Override @@ -358,10 +363,12 @@ public final class Timestamps { static Timestamp normalizedTimestamp(long seconds, int nanos) { if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) { seconds = checkedAdd(seconds, nanos / NANOS_PER_SECOND); - nanos %= NANOS_PER_SECOND; + nanos = (int) (nanos % NANOS_PER_SECOND); } if (nanos < 0) { - nanos += NANOS_PER_SECOND; // no overflow since nanos is negative (and we're adding) + nanos = + (int) + (nanos + NANOS_PER_SECOND); // no overflow since nanos is negative (and we're adding) seconds = checkedSubtract(seconds, 1); } Timestamp timestamp = Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); 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 e4c5387a..6ef08508 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 @@ -1174,6 +1174,14 @@ public class JsonFormatTest extends TestCase { JsonFormat.parser().ignoringUnknownFields().merge(json, builder); } + public void testParserIntegerEnumValue() throws Exception { + TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); + mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder); + + TestAllTypes expected = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAZ).build(); + assertEquals(expected, actualBuilder.build()); + } + public void testCustomJsonName() throws Exception { TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build(); assertEquals("{\n" + " \"@value\": 12345\n" + "}", JsonFormat.printer().print(message)); @@ -1441,6 +1449,13 @@ public class JsonFormatTest extends TestCase { assertEquals(54321, builder.getOptionalInt32()); } + public void testPrintingEnumsAsInts() throws Exception { + TestAllTypes message = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAR).build(); + assertEquals( + "{\n" + " \"optionalNestedEnum\": 1\n" + "}", + JsonFormat.printer().printingEnumsAsInts().print(message)); + } + public void testOmittingInsignificantWhiteSpace() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build(); assertEquals( -- cgit v1.2.3