JsonFormatTest.java
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf.util;
32 
33 import com.google.protobuf.Any;
40 import com.google.protobuf.FloatValue;
42 import com.google.protobuf.Int64Value;
45 import com.google.protobuf.Message;
46 import com.google.protobuf.NullValue;
48 import com.google.protobuf.Struct;
51 import com.google.protobuf.Value;
53 import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes;
54 import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.AliasedEnum;
55 import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.NestedEnum;
56 import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.NestedMessage;
57 import com.google.protobuf.util.proto.JsonTestProto.TestAny;
58 import com.google.protobuf.util.proto.JsonTestProto.TestCustomJsonName;
59 import com.google.protobuf.util.proto.JsonTestProto.TestDuration;
60 import com.google.protobuf.util.proto.JsonTestProto.TestFieldMask;
61 import com.google.protobuf.util.proto.JsonTestProto.TestMap;
62 import com.google.protobuf.util.proto.JsonTestProto.TestOneof;
63 import com.google.protobuf.util.proto.JsonTestProto.TestRecursive;
64 import com.google.protobuf.util.proto.JsonTestProto.TestStruct;
65 import com.google.protobuf.util.proto.JsonTestProto.TestTimestamp;
66 import com.google.protobuf.util.proto.JsonTestProto.TestWrappers;
67 import java.io.IOException;
68 import java.io.InputStream;
69 import java.io.InputStreamReader;
70 import java.io.Reader;
71 import java.io.StringReader;
72 import java.math.BigDecimal;
73 import java.math.BigInteger;
74 import java.util.Collections;
75 import java.util.HashSet;
76 import java.util.Locale;
77 import java.util.Set;
78 import junit.framework.TestCase;
79 
80 public class JsonFormatTest extends TestCase {
81  public JsonFormatTest() {
82  // Test that locale does not affect JsonFormat.
83  Locale.setDefault(Locale.forLanguageTag("hi-IN"));
84  }
85 
86  private void setAllFields(TestAllTypes.Builder builder) {
87  builder.setOptionalInt32(1234);
88  builder.setOptionalInt64(1234567890123456789L);
89  builder.setOptionalUint32(5678);
90  builder.setOptionalUint64(2345678901234567890L);
91  builder.setOptionalSint32(9012);
92  builder.setOptionalSint64(3456789012345678901L);
93  builder.setOptionalFixed32(3456);
94  builder.setOptionalFixed64(4567890123456789012L);
95  builder.setOptionalSfixed32(7890);
96  builder.setOptionalSfixed64(5678901234567890123L);
97  builder.setOptionalFloat(1.5f);
98  builder.setOptionalDouble(1.25);
99  builder.setOptionalBool(true);
100  builder.setOptionalString("Hello world!");
101  builder.setOptionalBytes(ByteString.copyFrom(new byte[] {0, 1, 2}));
102  builder.setOptionalNestedEnum(NestedEnum.BAR);
103  builder.getOptionalNestedMessageBuilder().setValue(100);
104 
105  builder.addRepeatedInt32(1234);
106  builder.addRepeatedInt64(1234567890123456789L);
107  builder.addRepeatedUint32(5678);
108  builder.addRepeatedUint64(2345678901234567890L);
109  builder.addRepeatedSint32(9012);
110  builder.addRepeatedSint64(3456789012345678901L);
111  builder.addRepeatedFixed32(3456);
112  builder.addRepeatedFixed64(4567890123456789012L);
113  builder.addRepeatedSfixed32(7890);
114  builder.addRepeatedSfixed64(5678901234567890123L);
115  builder.addRepeatedFloat(1.5f);
116  builder.addRepeatedDouble(1.25);
117  builder.addRepeatedBool(true);
118  builder.addRepeatedString("Hello world!");
119  builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {0, 1, 2}));
120  builder.addRepeatedNestedEnum(NestedEnum.BAR);
121  builder.addRepeatedNestedMessageBuilder().setValue(100);
122 
123  builder.addRepeatedInt32(234);
124  builder.addRepeatedInt64(234567890123456789L);
125  builder.addRepeatedUint32(678);
126  builder.addRepeatedUint64(345678901234567890L);
127  builder.addRepeatedSint32(012);
128  builder.addRepeatedSint64(456789012345678901L);
129  builder.addRepeatedFixed32(456);
130  builder.addRepeatedFixed64(567890123456789012L);
131  builder.addRepeatedSfixed32(890);
132  builder.addRepeatedSfixed64(678901234567890123L);
133  builder.addRepeatedFloat(11.5f);
134  builder.addRepeatedDouble(11.25);
135  builder.addRepeatedBool(true);
136  builder.addRepeatedString("ello world!");
137  builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {1, 2}));
138  builder.addRepeatedNestedEnum(NestedEnum.BAZ);
139  builder.addRepeatedNestedMessageBuilder().setValue(200);
140  }
141 
142  private void assertRoundTripEquals(Message message) throws Exception {
144  }
145 
146  private void assertRoundTripEquals(Message message, TypeRegistry registry) throws Exception {
147  JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry);
149  Message.Builder builder = message.newBuilderForType();
150  parser.merge(printer.print(message), builder);
151  Message parsedMessage = builder.build();
152  assertEquals(message.toString(), parsedMessage.toString());
153  }
154 
155  private String toJsonString(Message message) throws IOException {
156  return JsonFormat.printer().print(message);
157  }
158  private String toCompactJsonString(Message message) throws IOException {
160  }
161  private String toSortedJsonString(Message message) throws IOException {
162  return JsonFormat.printer().sortingMapKeys().print(message);
163  }
164 
165  private void mergeFromJson(String json, Message.Builder builder) throws IOException {
166  JsonFormat.parser().merge(json, builder);
167  }
168 
169  private void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder)
170  throws IOException {
171  JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
172  }
173 
174  public void testAllFields() throws Exception {
175  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
176  setAllFields(builder);
177  TestAllTypes message = builder.build();
178 
179  assertEquals(
180  "{\n"
181  + " \"optionalInt32\": 1234,\n"
182  + " \"optionalInt64\": \"1234567890123456789\",\n"
183  + " \"optionalUint32\": 5678,\n"
184  + " \"optionalUint64\": \"2345678901234567890\",\n"
185  + " \"optionalSint32\": 9012,\n"
186  + " \"optionalSint64\": \"3456789012345678901\",\n"
187  + " \"optionalFixed32\": 3456,\n"
188  + " \"optionalFixed64\": \"4567890123456789012\",\n"
189  + " \"optionalSfixed32\": 7890,\n"
190  + " \"optionalSfixed64\": \"5678901234567890123\",\n"
191  + " \"optionalFloat\": 1.5,\n"
192  + " \"optionalDouble\": 1.25,\n"
193  + " \"optionalBool\": true,\n"
194  + " \"optionalString\": \"Hello world!\",\n"
195  + " \"optionalBytes\": \"AAEC\",\n"
196  + " \"optionalNestedMessage\": {\n"
197  + " \"value\": 100\n"
198  + " },\n"
199  + " \"optionalNestedEnum\": \"BAR\",\n"
200  + " \"repeatedInt32\": [1234, 234],\n"
201  + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n"
202  + " \"repeatedUint32\": [5678, 678],\n"
203  + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n"
204  + " \"repeatedSint32\": [9012, 10],\n"
205  + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n"
206  + " \"repeatedFixed32\": [3456, 456],\n"
207  + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n"
208  + " \"repeatedSfixed32\": [7890, 890],\n"
209  + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n"
210  + " \"repeatedFloat\": [1.5, 11.5],\n"
211  + " \"repeatedDouble\": [1.25, 11.25],\n"
212  + " \"repeatedBool\": [true, true],\n"
213  + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n"
214  + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n"
215  + " \"repeatedNestedMessage\": [{\n"
216  + " \"value\": 100\n"
217  + " }, {\n"
218  + " \"value\": 200\n"
219  + " }],\n"
220  + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n"
221  + "}",
223 
225  }
226 
227  public void testUnknownEnumValues() throws Exception {
228  TestAllTypes message =
229  TestAllTypes.newBuilder()
230  .setOptionalNestedEnumValue(12345)
231  .addRepeatedNestedEnumValue(12345)
232  .addRepeatedNestedEnumValue(0)
233  .build();
234  assertEquals(
235  "{\n"
236  + " \"optionalNestedEnum\": 12345,\n"
237  + " \"repeatedNestedEnum\": [12345, \"FOO\"]\n"
238  + "}",
241 
242  TestMap.Builder mapBuilder = TestMap.newBuilder();
243  mapBuilder.putInt32ToEnumMapValue(1, 0);
244  mapBuilder.putInt32ToEnumMapValue(2, 12345);
245  TestMap mapMessage = mapBuilder.build();
246  assertEquals(
247  "{\n"
248  + " \"int32ToEnumMap\": {\n"
249  + " \"1\": \"FOO\",\n"
250  + " \"2\": 12345\n"
251  + " }\n"
252  + "}",
253  toJsonString(mapMessage));
254  assertRoundTripEquals(mapMessage);
255  }
256 
257  public void testSpecialFloatValues() throws Exception {
258  TestAllTypes message =
259  TestAllTypes.newBuilder()
260  .addRepeatedFloat(Float.NaN)
261  .addRepeatedFloat(Float.POSITIVE_INFINITY)
262  .addRepeatedFloat(Float.NEGATIVE_INFINITY)
263  .addRepeatedDouble(Double.NaN)
264  .addRepeatedDouble(Double.POSITIVE_INFINITY)
265  .addRepeatedDouble(Double.NEGATIVE_INFINITY)
266  .build();
267  assertEquals(
268  "{\n"
269  + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n"
270  + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n"
271  + "}",
273 
275  }
276 
277  public void testParserAcceptStringForNumericField() throws Exception {
278  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
280  "{\n"
281  + " \"optionalInt32\": \"1234\",\n"
282  + " \"optionalUint32\": \"5678\",\n"
283  + " \"optionalSint32\": \"9012\",\n"
284  + " \"optionalFixed32\": \"3456\",\n"
285  + " \"optionalSfixed32\": \"7890\",\n"
286  + " \"optionalFloat\": \"1.5\",\n"
287  + " \"optionalDouble\": \"1.25\",\n"
288  + " \"optionalBool\": \"true\"\n"
289  + "}",
290  builder);
291  TestAllTypes message = builder.build();
292  assertEquals(1234, message.getOptionalInt32());
293  assertEquals(5678, message.getOptionalUint32());
294  assertEquals(9012, message.getOptionalSint32());
295  assertEquals(3456, message.getOptionalFixed32());
296  assertEquals(7890, message.getOptionalSfixed32());
297  assertEquals(1.5f, message.getOptionalFloat(), 0.0f);
298  assertEquals(1.25, message.getOptionalDouble(), 0.0);
299  assertEquals(true, message.getOptionalBool());
300  }
301 
302  public void testParserAcceptFloatingPointValueForIntegerField() throws Exception {
303  // Test that numeric values like "1.000", "1e5" will also be accepted.
304  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
306  "{\n"
307  + " \"repeatedInt32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
308  + " \"repeatedUint32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
309  + " \"repeatedInt64\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
310  + " \"repeatedUint64\": [1.000, 1e5, \"1.000\", \"1e5\"]\n"
311  + "}",
312  builder);
313  int[] expectedValues = new int[] {1, 100000, 1, 100000};
314  assertEquals(4, builder.getRepeatedInt32Count());
315  assertEquals(4, builder.getRepeatedUint32Count());
316  assertEquals(4, builder.getRepeatedInt64Count());
317  assertEquals(4, builder.getRepeatedUint64Count());
318  for (int i = 0; i < 4; ++i) {
319  assertEquals(expectedValues[i], builder.getRepeatedInt32(i));
320  assertEquals(expectedValues[i], builder.getRepeatedUint32(i));
321  assertEquals(expectedValues[i], builder.getRepeatedInt64(i));
322  assertEquals(expectedValues[i], builder.getRepeatedUint64(i));
323  }
324 
325  // Non-integers will still be rejected.
326  assertRejects("optionalInt32", "1.5");
327  assertRejects("optionalUint32", "1.5");
328  assertRejects("optionalInt64", "1.5");
329  assertRejects("optionalUint64", "1.5");
330  }
331 
332  private void assertRejects(String name, String value) {
333  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
334  try {
335  // Numeric form is rejected.
336  mergeFromJson("{\"" + name + "\":" + value + "}", builder);
337  fail("Exception is expected.");
338  } catch (IOException e) {
339  // Expected.
340  }
341  try {
342  // String form is also rejected.
343  mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder);
344  fail("Exception is expected.");
345  } catch (IOException e) {
346  // Expected.
347  }
348  }
349 
350  private void assertAccepts(String name, String value) throws IOException {
351  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
352  // Both numeric form and string form are accepted.
353  mergeFromJson("{\"" + name + "\":" + value + "}", builder);
354  builder.clear();
355  mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder);
356  }
357 
358  public void testParserRejectOutOfRangeNumericValues() throws Exception {
359  assertAccepts("optionalInt32", String.valueOf(Integer.MAX_VALUE));
360  assertAccepts("optionalInt32", String.valueOf(Integer.MIN_VALUE));
361  assertRejects("optionalInt32", String.valueOf(Integer.MAX_VALUE + 1L));
362  assertRejects("optionalInt32", String.valueOf(Integer.MIN_VALUE - 1L));
363 
364  assertAccepts("optionalUint32", String.valueOf(Integer.MAX_VALUE + 1L));
365  assertRejects("optionalUint32", "123456789012345");
366  assertRejects("optionalUint32", "-1");
367 
368  BigInteger one = new BigInteger("1");
369  BigInteger maxLong = new BigInteger(String.valueOf(Long.MAX_VALUE));
370  BigInteger minLong = new BigInteger(String.valueOf(Long.MIN_VALUE));
371  assertAccepts("optionalInt64", maxLong.toString());
372  assertAccepts("optionalInt64", minLong.toString());
373  assertRejects("optionalInt64", maxLong.add(one).toString());
374  assertRejects("optionalInt64", minLong.subtract(one).toString());
375 
376  assertAccepts("optionalUint64", maxLong.add(one).toString());
377  assertRejects("optionalUint64", "1234567890123456789012345");
378  assertRejects("optionalUint64", "-1");
379 
380  assertAccepts("optionalBool", "true");
381  assertRejects("optionalBool", "1");
382  assertRejects("optionalBool", "0");
383 
384  assertAccepts("optionalFloat", String.valueOf(Float.MAX_VALUE));
385  assertAccepts("optionalFloat", String.valueOf(-Float.MAX_VALUE));
386  assertRejects("optionalFloat", String.valueOf(Double.MAX_VALUE));
387  assertRejects("optionalFloat", String.valueOf(-Double.MAX_VALUE));
388 
389  BigDecimal moreThanOne = new BigDecimal("1.000001");
390  BigDecimal maxDouble = new BigDecimal(Double.MAX_VALUE);
391  BigDecimal minDouble = new BigDecimal(-Double.MAX_VALUE);
392  assertAccepts("optionalDouble", maxDouble.toString());
393  assertAccepts("optionalDouble", minDouble.toString());
394  assertRejects("optionalDouble", maxDouble.multiply(moreThanOne).toString());
395  assertRejects("optionalDouble", minDouble.multiply(moreThanOne).toString());
396  }
397 
398  public void testParserAcceptNull() throws Exception {
399  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
401  "{\n"
402  + " \"optionalInt32\": null,\n"
403  + " \"optionalInt64\": null,\n"
404  + " \"optionalUint32\": null,\n"
405  + " \"optionalUint64\": null,\n"
406  + " \"optionalSint32\": null,\n"
407  + " \"optionalSint64\": null,\n"
408  + " \"optionalFixed32\": null,\n"
409  + " \"optionalFixed64\": null,\n"
410  + " \"optionalSfixed32\": null,\n"
411  + " \"optionalSfixed64\": null,\n"
412  + " \"optionalFloat\": null,\n"
413  + " \"optionalDouble\": null,\n"
414  + " \"optionalBool\": null,\n"
415  + " \"optionalString\": null,\n"
416  + " \"optionalBytes\": null,\n"
417  + " \"optionalNestedMessage\": null,\n"
418  + " \"optionalNestedEnum\": null,\n"
419  + " \"repeatedInt32\": null,\n"
420  + " \"repeatedInt64\": null,\n"
421  + " \"repeatedUint32\": null,\n"
422  + " \"repeatedUint64\": null,\n"
423  + " \"repeatedSint32\": null,\n"
424  + " \"repeatedSint64\": null,\n"
425  + " \"repeatedFixed32\": null,\n"
426  + " \"repeatedFixed64\": null,\n"
427  + " \"repeatedSfixed32\": null,\n"
428  + " \"repeatedSfixed64\": null,\n"
429  + " \"repeatedFloat\": null,\n"
430  + " \"repeatedDouble\": null,\n"
431  + " \"repeatedBool\": null,\n"
432  + " \"repeatedString\": null,\n"
433  + " \"repeatedBytes\": null,\n"
434  + " \"repeatedNestedMessage\": null,\n"
435  + " \"repeatedNestedEnum\": null\n"
436  + "}",
437  builder);
438  TestAllTypes message = builder.build();
439  assertEquals(TestAllTypes.getDefaultInstance(), message);
440 
441  // Repeated field elements cannot be null.
442  try {
443  builder = TestAllTypes.newBuilder();
444  mergeFromJson("{\n" + " \"repeatedInt32\": [null, null],\n" + "}", builder);
445  fail();
446  } catch (InvalidProtocolBufferException e) {
447  // Exception expected.
448  }
449 
450  try {
451  builder = TestAllTypes.newBuilder();
452  mergeFromJson("{\n" + " \"repeatedNestedMessage\": [null, null],\n" + "}", builder);
453  fail();
454  } catch (InvalidProtocolBufferException e) {
455  // Exception expected.
456  }
457  }
458 
459  public void testNullInOneof() throws Exception {
460  TestOneof.Builder builder = TestOneof.newBuilder();
461  mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", builder);
462  TestOneof message = builder.build();
463  assertEquals(TestOneof.OneofFieldCase.ONEOF_NULL_VALUE, message.getOneofFieldCase());
464  assertEquals(NullValue.NULL_VALUE, message.getOneofNullValue());
465  }
466 
467  public void testNullFirstInDuplicateOneof() throws Exception {
468  TestOneof.Builder builder = TestOneof.newBuilder();
469  mergeFromJson("{\"oneofNestedMessage\": null, \"oneofInt32\": 1}", builder);
470  TestOneof message = builder.build();
471  assertEquals(1, message.getOneofInt32());
472  }
473 
474  public void testNullLastInDuplicateOneof() throws Exception {
475  TestOneof.Builder builder = TestOneof.newBuilder();
476  mergeFromJson("{\"oneofInt32\": 1, \"oneofNestedMessage\": null}", builder);
477  TestOneof message = builder.build();
478  assertEquals(1, message.getOneofInt32());
479  }
480 
481  public void testParserRejectDuplicatedFields() throws Exception {
482  // TODO(xiaofeng): The parser we are currently using (GSON) will accept and keep the last
483  // one if multiple entries have the same name. This is not the desired behavior but it can
484  // only be fixed by using our own parser. Here we only test the cases where the names are
485  // different but still referring to the same field.
486 
487  // Duplicated optional fields.
488  try {
489  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
491  "{\n"
492  + " \"optionalNestedMessage\": {},\n"
493  + " \"optional_nested_message\": {}\n"
494  + "}",
495  builder);
496  fail();
497  } catch (InvalidProtocolBufferException e) {
498  // Exception expected.
499  }
500 
501  // Duplicated repeated fields.
502  try {
503  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
505  "{\n"
506  + " \"repeatedInt32\": [1, 2],\n"
507  + " \"repeated_int32\": [5, 6]\n"
508  + "}",
509  builder);
510  fail();
511  } catch (InvalidProtocolBufferException e) {
512  // Exception expected.
513  }
514 
515  // Duplicated oneof fields, same name.
516  try {
517  TestOneof.Builder builder = TestOneof.newBuilder();
518  mergeFromJson("{\n" + " \"oneofInt32\": 1,\n" + " \"oneof_int32\": 2\n" + "}", builder);
519  fail();
520  } catch (InvalidProtocolBufferException e) {
521  // Exception expected.
522  }
523 
524  // Duplicated oneof fields, different name.
525  try {
526  TestOneof.Builder builder = TestOneof.newBuilder();
528  "{\n" + " \"oneofInt32\": 1,\n" + " \"oneofNullValue\": null\n" + "}", builder);
529  fail();
530  } catch (InvalidProtocolBufferException e) {
531  // Exception expected.
532  }
533  }
534 
535  public void testMapFields() throws Exception {
536  TestMap.Builder builder = TestMap.newBuilder();
537  builder.putInt32ToInt32Map(1, 10);
538  builder.putInt64ToInt32Map(1234567890123456789L, 10);
539  builder.putUint32ToInt32Map(2, 20);
540  builder.putUint64ToInt32Map(2234567890123456789L, 20);
541  builder.putSint32ToInt32Map(3, 30);
542  builder.putSint64ToInt32Map(3234567890123456789L, 30);
543  builder.putFixed32ToInt32Map(4, 40);
544  builder.putFixed64ToInt32Map(4234567890123456789L, 40);
545  builder.putSfixed32ToInt32Map(5, 50);
546  builder.putSfixed64ToInt32Map(5234567890123456789L, 50);
547  builder.putBoolToInt32Map(false, 6);
548  builder.putStringToInt32Map("Hello", 10);
549 
550  builder.putInt32ToInt64Map(1, 1234567890123456789L);
551  builder.putInt32ToUint32Map(2, 20);
552  builder.putInt32ToUint64Map(2, 2234567890123456789L);
553  builder.putInt32ToSint32Map(3, 30);
554  builder.putInt32ToSint64Map(3, 3234567890123456789L);
555  builder.putInt32ToFixed32Map(4, 40);
556  builder.putInt32ToFixed64Map(4, 4234567890123456789L);
557  builder.putInt32ToSfixed32Map(5, 50);
558  builder.putInt32ToSfixed64Map(5, 5234567890123456789L);
559  builder.putInt32ToFloatMap(6, 1.5f);
560  builder.putInt32ToDoubleMap(6, 1.25);
561  builder.putInt32ToBoolMap(7, false);
562  builder.putInt32ToStringMap(7, "World");
563  builder.putInt32ToBytesMap(8, ByteString.copyFrom(new byte[] {1, 2, 3}));
564  builder.putInt32ToMessageMap(8, NestedMessage.newBuilder().setValue(1234).build());
565  builder.putInt32ToEnumMap(9, NestedEnum.BAR);
566  TestMap message = builder.build();
567 
568  assertEquals(
569  "{\n"
570  + " \"int32ToInt32Map\": {\n"
571  + " \"1\": 10\n"
572  + " },\n"
573  + " \"int64ToInt32Map\": {\n"
574  + " \"1234567890123456789\": 10\n"
575  + " },\n"
576  + " \"uint32ToInt32Map\": {\n"
577  + " \"2\": 20\n"
578  + " },\n"
579  + " \"uint64ToInt32Map\": {\n"
580  + " \"2234567890123456789\": 20\n"
581  + " },\n"
582  + " \"sint32ToInt32Map\": {\n"
583  + " \"3\": 30\n"
584  + " },\n"
585  + " \"sint64ToInt32Map\": {\n"
586  + " \"3234567890123456789\": 30\n"
587  + " },\n"
588  + " \"fixed32ToInt32Map\": {\n"
589  + " \"4\": 40\n"
590  + " },\n"
591  + " \"fixed64ToInt32Map\": {\n"
592  + " \"4234567890123456789\": 40\n"
593  + " },\n"
594  + " \"sfixed32ToInt32Map\": {\n"
595  + " \"5\": 50\n"
596  + " },\n"
597  + " \"sfixed64ToInt32Map\": {\n"
598  + " \"5234567890123456789\": 50\n"
599  + " },\n"
600  + " \"boolToInt32Map\": {\n"
601  + " \"false\": 6\n"
602  + " },\n"
603  + " \"stringToInt32Map\": {\n"
604  + " \"Hello\": 10\n"
605  + " },\n"
606  + " \"int32ToInt64Map\": {\n"
607  + " \"1\": \"1234567890123456789\"\n"
608  + " },\n"
609  + " \"int32ToUint32Map\": {\n"
610  + " \"2\": 20\n"
611  + " },\n"
612  + " \"int32ToUint64Map\": {\n"
613  + " \"2\": \"2234567890123456789\"\n"
614  + " },\n"
615  + " \"int32ToSint32Map\": {\n"
616  + " \"3\": 30\n"
617  + " },\n"
618  + " \"int32ToSint64Map\": {\n"
619  + " \"3\": \"3234567890123456789\"\n"
620  + " },\n"
621  + " \"int32ToFixed32Map\": {\n"
622  + " \"4\": 40\n"
623  + " },\n"
624  + " \"int32ToFixed64Map\": {\n"
625  + " \"4\": \"4234567890123456789\"\n"
626  + " },\n"
627  + " \"int32ToSfixed32Map\": {\n"
628  + " \"5\": 50\n"
629  + " },\n"
630  + " \"int32ToSfixed64Map\": {\n"
631  + " \"5\": \"5234567890123456789\"\n"
632  + " },\n"
633  + " \"int32ToFloatMap\": {\n"
634  + " \"6\": 1.5\n"
635  + " },\n"
636  + " \"int32ToDoubleMap\": {\n"
637  + " \"6\": 1.25\n"
638  + " },\n"
639  + " \"int32ToBoolMap\": {\n"
640  + " \"7\": false\n"
641  + " },\n"
642  + " \"int32ToStringMap\": {\n"
643  + " \"7\": \"World\"\n"
644  + " },\n"
645  + " \"int32ToBytesMap\": {\n"
646  + " \"8\": \"AQID\"\n"
647  + " },\n"
648  + " \"int32ToMessageMap\": {\n"
649  + " \"8\": {\n"
650  + " \"value\": 1234\n"
651  + " }\n"
652  + " },\n"
653  + " \"int32ToEnumMap\": {\n"
654  + " \"9\": \"BAR\"\n"
655  + " }\n"
656  + "}",
659 
660  // Test multiple entries.
661  builder = TestMap.newBuilder();
662  builder.putInt32ToInt32Map(1, 2);
663  builder.putInt32ToInt32Map(3, 4);
664  message = builder.build();
665 
666  assertEquals(
667  "{\n" + " \"int32ToInt32Map\": {\n" + " \"1\": 2,\n" + " \"3\": 4\n" + " }\n" + "}",
670  }
671 
672  public void testMapNullValueIsRejected() throws Exception {
673  try {
674  TestMap.Builder builder = TestMap.newBuilder();
676  "{\n"
677  + " \"int32ToInt32Map\": {null: 1},\n"
678  + " \"int32ToMessageMap\": {null: 2}\n"
679  + "}",
680  builder);
681  fail();
682  } catch (InvalidProtocolBufferException e) {
683  // Exception expected.
684  }
685 
686  try {
687  TestMap.Builder builder = TestMap.newBuilder();
689  "{\n"
690  + " \"int32ToInt32Map\": {\"1\": null},\n"
691  + " \"int32ToMessageMap\": {\"2\": null}\n"
692  + "}",
693  builder);
694  fail();
695 
696  } catch (InvalidProtocolBufferException e) {
697  // Exception expected.
698  }
699  }
700 
701  public void testMapEnumNullValueIsIgnored() throws Exception {
702  TestMap.Builder builder = TestMap.newBuilder();
704  "{\n" + " \"int32ToEnumMap\": {\"1\": null}\n" + "}", builder);
705  TestMap map = builder.build();
706  assertEquals(0, map.getInt32ToEnumMapMap().size());
707  }
708 
709  public void testParserAcceptNonQuotedObjectKey() throws Exception {
710  TestMap.Builder builder = TestMap.newBuilder();
712  "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder);
713  TestMap message = builder.build();
714  assertEquals(2, message.getInt32ToInt32Map().get(1).intValue());
715  assertEquals(3, message.getStringToInt32Map().get("hello").intValue());
716  }
717 
718  public void testWrappers() throws Exception {
719  TestWrappers.Builder builder = TestWrappers.newBuilder();
720  builder.getBoolValueBuilder().setValue(false);
721  builder.getInt32ValueBuilder().setValue(0);
722  builder.getInt64ValueBuilder().setValue(0);
723  builder.getUint32ValueBuilder().setValue(0);
724  builder.getUint64ValueBuilder().setValue(0);
725  builder.getFloatValueBuilder().setValue(0.0f);
726  builder.getDoubleValueBuilder().setValue(0.0);
727  builder.getStringValueBuilder().setValue("");
728  builder.getBytesValueBuilder().setValue(ByteString.EMPTY);
729  TestWrappers message = builder.build();
730 
731  assertEquals(
732  "{\n"
733  + " \"int32Value\": 0,\n"
734  + " \"uint32Value\": 0,\n"
735  + " \"int64Value\": \"0\",\n"
736  + " \"uint64Value\": \"0\",\n"
737  + " \"floatValue\": 0.0,\n"
738  + " \"doubleValue\": 0.0,\n"
739  + " \"boolValue\": false,\n"
740  + " \"stringValue\": \"\",\n"
741  + " \"bytesValue\": \"\"\n"
742  + "}",
745 
746  builder = TestWrappers.newBuilder();
747  builder.getBoolValueBuilder().setValue(true);
748  builder.getInt32ValueBuilder().setValue(1);
749  builder.getInt64ValueBuilder().setValue(2);
750  builder.getUint32ValueBuilder().setValue(3);
751  builder.getUint64ValueBuilder().setValue(4);
752  builder.getFloatValueBuilder().setValue(5.0f);
753  builder.getDoubleValueBuilder().setValue(6.0);
754  builder.getStringValueBuilder().setValue("7");
755  builder.getBytesValueBuilder().setValue(ByteString.copyFrom(new byte[] {8}));
756  message = builder.build();
757 
758  assertEquals(
759  "{\n"
760  + " \"int32Value\": 1,\n"
761  + " \"uint32Value\": 3,\n"
762  + " \"int64Value\": \"2\",\n"
763  + " \"uint64Value\": \"4\",\n"
764  + " \"floatValue\": 5.0,\n"
765  + " \"doubleValue\": 6.0,\n"
766  + " \"boolValue\": true,\n"
767  + " \"stringValue\": \"7\",\n"
768  + " \"bytesValue\": \"CA==\"\n"
769  + "}",
772  }
773 
774  public void testTimestamp() throws Exception {
775  TestTimestamp message =
776  TestTimestamp.newBuilder()
777  .setTimestampValue(Timestamps.parse("1970-01-01T00:00:00Z"))
778  .build();
779 
780  assertEquals(
781  "{\n" + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n" + "}", toJsonString(message));
783  }
784 
785  public void testDuration() throws Exception {
786  TestDuration message =
787  TestDuration.newBuilder().setDurationValue(Durations.parse("12345s")).build();
788 
789  assertEquals("{\n" + " \"durationValue\": \"12345s\"\n" + "}", toJsonString(message));
791  }
792 
793  public void testFieldMask() throws Exception {
794  TestFieldMask message =
795  TestFieldMask.newBuilder()
796  .setFieldMaskValue(FieldMaskUtil.fromString("foo.bar,baz,foo_bar.baz"))
797  .build();
798 
799  assertEquals(
800  "{\n" + " \"fieldMaskValue\": \"foo.bar,baz,fooBar.baz\"\n" + "}", toJsonString(message));
802  }
803 
804  public void testStruct() throws Exception {
805  // Build a struct with all possible values.
806  TestStruct.Builder builder = TestStruct.newBuilder();
807  Struct.Builder structBuilder = builder.getStructValueBuilder();
808  structBuilder.putFields("null_value", Value.newBuilder().setNullValueValue(0).build());
809  structBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1.25).build());
810  structBuilder.putFields("string_value", Value.newBuilder().setStringValue("hello").build());
811  Struct.Builder subStructBuilder = Struct.newBuilder();
812  subStructBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1234).build());
813  structBuilder.putFields(
814  "struct_value", Value.newBuilder().setStructValue(subStructBuilder.build()).build());
815  ListValue.Builder listBuilder = ListValue.newBuilder();
816  listBuilder.addValues(Value.newBuilder().setNumberValue(1.125).build());
817  listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build());
818  structBuilder.putFields(
819  "list_value", Value.newBuilder().setListValue(listBuilder.build()).build());
820  TestStruct message = builder.build();
821 
822  assertEquals(
823  "{\n"
824  + " \"structValue\": {\n"
825  + " \"null_value\": null,\n"
826  + " \"number_value\": 1.25,\n"
827  + " \"string_value\": \"hello\",\n"
828  + " \"struct_value\": {\n"
829  + " \"number_value\": 1234.0\n"
830  + " },\n"
831  + " \"list_value\": [1.125, null]\n"
832  + " }\n"
833  + "}",
836 
837  builder = TestStruct.newBuilder();
838  builder.setValue(Value.newBuilder().setNullValueValue(0).build());
839  message = builder.build();
840  assertEquals("{\n" + " \"value\": null\n" + "}", toJsonString(message));
842 
843  builder = TestStruct.newBuilder();
844  listBuilder = builder.getListValueBuilder();
845  listBuilder.addValues(Value.newBuilder().setNumberValue(31831.125).build());
846  listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build());
847  message = builder.build();
848  assertEquals("{\n" + " \"listValue\": [31831.125, null]\n" + "}", toJsonString(message));
850  }
851 
852 
853  public void testAnyFields() throws Exception {
854  TestAllTypes content = TestAllTypes.newBuilder().setOptionalInt32(1234).build();
855  TestAny message = TestAny.newBuilder().setAnyValue(Any.pack(content)).build();
856 
857  // A TypeRegistry must be provided in order to convert Any types.
858  try {
860  fail("Exception is expected.");
861  } catch (IOException e) {
862  // Expected.
863  }
864 
865  JsonFormat.TypeRegistry registry =
866  JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
867  JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry);
868 
869  assertEquals(
870  "{\n"
871  + " \"anyValue\": {\n"
872  + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
873  + " \"optionalInt32\": 1234\n"
874  + " }\n"
875  + "}",
876  printer.print(message));
877  assertRoundTripEquals(message, registry);
878 
879  TestAny messageWithDefaultAnyValue =
880  TestAny.newBuilder().setAnyValue(Any.getDefaultInstance()).build();
881  assertEquals(
882  "{\n"
883  + " \"anyValue\": {}\n"
884  + "}",
885  printer.print(messageWithDefaultAnyValue));
886  assertRoundTripEquals(messageWithDefaultAnyValue, registry);
887 
888  // Well-known types have a special formatting when embedded in Any.
889  //
890  // 1. Any in Any.
891  Any anyMessage = Any.pack(Any.pack(content));
892  assertEquals(
893  "{\n"
894  + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n"
895  + " \"value\": {\n"
896  + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
897  + " \"optionalInt32\": 1234\n"
898  + " }\n"
899  + "}",
900  printer.print(anyMessage));
901  assertRoundTripEquals(anyMessage, registry);
902 
903  // 2. Wrappers in Any.
904  anyMessage = Any.pack(Int32Value.newBuilder().setValue(12345).build());
905  assertEquals(
906  "{\n"
907  + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n"
908  + " \"value\": 12345\n"
909  + "}",
910  printer.print(anyMessage));
911  assertRoundTripEquals(anyMessage, registry);
912  anyMessage = Any.pack(UInt32Value.newBuilder().setValue(12345).build());
913  assertEquals(
914  "{\n"
915  + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n"
916  + " \"value\": 12345\n"
917  + "}",
918  printer.print(anyMessage));
919  assertRoundTripEquals(anyMessage, registry);
920  anyMessage = Any.pack(Int64Value.newBuilder().setValue(12345).build());
921  assertEquals(
922  "{\n"
923  + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n"
924  + " \"value\": \"12345\"\n"
925  + "}",
926  printer.print(anyMessage));
927  assertRoundTripEquals(anyMessage, registry);
928  anyMessage = Any.pack(UInt64Value.newBuilder().setValue(12345).build());
929  assertEquals(
930  "{\n"
931  + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n"
932  + " \"value\": \"12345\"\n"
933  + "}",
934  printer.print(anyMessage));
935  assertRoundTripEquals(anyMessage, registry);
936  anyMessage = Any.pack(FloatValue.newBuilder().setValue(12345).build());
937  assertEquals(
938  "{\n"
939  + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n"
940  + " \"value\": 12345.0\n"
941  + "}",
942  printer.print(anyMessage));
943  assertRoundTripEquals(anyMessage, registry);
944  anyMessage = Any.pack(DoubleValue.newBuilder().setValue(12345).build());
945  assertEquals(
946  "{\n"
947  + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n"
948  + " \"value\": 12345.0\n"
949  + "}",
950  printer.print(anyMessage));
951  assertRoundTripEquals(anyMessage, registry);
952  anyMessage = Any.pack(BoolValue.newBuilder().setValue(true).build());
953  assertEquals(
954  "{\n"
955  + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
956  + " \"value\": true\n"
957  + "}",
958  printer.print(anyMessage));
959  assertRoundTripEquals(anyMessage, registry);
960  anyMessage = Any.pack(StringValue.newBuilder().setValue("Hello").build());
961  assertEquals(
962  "{\n"
963  + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n"
964  + " \"value\": \"Hello\"\n"
965  + "}",
966  printer.print(anyMessage));
967  assertRoundTripEquals(anyMessage, registry);
968  anyMessage =
969  Any.pack(BytesValue.newBuilder().setValue(ByteString.copyFrom(new byte[] {1, 2})).build());
970  assertEquals(
971  "{\n"
972  + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n"
973  + " \"value\": \"AQI=\"\n"
974  + "}",
975  printer.print(anyMessage));
976  assertRoundTripEquals(anyMessage, registry);
977 
978  // 3. Timestamp in Any.
979  anyMessage = Any.pack(Timestamps.parse("1969-12-31T23:59:59Z"));
980  assertEquals(
981  "{\n"
982  + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n"
983  + " \"value\": \"1969-12-31T23:59:59Z\"\n"
984  + "}",
985  printer.print(anyMessage));
986  assertRoundTripEquals(anyMessage, registry);
987 
988  // 4. Duration in Any
989  anyMessage = Any.pack(Durations.parse("12345.10s"));
990  assertEquals(
991  "{\n"
992  + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n"
993  + " \"value\": \"12345.100s\"\n"
994  + "}",
995  printer.print(anyMessage));
996  assertRoundTripEquals(anyMessage, registry);
997 
998  // 5. FieldMask in Any
999  anyMessage = Any.pack(FieldMaskUtil.fromString("foo.bar,baz"));
1000  assertEquals(
1001  "{\n"
1002  + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n"
1003  + " \"value\": \"foo.bar,baz\"\n"
1004  + "}",
1005  printer.print(anyMessage));
1006  assertRoundTripEquals(anyMessage, registry);
1007 
1008  // 6. Struct in Any
1009  Struct.Builder structBuilder = Struct.newBuilder();
1010  structBuilder.putFields("number", Value.newBuilder().setNumberValue(1.125).build());
1011  anyMessage = Any.pack(structBuilder.build());
1012  assertEquals(
1013  "{\n"
1014  + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n"
1015  + " \"value\": {\n"
1016  + " \"number\": 1.125\n"
1017  + " }\n"
1018  + "}",
1019  printer.print(anyMessage));
1020  assertRoundTripEquals(anyMessage, registry);
1021 
1022  // 7. Value (number type) in Any
1023  Value.Builder valueBuilder = Value.newBuilder();
1024  valueBuilder.setNumberValue(1);
1025  anyMessage = Any.pack(valueBuilder.build());
1026  assertEquals(
1027  "{\n"
1028  + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n"
1029  + " \"value\": 1.0\n"
1030  + "}",
1031  printer.print(anyMessage));
1032  assertRoundTripEquals(anyMessage, registry);
1033 
1034  // 8. Value (null type) in Any
1035  anyMessage = Any.pack(Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build());
1036  assertEquals(
1037  "{\n"
1038  + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n"
1039  + " \"value\": null\n"
1040  + "}",
1041  printer.print(anyMessage));
1042  assertRoundTripEquals(anyMessage, registry);
1043  }
1044 
1045  public void testAnyInMaps() throws Exception {
1046  JsonFormat.TypeRegistry registry =
1047  JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
1048  JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry);
1049 
1050  TestAny.Builder testAny = TestAny.newBuilder();
1051  testAny.putAnyMap("int32_wrapper", Any.pack(Int32Value.newBuilder().setValue(123).build()));
1052  testAny.putAnyMap("int64_wrapper", Any.pack(Int64Value.newBuilder().setValue(456).build()));
1053  testAny.putAnyMap("timestamp", Any.pack(Timestamps.parse("1969-12-31T23:59:59Z")));
1054  testAny.putAnyMap("duration", Any.pack(Durations.parse("12345.1s")));
1055  testAny.putAnyMap("field_mask", Any.pack(FieldMaskUtil.fromString("foo.bar,baz")));
1056  Value numberValue = Value.newBuilder().setNumberValue(1.125).build();
1057  Struct.Builder struct = Struct.newBuilder();
1058  struct.putFields("number", numberValue);
1059  testAny.putAnyMap("struct", Any.pack(struct.build()));
1060  Value nullValue = Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build();
1061  testAny.putAnyMap(
1062  "list_value",
1063  Any.pack(ListValue.newBuilder().addValues(numberValue).addValues(nullValue).build()));
1064  testAny.putAnyMap("number_value", Any.pack(numberValue));
1065  testAny.putAnyMap("any_value_number", Any.pack(Any.pack(numberValue)));
1066  testAny.putAnyMap("any_value_default", Any.pack(Any.getDefaultInstance()));
1067  testAny.putAnyMap("default", Any.getDefaultInstance());
1068 
1069  assertEquals(
1070  "{\n"
1071  + " \"anyMap\": {\n"
1072  + " \"int32_wrapper\": {\n"
1073  + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n"
1074  + " \"value\": 123\n"
1075  + " },\n"
1076  + " \"int64_wrapper\": {\n"
1077  + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n"
1078  + " \"value\": \"456\"\n"
1079  + " },\n"
1080  + " \"timestamp\": {\n"
1081  + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n"
1082  + " \"value\": \"1969-12-31T23:59:59Z\"\n"
1083  + " },\n"
1084  + " \"duration\": {\n"
1085  + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n"
1086  + " \"value\": \"12345.100s\"\n"
1087  + " },\n"
1088  + " \"field_mask\": {\n"
1089  + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n"
1090  + " \"value\": \"foo.bar,baz\"\n"
1091  + " },\n"
1092  + " \"struct\": {\n"
1093  + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n"
1094  + " \"value\": {\n"
1095  + " \"number\": 1.125\n"
1096  + " }\n"
1097  + " },\n"
1098  + " \"list_value\": {\n"
1099  + " \"@type\": \"type.googleapis.com/google.protobuf.ListValue\",\n"
1100  + " \"value\": [1.125, null]\n"
1101  + " },\n"
1102  + " \"number_value\": {\n"
1103  + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n"
1104  + " \"value\": 1.125\n"
1105  + " },\n"
1106  + " \"any_value_number\": {\n"
1107  + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n"
1108  + " \"value\": {\n"
1109  + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n"
1110  + " \"value\": 1.125\n"
1111  + " }\n"
1112  + " },\n"
1113  + " \"any_value_default\": {\n"
1114  + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n"
1115  + " \"value\": {}\n"
1116  + " },\n"
1117  + " \"default\": {}\n"
1118  + " }\n"
1119  + "}",
1120  printer.print(testAny.build()));
1121  assertRoundTripEquals(testAny.build(), registry);
1122  }
1123 
1124  public void testParserMissingTypeUrl() throws Exception {
1125  try {
1126  Any.Builder builder = Any.newBuilder();
1127  mergeFromJson("{\n" + " \"optionalInt32\": 1234\n" + "}", builder);
1128  fail("Exception is expected.");
1129  } catch (IOException e) {
1130  // Expected.
1131  }
1132  }
1133 
1134  public void testParserUnexpectedTypeUrl() throws Exception {
1135  try {
1136  Any.Builder builder = Any.newBuilder();
1137  mergeFromJson(
1138  "{\n"
1139  + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
1140  + " \"optionalInt32\": 12345\n"
1141  + "}",
1142  builder);
1143  fail("Exception is expected.");
1144  } catch (IOException e) {
1145  // Expected.
1146  }
1147  }
1148 
1149  public void testParserRejectTrailingComma() throws Exception {
1150  try {
1151  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1152  mergeFromJson("{\n" + " \"optionalInt32\": 12345,\n" + "}", builder);
1153  fail("Exception is expected.");
1154  } catch (IOException e) {
1155  // Expected.
1156  }
1157 
1158  // TODO(xiaofeng): GSON allows trailing comma in arrays even after I set
1159  // the JsonReader to non-lenient mode. If we want to enforce strict JSON
1160  // compliance, we might want to switch to a different JSON parser or
1161  // implement one by ourselves.
1162  // try {
1163  // TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1164  // JsonFormat.merge(
1165  // "{\n"
1166  // + " \"repeatedInt32\": [12345,]\n"
1167  // + "}", builder);
1168  // fail("Exception is expected.");
1169  // } catch (IOException e) {
1170  // // Expected.
1171  // }
1172  }
1173 
1174  public void testParserRejectInvalidBase64() throws Exception {
1175  assertRejects("optionalBytes", "!@#$");
1176  }
1177 
1178  public void testParserAcceptBase64Variants() throws Exception {
1179  assertAccepts("optionalBytes", "AQI"); // No padding
1180  assertAccepts("optionalBytes", "-_w"); // base64Url, no padding
1181  }
1182 
1183  public void testParserRejectInvalidEnumValue() throws Exception {
1184  try {
1185  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1186  mergeFromJson("{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}", builder);
1187  fail("Exception is expected.");
1188  } catch (InvalidProtocolBufferException e) {
1189  // Expected.
1190  }
1191  }
1192 
1193  public void testParserUnknownFields() throws Exception {
1194  try {
1195  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1196  String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}";
1197  JsonFormat.parser().merge(json, builder);
1198  fail("Exception is expected.");
1199  } catch (InvalidProtocolBufferException e) {
1200  // Expected.
1201  }
1202  }
1203 
1204  public void testParserIgnoringUnknownFields() throws Exception {
1205  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1206  String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}";
1207  JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
1208  }
1209 
1210  public void testParserIgnoringUnknownEnums() throws Exception {
1211  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1212  String json = "{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}";
1213  JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
1214  assertEquals(0, builder.getOptionalNestedEnumValue());
1215  }
1216 
1217  public void testParserSupportAliasEnums() throws Exception {
1218  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1219  String json = "{\n" + " \"optionalAliasedEnum\": \"QUX\"\n" + "}";
1220  JsonFormat.parser().merge(json, builder);
1221  assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum());
1222 
1223  builder = TestAllTypes.newBuilder();
1224  json = "{\n" + " \"optionalAliasedEnum\": \"qux\"\n" + "}";
1225  JsonFormat.parser().merge(json, builder);
1226  assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum());
1227 
1228  builder = TestAllTypes.newBuilder();
1229  json = "{\n" + " \"optionalAliasedEnum\": \"bAz\"\n" + "}";
1230  JsonFormat.parser().merge(json, builder);
1231  assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum());
1232  }
1233 
1234  public void testUnknownEnumMap() throws Exception {
1235  TestMap.Builder builder = TestMap.newBuilder();
1236  JsonFormat.parser()
1238  .merge("{\n" + " \"int32ToEnumMap\": {1: XXX, 2: FOO}" + "}", builder);
1239 
1240  assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2));
1241  assertEquals(1, builder.getInt32ToEnumMapMap().size());
1242  }
1243 
1244  public void testRepeatedUnknownEnum() throws Exception {
1245  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1246  JsonFormat.parser()
1248  .merge("{\n" + " \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]" + "}", builder);
1249 
1250  assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0));
1251  assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1));
1252  assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2));
1253  assertEquals(3, builder.getRepeatedNestedEnumList().size());
1254  }
1255 
1256  public void testParserIntegerEnumValue() throws Exception {
1257  TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder();
1258  mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder);
1259 
1260  TestAllTypes expected = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAZ).build();
1261  assertEquals(expected, actualBuilder.build());
1262  }
1263 
1264  public void testCustomJsonName() throws Exception {
1265  TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build();
1266  assertEquals("{\n" + " \"@value\": 12345\n" + "}", JsonFormat.printer().print(message));
1268  }
1269 
1270  // Regression test for b/73832901. Make sure html tags are escaped.
1271  public void testHtmlEscape() throws Exception {
1272  TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("</script>").build();
1273  assertEquals("{\n \"optionalString\": \"\\u003c/script\\u003e\"\n}", toJsonString(message));
1274 
1275  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1277  assertEquals(message.getOptionalString(), builder.getOptionalString());
1278  }
1279 
1280  public void testIncludingDefaultValueFields() throws Exception {
1281  TestAllTypes message = TestAllTypes.getDefaultInstance();
1282  assertEquals("{\n}", JsonFormat.printer().print(message));
1283  assertEquals(
1284  "{\n"
1285  + " \"optionalInt32\": 0,\n"
1286  + " \"optionalInt64\": \"0\",\n"
1287  + " \"optionalUint32\": 0,\n"
1288  + " \"optionalUint64\": \"0\",\n"
1289  + " \"optionalSint32\": 0,\n"
1290  + " \"optionalSint64\": \"0\",\n"
1291  + " \"optionalFixed32\": 0,\n"
1292  + " \"optionalFixed64\": \"0\",\n"
1293  + " \"optionalSfixed32\": 0,\n"
1294  + " \"optionalSfixed64\": \"0\",\n"
1295  + " \"optionalFloat\": 0.0,\n"
1296  + " \"optionalDouble\": 0.0,\n"
1297  + " \"optionalBool\": false,\n"
1298  + " \"optionalString\": \"\",\n"
1299  + " \"optionalBytes\": \"\",\n"
1300  + " \"optionalNestedEnum\": \"FOO\",\n"
1301  + " \"repeatedInt32\": [],\n"
1302  + " \"repeatedInt64\": [],\n"
1303  + " \"repeatedUint32\": [],\n"
1304  + " \"repeatedUint64\": [],\n"
1305  + " \"repeatedSint32\": [],\n"
1306  + " \"repeatedSint64\": [],\n"
1307  + " \"repeatedFixed32\": [],\n"
1308  + " \"repeatedFixed64\": [],\n"
1309  + " \"repeatedSfixed32\": [],\n"
1310  + " \"repeatedSfixed64\": [],\n"
1311  + " \"repeatedFloat\": [],\n"
1312  + " \"repeatedDouble\": [],\n"
1313  + " \"repeatedBool\": [],\n"
1314  + " \"repeatedString\": [],\n"
1315  + " \"repeatedBytes\": [],\n"
1316  + " \"repeatedNestedMessage\": [],\n"
1317  + " \"repeatedNestedEnum\": [],\n"
1318  + " \"optionalAliasedEnum\": \"ALIAS_FOO\"\n"
1319  + "}",
1321 
1322  Set<FieldDescriptor> fixedFields = new HashSet<FieldDescriptor>();
1323  for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) {
1324  if (fieldDesc.getName().contains("_fixed")) {
1325  fixedFields.add(fieldDesc);
1326  }
1327  }
1328 
1329  assertEquals(
1330  "{\n"
1331  + " \"optionalFixed32\": 0,\n"
1332  + " \"optionalFixed64\": \"0\",\n"
1333  + " \"repeatedFixed32\": [],\n"
1334  + " \"repeatedFixed64\": []\n"
1335  + "}",
1336  JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message));
1337 
1338  TestAllTypes messageNonDefaults =
1339  message.toBuilder().setOptionalInt64(1234).setOptionalFixed32(3232).build();
1340  assertEquals(
1341  "{\n"
1342  + " \"optionalInt64\": \"1234\",\n"
1343  + " \"optionalFixed32\": 3232,\n"
1344  + " \"optionalFixed64\": \"0\",\n"
1345  + " \"repeatedFixed32\": [],\n"
1346  + " \"repeatedFixed64\": []\n"
1347  + "}",
1348  JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults));
1349 
1350  try {
1351  JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields();
1352  fail("IllegalStateException is expected.");
1353  } catch (IllegalStateException e) {
1354  // Expected.
1355  assertTrue(
1356  "Exception message should mention includingDefaultValueFields.",
1357  e.getMessage().contains("includingDefaultValueFields"));
1358  }
1359 
1360  try {
1361  JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(fixedFields);
1362  fail("IllegalStateException is expected.");
1363  } catch (IllegalStateException e) {
1364  // Expected.
1365  assertTrue(
1366  "Exception message should mention includingDefaultValueFields.",
1367  e.getMessage().contains("includingDefaultValueFields"));
1368  }
1369 
1370  try {
1371  JsonFormat.printer().includingDefaultValueFields(fixedFields).includingDefaultValueFields();
1372  fail("IllegalStateException is expected.");
1373  } catch (IllegalStateException e) {
1374  // Expected.
1375  assertTrue(
1376  "Exception message should mention includingDefaultValueFields.",
1377  e.getMessage().contains("includingDefaultValueFields"));
1378  }
1379 
1380  try {
1382  .includingDefaultValueFields(fixedFields)
1383  .includingDefaultValueFields(fixedFields);
1384  fail("IllegalStateException is expected.");
1385  } catch (IllegalStateException e) {
1386  // Expected.
1387  assertTrue(
1388  "Exception message should mention includingDefaultValueFields.",
1389  e.getMessage().contains("includingDefaultValueFields"));
1390  }
1391 
1392  Set<FieldDescriptor> intFields = new HashSet<FieldDescriptor>();
1393  for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) {
1394  if (fieldDesc.getName().contains("_int")) {
1395  intFields.add(fieldDesc);
1396  }
1397  }
1398 
1399  try {
1401  .includingDefaultValueFields(intFields)
1402  .includingDefaultValueFields(fixedFields);
1403  fail("IllegalStateException is expected.");
1404  } catch (IllegalStateException e) {
1405  // Expected.
1406  assertTrue(
1407  "Exception message should mention includingDefaultValueFields.",
1408  e.getMessage().contains("includingDefaultValueFields"));
1409  }
1410 
1411  try {
1413  fail("IllegalArgumentException is expected.");
1414  } catch (IllegalArgumentException e) {
1415  // Expected.
1416  assertTrue(
1417  "Exception message should mention includingDefaultValueFields.",
1418  e.getMessage().contains("includingDefaultValueFields"));
1419  }
1420 
1421  try {
1423  fail("IllegalArgumentException is expected.");
1424  } catch (IllegalArgumentException e) {
1425  // Expected.
1426  assertTrue(
1427  "Exception message should mention includingDefaultValueFields.",
1428  e.getMessage().contains("includingDefaultValueFields"));
1429  }
1430 
1431  TestMap mapMessage = TestMap.getDefaultInstance();
1432  assertEquals("{\n}", JsonFormat.printer().print(mapMessage));
1433  assertEquals(
1434  "{\n"
1435  + " \"int32ToInt32Map\": {\n"
1436  + " },\n"
1437  + " \"int64ToInt32Map\": {\n"
1438  + " },\n"
1439  + " \"uint32ToInt32Map\": {\n"
1440  + " },\n"
1441  + " \"uint64ToInt32Map\": {\n"
1442  + " },\n"
1443  + " \"sint32ToInt32Map\": {\n"
1444  + " },\n"
1445  + " \"sint64ToInt32Map\": {\n"
1446  + " },\n"
1447  + " \"fixed32ToInt32Map\": {\n"
1448  + " },\n"
1449  + " \"fixed64ToInt32Map\": {\n"
1450  + " },\n"
1451  + " \"sfixed32ToInt32Map\": {\n"
1452  + " },\n"
1453  + " \"sfixed64ToInt32Map\": {\n"
1454  + " },\n"
1455  + " \"boolToInt32Map\": {\n"
1456  + " },\n"
1457  + " \"stringToInt32Map\": {\n"
1458  + " },\n"
1459  + " \"int32ToInt64Map\": {\n"
1460  + " },\n"
1461  + " \"int32ToUint32Map\": {\n"
1462  + " },\n"
1463  + " \"int32ToUint64Map\": {\n"
1464  + " },\n"
1465  + " \"int32ToSint32Map\": {\n"
1466  + " },\n"
1467  + " \"int32ToSint64Map\": {\n"
1468  + " },\n"
1469  + " \"int32ToFixed32Map\": {\n"
1470  + " },\n"
1471  + " \"int32ToFixed64Map\": {\n"
1472  + " },\n"
1473  + " \"int32ToSfixed32Map\": {\n"
1474  + " },\n"
1475  + " \"int32ToSfixed64Map\": {\n"
1476  + " },\n"
1477  + " \"int32ToFloatMap\": {\n"
1478  + " },\n"
1479  + " \"int32ToDoubleMap\": {\n"
1480  + " },\n"
1481  + " \"int32ToBoolMap\": {\n"
1482  + " },\n"
1483  + " \"int32ToStringMap\": {\n"
1484  + " },\n"
1485  + " \"int32ToBytesMap\": {\n"
1486  + " },\n"
1487  + " \"int32ToMessageMap\": {\n"
1488  + " },\n"
1489  + " \"int32ToEnumMap\": {\n"
1490  + " }\n"
1491  + "}",
1492  JsonFormat.printer().includingDefaultValueFields().print(mapMessage));
1493 
1494  TestOneof oneofMessage = TestOneof.getDefaultInstance();
1495  assertEquals("{\n}", JsonFormat.printer().print(oneofMessage));
1496  assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
1497 
1498  oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build();
1499  assertEquals("{\n \"oneofInt32\": 42\n}", JsonFormat.printer().print(oneofMessage));
1500  assertEquals(
1501  "{\n \"oneofInt32\": 42\n}",
1502  JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
1503 
1504  TestOneof.Builder oneofBuilder = TestOneof.newBuilder();
1505  mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder);
1506  oneofMessage = oneofBuilder.build();
1507  assertEquals("{\n \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage));
1508  assertEquals(
1509  "{\n \"oneofNullValue\": null\n}",
1510  JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
1511  }
1512 
1513  public void testPreservingProtoFieldNames() throws Exception {
1514  TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build();
1515  assertEquals("{\n" + " \"optionalInt32\": 12345\n" + "}", JsonFormat.printer().print(message));
1516  assertEquals(
1517  "{\n" + " \"optional_int32\": 12345\n" + "}",
1519 
1520  // The json_name field option is ignored when configured to use original proto field names.
1521  TestCustomJsonName messageWithCustomJsonName =
1522  TestCustomJsonName.newBuilder().setValue(12345).build();
1523  assertEquals(
1524  "{\n" + " \"value\": 12345\n" + "}",
1525  JsonFormat.printer().preservingProtoFieldNames().print(messageWithCustomJsonName));
1526 
1527  // Parsers accept both original proto field names and lowerCamelCase names.
1528  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1529  JsonFormat.parser().merge("{\"optionalInt32\": 12345}", builder);
1530  assertEquals(12345, builder.getOptionalInt32());
1531  builder.clear();
1532  JsonFormat.parser().merge("{\"optional_int32\": 54321}", builder);
1533  assertEquals(54321, builder.getOptionalInt32());
1534  }
1535 
1536  public void testPrintingEnumsAsInts() throws Exception {
1537  TestAllTypes message = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAR).build();
1538  assertEquals(
1539  "{\n" + " \"optionalNestedEnum\": 1\n" + "}",
1541  }
1542 
1543  public void testOmittingInsignificantWhiteSpace() throws Exception {
1544  TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build();
1545  assertEquals(
1546  "{" + "\"optionalInt32\":12345" + "}",
1548  TestAllTypes message1 = TestAllTypes.getDefaultInstance();
1549  assertEquals("{}", JsonFormat.printer().omittingInsignificantWhitespace().print(message1));
1550  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1551  setAllFields(builder);
1552  TestAllTypes message2 = builder.build();
1553  assertEquals(
1554  "{"
1555  + "\"optionalInt32\":1234,"
1556  + "\"optionalInt64\":\"1234567890123456789\","
1557  + "\"optionalUint32\":5678,"
1558  + "\"optionalUint64\":\"2345678901234567890\","
1559  + "\"optionalSint32\":9012,"
1560  + "\"optionalSint64\":\"3456789012345678901\","
1561  + "\"optionalFixed32\":3456,"
1562  + "\"optionalFixed64\":\"4567890123456789012\","
1563  + "\"optionalSfixed32\":7890,"
1564  + "\"optionalSfixed64\":\"5678901234567890123\","
1565  + "\"optionalFloat\":1.5,"
1566  + "\"optionalDouble\":1.25,"
1567  + "\"optionalBool\":true,"
1568  + "\"optionalString\":\"Hello world!\","
1569  + "\"optionalBytes\":\"AAEC\","
1570  + "\"optionalNestedMessage\":{"
1571  + "\"value\":100"
1572  + "},"
1573  + "\"optionalNestedEnum\":\"BAR\","
1574  + "\"repeatedInt32\":[1234,234],"
1575  + "\"repeatedInt64\":[\"1234567890123456789\",\"234567890123456789\"],"
1576  + "\"repeatedUint32\":[5678,678],"
1577  + "\"repeatedUint64\":[\"2345678901234567890\",\"345678901234567890\"],"
1578  + "\"repeatedSint32\":[9012,10],"
1579  + "\"repeatedSint64\":[\"3456789012345678901\",\"456789012345678901\"],"
1580  + "\"repeatedFixed32\":[3456,456],"
1581  + "\"repeatedFixed64\":[\"4567890123456789012\",\"567890123456789012\"],"
1582  + "\"repeatedSfixed32\":[7890,890],"
1583  + "\"repeatedSfixed64\":[\"5678901234567890123\",\"678901234567890123\"],"
1584  + "\"repeatedFloat\":[1.5,11.5],"
1585  + "\"repeatedDouble\":[1.25,11.25],"
1586  + "\"repeatedBool\":[true,true],"
1587  + "\"repeatedString\":[\"Hello world!\",\"ello world!\"],"
1588  + "\"repeatedBytes\":[\"AAEC\",\"AQI=\"],"
1589  + "\"repeatedNestedMessage\":[{"
1590  + "\"value\":100"
1591  + "},{"
1592  + "\"value\":200"
1593  + "}],"
1594  + "\"repeatedNestedEnum\":[\"BAR\",\"BAZ\"]"
1595  + "}",
1596  toCompactJsonString(message2));
1597  }
1598 
1599  // Regression test for b/29892357
1600  public void testEmptyWrapperTypesInAny() throws Exception {
1601  JsonFormat.TypeRegistry registry =
1602  JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
1604 
1605  Any.Builder builder = Any.newBuilder();
1606  parser.merge(
1607  "{\n"
1608  + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
1609  + " \"value\": false\n"
1610  + "}\n",
1611  builder);
1612  Any any = builder.build();
1613  assertEquals(0, any.getValue().size());
1614  }
1615 
1616  public void testRecursionLimit() throws Exception {
1617  String input =
1618  "{\n"
1619  + " \"nested\": {\n"
1620  + " \"nested\": {\n"
1621  + " \"nested\": {\n"
1622  + " \"nested\": {\n"
1623  + " \"value\": 1234\n"
1624  + " }\n"
1625  + " }\n"
1626  + " }\n"
1627  + " }\n"
1628  + "}\n";
1629 
1631  TestRecursive.Builder builder = TestRecursive.newBuilder();
1632  parser.merge(input, builder);
1633  TestRecursive message = builder.build();
1634  assertEquals(1234, message.getNested().getNested().getNested().getNested().getValue());
1635 
1636  parser = JsonFormat.parser().usingRecursionLimit(3);
1637  builder = TestRecursive.newBuilder();
1638  try {
1639  parser.merge(input, builder);
1640  fail("Exception is expected.");
1641  } catch (InvalidProtocolBufferException e) {
1642  // Expected.
1643  }
1644  }
1645 
1646  // Test that we are not leaking out JSON exceptions.
1647  public void testJsonException() throws Exception {
1648  InputStream throwingInputStream =
1649  new InputStream() {
1650  public int read() throws IOException {
1651  throw new IOException("12345");
1652  }
1653  };
1654  InputStreamReader throwingReader = new InputStreamReader(throwingInputStream);
1655  // When the underlying reader throws IOException, JsonFormat should forward
1656  // through this IOException.
1657  try {
1658  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1659  JsonFormat.parser().merge(throwingReader, builder);
1660  fail("Exception is expected.");
1661  } catch (IOException e) {
1662  assertEquals("12345", e.getMessage());
1663  }
1664 
1665  Reader invalidJsonReader = new StringReader("{ xxx - yyy }");
1666  // When the JSON parser throws parser exceptions, JsonFormat should turn
1667  // that into InvalidProtocolBufferException.
1668  try {
1669  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1670  JsonFormat.parser().merge(invalidJsonReader, builder);
1671  fail("Exception is expected.");
1672  } catch (InvalidProtocolBufferException e) {
1673  // Expected.
1674  }
1675  }
1676 
1677  public void testSortedMapKeys() throws Exception {
1678  TestMap.Builder mapBuilder = TestMap.newBuilder();
1679  mapBuilder.putStringToInt32Map("\ud834\udd20", 3); // utf-8 F0 9D 84 A0
1680  mapBuilder.putStringToInt32Map("foo", 99);
1681  mapBuilder.putStringToInt32Map("xxx", 123);
1682  mapBuilder.putStringToInt32Map("\u20ac", 1); // utf-8 E2 82 AC
1683  mapBuilder.putStringToInt32Map("abc", 20);
1684  mapBuilder.putStringToInt32Map("19", 19);
1685  mapBuilder.putStringToInt32Map("8", 8);
1686  mapBuilder.putStringToInt32Map("\ufb00", 2); // utf-8 EF AC 80
1687  mapBuilder.putInt32ToInt32Map(3, 3);
1688  mapBuilder.putInt32ToInt32Map(10, 10);
1689  mapBuilder.putInt32ToInt32Map(5, 5);
1690  mapBuilder.putInt32ToInt32Map(4, 4);
1691  mapBuilder.putInt32ToInt32Map(1, 1);
1692  mapBuilder.putInt32ToInt32Map(2, 2);
1693  mapBuilder.putInt32ToInt32Map(-3, -3);
1694  TestMap mapMessage = mapBuilder.build();
1695  assertEquals(
1696  "{\n"
1697  + " \"int32ToInt32Map\": {\n"
1698  + " \"-3\": -3,\n"
1699  + " \"1\": 1,\n"
1700  + " \"2\": 2,\n"
1701  + " \"3\": 3,\n"
1702  + " \"4\": 4,\n"
1703  + " \"5\": 5,\n"
1704  + " \"10\": 10\n"
1705  + " },\n"
1706  + " \"stringToInt32Map\": {\n"
1707  + " \"19\": 19,\n"
1708  + " \"8\": 8,\n"
1709  + " \"abc\": 20,\n"
1710  + " \"foo\": 99,\n"
1711  + " \"xxx\": 123,\n"
1712  + " \"\u20ac\": 1,\n"
1713  + " \"\ufb00\": 2,\n"
1714  + " \"\ud834\udd20\": 3\n"
1715  + " }\n"
1716  + "}",
1717  toSortedJsonString(mapMessage));
1718 
1719  TestMap emptyMap = TestMap.getDefaultInstance();
1720  assertEquals("{\n}", toSortedJsonString(emptyMap));
1721  }
1722 }
com.google.protobuf.util.JsonFormatTest.testParserRejectOutOfRangeNumericValues
void testParserRejectOutOfRangeNumericValues()
Definition: JsonFormatTest.java:358
com.google.protobuf.util.JsonFormatTest.testAnyInMaps
void testAnyInMaps()
Definition: JsonFormatTest.java:1045
com.google.protobuf.Descriptors
Definition: Descriptors.java:80
com.google.protobuf.util.JsonFormatTest.testIncludingDefaultValueFields
void testIncludingDefaultValueFields()
Definition: JsonFormatTest.java:1280
com.google.protobuf.util.JsonFormatTest.testParserRejectInvalidBase64
void testParserRejectInvalidBase64()
Definition: JsonFormatTest.java:1174
com.google.protobuf.util.JsonFormat.Parser.merge
void merge(String json, Message.Builder builder)
Definition: JsonFormat.java:404
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
com.google.protobuf.util.JsonFormatTest.testStruct
void testStruct()
Definition: JsonFormatTest.java:804
com.google.protobuf.util.JsonFormatTest.testMapNullValueIsRejected
void testMapNullValueIsRejected()
Definition: JsonFormatTest.java:672
TestStruct
com.google.protobuf.util.JsonFormat.TypeRegistry.newBuilder
static Builder newBuilder()
Definition: JsonFormat.java:446
com.google.protobuf.util.JsonFormatTest.testParserUnexpectedTypeUrl
void testParserUnexpectedTypeUrl()
Definition: JsonFormatTest.java:1134
com.google.protobuf::Any
BoolValue
struct BoolValue BoolValue
Definition: php/ext/google/protobuf/protobuf.h:626
com.google.protobuf::ListValue
com.google.protobuf.util.JsonFormat.parser
static Parser parser()
Definition: JsonFormat.java:356
com.google.protobuf.util.JsonFormat.Printer.includingDefaultValueFields
Set< FieldDescriptor > includingDefaultValueFields
Definition: JsonFormat.java:129
com.google.protobuf.util.JsonFormat.Parser.ignoringUnknownFields
final boolean ignoringUnknownFields
Definition: JsonFormat.java:365
com.google.protobuf.util.JsonFormatTest.testParserRejectInvalidEnumValue
void testParserRejectInvalidEnumValue()
Definition: JsonFormatTest.java:1183
com.google.protobuf.util.JsonFormatTest.testRepeatedUnknownEnum
void testRepeatedUnknownEnum()
Definition: JsonFormatTest.java:1244
com.google.protobuf.util.JsonFormatTest.testMapEnumNullValueIsIgnored
void testMapEnumNullValueIsIgnored()
Definition: JsonFormatTest.java:701
com.google.protobuf.util.JsonFormatTest.testNullLastInDuplicateOneof
void testNullLastInDuplicateOneof()
Definition: JsonFormatTest.java:474
input
std::string input
Definition: tokenizer_unittest.cc:197
com.google.protobuf.util.JsonFormat.printer
static Printer printer()
Definition: JsonFormat.java:109
com.google.protobuf.Message.toString
String toString()
com.google.protobuf.util.JsonFormatTest.testHtmlEscape
void testHtmlEscape()
Definition: JsonFormatTest.java:1271
com.google.protobuf.util.Durations.parse
static Duration parse(String value)
Definition: Durations.java:241
com.google.protobuf.util.JsonFormat.Printer.print
String print(MessageOrBuilder message)
Definition: JsonFormat.java:339
com.google.protobuf.util.JsonFormatTest.testParserAcceptNull
void testParserAcceptNull()
Definition: JsonFormatTest.java:398
com.google.protobuf.util.JsonFormatTest.setAllFields
void setAllFields(TestAllTypes.Builder builder)
Definition: JsonFormatTest.java:86
com.google.protobuf.util.JsonFormat.Printer.printingEnumsAsInts
final boolean printingEnumsAsInts
Definition: JsonFormat.java:132
com.google.protobuf.util.JsonFormatTest.testNullInOneof
void testNullInOneof()
Definition: JsonFormatTest.java:459
com.google.protobuf.util.JsonFormatTest.testNullFirstInDuplicateOneof
void testNullFirstInDuplicateOneof()
Definition: JsonFormatTest.java:467
com.google.protobuf.util.JsonFormat.Parser.usingTypeRegistry
Parser usingTypeRegistry(TypeRegistry registry)
Definition: JsonFormat.java:383
com.google.protobuf::BoolValue
TestTimestamp
com.google.protobuf.util.JsonFormatTest.testJsonException
void testJsonException()
Definition: JsonFormatTest.java:1647
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
com.google.protobuf.util.JsonFormatTest.testSpecialFloatValues
void testSpecialFloatValues()
Definition: JsonFormatTest.java:257
com.google.protobuf.util.JsonFormatTest.testUnknownEnumValues
void testUnknownEnumValues()
Definition: JsonFormatTest.java:227
com.google.protobuf::Int32Value
com.google.protobuf.util.JsonFormatTest.toSortedJsonString
String toSortedJsonString(Message message)
Definition: JsonFormatTest.java:161
com.google.protobuf.ByteString.EMPTY
static final ByteString EMPTY
Definition: ByteString.java:85
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:473
com.google.protobuf.util.JsonFormatTest.testRecursionLimit
void testRecursionLimit()
Definition: JsonFormatTest.java:1616
com.google.protobuf.util.JsonFormatTest.assertAccepts
void assertAccepts(String name, String value)
Definition: JsonFormatTest.java:350
TestMap
com.google.protobuf.util.JsonFormatTest.testTimestamp
void testTimestamp()
Definition: JsonFormatTest.java:774
testing::internal::Double
FloatingPoint< double > Double
Definition: gtest-internal.h:429
NullValue
NullValue
Definition: struct.pb.h:83
com.google.protobuf::Value
com.google.protobuf.util.Durations
Definition: Durations.java:54
TestOneof
com.google.protobuf.util.JsonFormatTest.testParserAcceptBase64Variants
void testParserAcceptBase64Variants()
Definition: JsonFormatTest.java:1178
TestAllTypes
com.google.protobuf.util.JsonFormatTest.testPrintingEnumsAsInts
void testPrintingEnumsAsInts()
Definition: JsonFormatTest.java:1536
com.google.protobuf.util.JsonFormatTest.testMapFields
void testMapFields()
Definition: JsonFormatTest.java:535
com.google.protobuf.util
Definition: Durations.java:31
com.google.protobuf.util.JsonFormatTest.testParserUnknownFields
void testParserUnknownFields()
Definition: JsonFormatTest.java:1193
TestDuration
com.google.protobuf.util.JsonFormat
Definition: JsonFormat.java:101
com.google.protobuf.util.JsonFormatTest.assertRoundTripEquals
void assertRoundTripEquals(Message message)
Definition: JsonFormatTest.java:142
com.google.protobuf.util.JsonFormatTest.mergeFromJsonIgnoringUnknownFields
void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder)
Definition: JsonFormatTest.java:169
com.google.protobuf.util.FieldMaskUtil.fromString
static FieldMask fromString(String value)
Definition: FieldMaskUtil.java:84
com.google.protobuf.util.JsonFormat.Printer.omittingInsignificantWhitespace
final boolean omittingInsignificantWhitespace
Definition: JsonFormat.java:131
com.google.protobuf.util.JsonFormatTest.testFieldMask
void testFieldMask()
Definition: JsonFormatTest.java:793
com.google.protobuf.Message.Builder
Definition: Message.java:104
com.google.protobuf.util.JsonFormatTest.testParserIgnoringUnknownFields
void testParserIgnoringUnknownFields()
Definition: JsonFormatTest.java:1204
testing::internal::Float
FloatingPoint< float > Float
Definition: gtest-internal.h:428
ListValue
struct ListValue ListValue
Definition: php/ext/google/protobuf/protobuf.h:646
com.google.protobuf.util.JsonFormatTest.assertRejects
void assertRejects(String name, String value)
Definition: JsonFormatTest.java:332
com.google.protobuf.util.Timestamps.parse
static Timestamp parse(String value)
Definition: Timestamps.java:232
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.build
TypeRegistry build()
Definition: JsonFormat.java:506
Int32Value
struct Int32Value Int32Value
Definition: php/ext/google/protobuf/protobuf.h:643
com.google.protobuf.util.JsonFormatTest.testParserAcceptStringForNumericField
void testParserAcceptStringForNumericField()
Definition: JsonFormatTest.java:277
com.google.protobuf.util.JsonFormatTest.testParserAcceptNonQuotedObjectKey
void testParserAcceptNonQuotedObjectKey()
Definition: JsonFormatTest.java:709
com.google.protobuf.util.JsonFormatTest.mergeFromJson
void mergeFromJson(String json, Message.Builder builder)
Definition: JsonFormatTest.java:165
com.google.protobuf.util.JsonFormatTest.testParserRejectTrailingComma
void testParserRejectTrailingComma()
Definition: JsonFormatTest.java:1149
UInt64Value
struct UInt64Value UInt64Value
Definition: php/ext/google/protobuf/protobuf.h:666
com.google.protobuf.util.JsonFormatTest.testParserIntegerEnumValue
void testParserIntegerEnumValue()
Definition: JsonFormatTest.java:1256
com.google.protobuf.util.JsonFormatTest.testWrappers
void testWrappers()
Definition: JsonFormatTest.java:718
StringValue
struct StringValue StringValue
Definition: php/ext/google/protobuf/protobuf.h:660
com.google.protobuf::StringValue
com.google.protobuf.util.JsonFormat.Printer.usingTypeRegistry
Printer usingTypeRegistry(TypeRegistry registry)
Definition: JsonFormat.java:158
TestFieldMask
com.google.protobuf.util.JsonFormat.Printer.sortingMapKeys
final boolean sortingMapKeys
Definition: JsonFormat.java:133
com.google.protobuf.util.JsonFormatTest.testParserMissingTypeUrl
void testParserMissingTypeUrl()
Definition: JsonFormatTest.java:1124
com.google.protobuf.util.FieldMaskUtil
Definition: FieldMaskUtil.java:52
com.google.protobuf::DoubleValue
i
int i
Definition: gmock-matchers_test.cc:764
com.google.protobuf.util.JsonFormatTest.testParserSupportAliasEnums
void testParserSupportAliasEnums()
Definition: JsonFormatTest.java:1217
java
com.google.protobuf.Descriptors.Descriptor
Definition: Descriptors.java:629
FloatValue
struct FloatValue FloatValue
Definition: php/ext/google/protobuf/protobuf.h:641
Int64Value
struct Int64Value Int64Value
Definition: php/ext/google/protobuf/protobuf.h:644
com.google.protobuf.util.JsonFormatTest.toJsonString
String toJsonString(Message message)
Definition: JsonFormatTest.java:155
Any
struct Any Any
Definition: php/ext/google/protobuf/protobuf.h:624
TestAny
com.google.protobuf.util.JsonFormat.Printer
Definition: JsonFormat.java:118
com.google.protobuf::UInt64Value
com.google.protobuf.util.JsonFormatTest.testParserAcceptFloatingPointValueForIntegerField
void testParserAcceptFloatingPointValueForIntegerField()
Definition: JsonFormatTest.java:302
DoubleValue
struct DoubleValue DoubleValue
Definition: php/ext/google/protobuf/protobuf.h:630
com.google.protobuf.util.JsonFormatTest.testParserIgnoringUnknownEnums
void testParserIgnoringUnknownEnums()
Definition: JsonFormatTest.java:1210
com.google.protobuf.util.JsonFormat.Printer.preservingProtoFieldNames
final boolean preservingProtoFieldNames
Definition: JsonFormat.java:130
com.google.protobuf.util.JsonFormatTest.testOmittingInsignificantWhiteSpace
void testOmittingInsignificantWhiteSpace()
Definition: JsonFormatTest.java:1543
com.google.protobuf.util.Timestamps
Definition: Timestamps.java:54
com.google.protobuf.util.JsonFormatTest.testEmptyWrapperTypesInAny
void testEmptyWrapperTypesInAny()
Definition: JsonFormatTest.java:1600
com.google.protobuf.util.JsonFormatTest.toCompactJsonString
String toCompactJsonString(Message message)
Definition: JsonFormatTest.java:158
TestCustomJsonName
com.google.protobuf.util.JsonFormat.TypeRegistry
Definition: JsonFormat.java:436
Json::nullValue
@ nullValue
'null' value
Definition: json.h:464
com.google.protobuf::BytesValue
com.google
com
com.google.protobuf.util.JsonFormatTest.assertRoundTripEquals
void assertRoundTripEquals(Message message, TypeRegistry registry)
Definition: JsonFormatTest.java:146
com.google.protobuf.util.JsonFormat.Parser
Definition: JsonFormat.java:363
UInt32Value
struct UInt32Value UInt32Value
Definition: php/ext/google/protobuf/protobuf.h:665
com.google.protobuf.util.JsonFormatTest.testCustomJsonName
void testCustomJsonName()
Definition: JsonFormatTest.java:1264
Struct
struct Struct Struct
Definition: php/ext/google/protobuf/protobuf.h:661
com.google.protobuf.util.JsonFormatTest.JsonFormatTest
JsonFormatTest()
Definition: JsonFormatTest.java:81
BytesValue
struct BytesValue BytesValue
Definition: php/ext/google/protobuf/protobuf.h:627
com.google.protobuf.util.JsonFormatTest.testAllFields
void testAllFields()
Definition: JsonFormatTest.java:174
TestWrappers
com.google.protobuf::UInt32Value
com.google.protobuf.InvalidProtocolBufferException
Definition: InvalidProtocolBufferException.java:41
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.add
Builder add(Descriptor messageType)
Definition: JsonFormat.java:479
com.google.protobuf.util.JsonFormatTest.testAnyFields
void testAnyFields()
Definition: JsonFormatTest.java:853
f
GLfloat f
Definition: glcorearb.h:3964
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
benchmarks.python.py_benchmark.parser
parser
Definition: py_benchmark.py:10
gmock_test_utils.TestCase
TestCase
Definition: gmock_test_utils.py:97
com.google.protobuf.util.JsonFormatTest.testSortedMapKeys
void testSortedMapKeys()
Definition: JsonFormatTest.java:1677
com.google.protobuf.util.JsonFormatTest.testPreservingProtoFieldNames
void testPreservingProtoFieldNames()
Definition: JsonFormatTest.java:1513
com.google.protobuf.util.JsonFormatTest
Definition: JsonFormatTest.java:80
com.google.protobuf.util.JsonFormatTest.testParserRejectDuplicatedFields
void testParserRejectDuplicatedFields()
Definition: JsonFormatTest.java:481
TestRecursive
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
com.google.protobuf.util.JsonFormatTest.testUnknownEnumMap
void testUnknownEnumMap()
Definition: JsonFormatTest.java:1234
com.google.protobuf.Message
Definition: Message.java:50
com.google.protobuf::Struct
com.google.protobuf.util.JsonFormatTest.testDuration
void testDuration()
Definition: JsonFormatTest.java:785
com.google.protobuf.util.JsonFormat.TypeRegistry.getEmptyTypeRegistry
static TypeRegistry getEmptyTypeRegistry()
Definition: JsonFormat.java:442
com.google.protobuf.Descriptors.FieldDescriptor
Definition: Descriptors.java:949
com.google.protobuf.ByteString
Definition: ByteString.java:67
Value
struct Value Value
Definition: php/ext/google/protobuf/protobuf.h:667


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55