blob: e37a9a3d7ee9b93b719c30df7501e6f7c015998d [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package protojson_test
Herbie Ongc96a79d2019-03-08 10:49:17 -08006
7import (
8 "math"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
Joe Tsaid47ea192019-07-09 22:38:15 -070012 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/proto"
14 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Onge63c4c42019-03-22 22:20:22 -070015
Joe Tsaid47ea192019-07-09 22:38:15 -070016 testpb "google.golang.org/protobuf/internal/testprotos/test"
17 weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
Joe Tsai94e730b2020-01-10 23:31:25 -080018 pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
19 pb3 "google.golang.org/protobuf/internal/testprotos/textpb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070020 "google.golang.org/protobuf/types/known/anypb"
21 "google.golang.org/protobuf/types/known/durationpb"
22 "google.golang.org/protobuf/types/known/emptypb"
23 "google.golang.org/protobuf/types/known/fieldmaskpb"
24 "google.golang.org/protobuf/types/known/structpb"
25 "google.golang.org/protobuf/types/known/timestamppb"
26 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080027)
28
29func TestUnmarshal(t *testing.T) {
30 tests := []struct {
31 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070032 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080033 inputMessage proto.Message
34 inputText string
35 wantMessage proto.Message
36 // TODO: verify expected error message substring.
37 wantErr bool
Joe Tsaid47ea192019-07-09 22:38:15 -070038 skip bool
Herbie Ongc96a79d2019-03-08 10:49:17 -080039 }{{
40 desc: "proto2 empty message",
41 inputMessage: &pb2.Scalars{},
42 inputText: "{}",
43 wantMessage: &pb2.Scalars{},
44 }, {
45 desc: "unexpected value instead of EOF",
46 inputMessage: &pb2.Scalars{},
47 inputText: "{} {}",
48 wantErr: true,
49 }, {
50 desc: "proto2 optional scalars set to zero values",
51 inputMessage: &pb2.Scalars{},
52 inputText: `{
53 "optBool": false,
54 "optInt32": 0,
55 "optInt64": 0,
56 "optUint32": 0,
57 "optUint64": 0,
58 "optSint32": 0,
59 "optSint64": 0,
60 "optFixed32": 0,
61 "optFixed64": 0,
62 "optSfixed32": 0,
63 "optSfixed64": 0,
64 "optFloat": 0,
65 "optDouble": 0,
66 "optBytes": "",
67 "optString": ""
68}`,
69 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070070 OptBool: proto.Bool(false),
71 OptInt32: proto.Int32(0),
72 OptInt64: proto.Int64(0),
73 OptUint32: proto.Uint32(0),
74 OptUint64: proto.Uint64(0),
75 OptSint32: proto.Int32(0),
76 OptSint64: proto.Int64(0),
77 OptFixed32: proto.Uint32(0),
78 OptFixed64: proto.Uint64(0),
79 OptSfixed32: proto.Int32(0),
80 OptSfixed64: proto.Int64(0),
81 OptFloat: proto.Float32(0),
82 OptDouble: proto.Float64(0),
Herbie Ongc96a79d2019-03-08 10:49:17 -080083 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070084 OptString: proto.String(""),
Herbie Ongc96a79d2019-03-08 10:49:17 -080085 },
86 }, {
87 desc: "proto3 scalars set to zero values",
88 inputMessage: &pb3.Scalars{},
89 inputText: `{
90 "sBool": false,
91 "sInt32": 0,
92 "sInt64": 0,
93 "sUint32": 0,
94 "sUint64": 0,
95 "sSint32": 0,
96 "sSint64": 0,
97 "sFixed32": 0,
98 "sFixed64": 0,
99 "sSfixed32": 0,
100 "sSfixed64": 0,
101 "sFloat": 0,
102 "sDouble": 0,
103 "sBytes": "",
104 "sString": ""
105}`,
106 wantMessage: &pb3.Scalars{},
107 }, {
108 desc: "proto2 optional scalars set to null",
109 inputMessage: &pb2.Scalars{},
110 inputText: `{
111 "optBool": null,
112 "optInt32": null,
113 "optInt64": null,
114 "optUint32": null,
115 "optUint64": null,
116 "optSint32": null,
117 "optSint64": null,
118 "optFixed32": null,
119 "optFixed64": null,
120 "optSfixed32": null,
121 "optSfixed64": null,
122 "optFloat": null,
123 "optDouble": null,
124 "optBytes": null,
125 "optString": null
126}`,
127 wantMessage: &pb2.Scalars{},
128 }, {
129 desc: "proto3 scalars set to null",
130 inputMessage: &pb3.Scalars{},
131 inputText: `{
132 "sBool": null,
133 "sInt32": null,
134 "sInt64": null,
135 "sUint32": null,
136 "sUint64": null,
137 "sSint32": null,
138 "sSint64": null,
139 "sFixed32": null,
140 "sFixed64": null,
141 "sSfixed32": null,
142 "sSfixed64": null,
143 "sFloat": null,
144 "sDouble": null,
145 "sBytes": null,
146 "sString": null
147}`,
148 wantMessage: &pb3.Scalars{},
149 }, {
150 desc: "boolean",
151 inputMessage: &pb3.Scalars{},
152 inputText: `{"sBool": true}`,
153 wantMessage: &pb3.Scalars{
154 SBool: true,
155 },
156 }, {
157 desc: "not boolean",
158 inputMessage: &pb3.Scalars{},
159 inputText: `{"sBool": "true"}`,
160 wantErr: true,
161 }, {
162 desc: "float and double",
163 inputMessage: &pb3.Scalars{},
164 inputText: `{
165 "sFloat": 1.234,
166 "sDouble": 5.678
167}`,
168 wantMessage: &pb3.Scalars{
169 SFloat: 1.234,
170 SDouble: 5.678,
171 },
172 }, {
173 desc: "float and double in string",
174 inputMessage: &pb3.Scalars{},
175 inputText: `{
176 "sFloat": "1.234",
177 "sDouble": "5.678"
178}`,
179 wantMessage: &pb3.Scalars{
180 SFloat: 1.234,
181 SDouble: 5.678,
182 },
183 }, {
184 desc: "float and double in E notation",
185 inputMessage: &pb3.Scalars{},
186 inputText: `{
187 "sFloat": 12.34E-1,
188 "sDouble": 5.678e4
189}`,
190 wantMessage: &pb3.Scalars{
191 SFloat: 1.234,
192 SDouble: 56780,
193 },
194 }, {
195 desc: "float and double in string E notation",
196 inputMessage: &pb3.Scalars{},
197 inputText: `{
198 "sFloat": "12.34E-1",
199 "sDouble": "5.678e4"
200}`,
201 wantMessage: &pb3.Scalars{
202 SFloat: 1.234,
203 SDouble: 56780,
204 },
205 }, {
206 desc: "float exceeds limit",
207 inputMessage: &pb3.Scalars{},
208 inputText: `{"sFloat": 3.4e39}`,
209 wantErr: true,
210 }, {
211 desc: "float in string exceeds limit",
212 inputMessage: &pb3.Scalars{},
213 inputText: `{"sFloat": "-3.4e39"}`,
214 wantErr: true,
215 }, {
216 desc: "double exceeds limit",
217 inputMessage: &pb3.Scalars{},
218 inputText: `{"sFloat": -1.79e+309}`,
219 wantErr: true,
220 }, {
221 desc: "double in string exceeds limit",
222 inputMessage: &pb3.Scalars{},
223 inputText: `{"sFloat": "1.79e+309"}`,
224 wantErr: true,
225 }, {
226 desc: "infinites",
227 inputMessage: &pb3.Scalars{},
228 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
229 wantMessage: &pb3.Scalars{
230 SFloat: float32(math.Inf(+1)),
231 SDouble: math.Inf(-1),
232 },
233 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700234 desc: "float string with leading space",
235 inputMessage: &pb3.Scalars{},
236 inputText: `{"sFloat": " 1.234"}`,
237 wantErr: true,
238 }, {
239 desc: "double string with trailing space",
240 inputMessage: &pb3.Scalars{},
241 inputText: `{"sDouble": "5.678 "}`,
242 wantErr: true,
243 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800244 desc: "not float",
245 inputMessage: &pb3.Scalars{},
246 inputText: `{"sFloat": true}`,
247 wantErr: true,
248 }, {
249 desc: "not double",
250 inputMessage: &pb3.Scalars{},
251 inputText: `{"sDouble": "not a number"}`,
252 wantErr: true,
253 }, {
254 desc: "integers",
255 inputMessage: &pb3.Scalars{},
256 inputText: `{
257 "sInt32": 1234,
258 "sInt64": -1234,
259 "sUint32": 1e2,
260 "sUint64": 100E-2,
261 "sSint32": 1.0,
262 "sSint64": -1.0,
263 "sFixed32": 1.234e+5,
264 "sFixed64": 1200E-2,
265 "sSfixed32": -1.234e05,
266 "sSfixed64": -1200e-02
267}`,
268 wantMessage: &pb3.Scalars{
269 SInt32: 1234,
270 SInt64: -1234,
271 SUint32: 100,
272 SUint64: 1,
273 SSint32: 1,
274 SSint64: -1,
275 SFixed32: 123400,
276 SFixed64: 12,
277 SSfixed32: -123400,
278 SSfixed64: -12,
279 },
280 }, {
281 desc: "integers in string",
282 inputMessage: &pb3.Scalars{},
283 inputText: `{
284 "sInt32": "1234",
285 "sInt64": "-1234",
286 "sUint32": "1e2",
287 "sUint64": "100E-2",
288 "sSint32": "1.0",
289 "sSint64": "-1.0",
290 "sFixed32": "1.234e+5",
291 "sFixed64": "1200E-2",
292 "sSfixed32": "-1.234e05",
293 "sSfixed64": "-1200e-02"
294}`,
295 wantMessage: &pb3.Scalars{
296 SInt32: 1234,
297 SInt64: -1234,
298 SUint32: 100,
299 SUint64: 1,
300 SSint32: 1,
301 SSint64: -1,
302 SFixed32: 123400,
303 SFixed64: 12,
304 SSfixed32: -123400,
305 SSfixed64: -12,
306 },
307 }, {
308 desc: "integers in escaped string",
309 inputMessage: &pb3.Scalars{},
310 inputText: `{"sInt32": "\u0031\u0032"}`,
311 wantMessage: &pb3.Scalars{
312 SInt32: 12,
313 },
314 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700315 desc: "integer string with leading space",
316 inputMessage: &pb3.Scalars{},
317 inputText: `{"sInt32": " 1234"}`,
318 wantErr: true,
319 }, {
320 desc: "integer string with trailing space",
321 inputMessage: &pb3.Scalars{},
322 inputText: `{"sUint32": "1e2 "}`,
323 wantErr: true,
324 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800325 desc: "number is not an integer",
326 inputMessage: &pb3.Scalars{},
327 inputText: `{"sInt32": 1.001}`,
328 wantErr: true,
329 }, {
330 desc: "32-bit int exceeds limit",
331 inputMessage: &pb3.Scalars{},
332 inputText: `{"sInt32": 2e10}`,
333 wantErr: true,
334 }, {
335 desc: "64-bit int exceeds limit",
336 inputMessage: &pb3.Scalars{},
337 inputText: `{"sSfixed64": -9e19}`,
338 wantErr: true,
339 }, {
340 desc: "not integer",
341 inputMessage: &pb3.Scalars{},
342 inputText: `{"sInt32": "not a number"}`,
343 wantErr: true,
344 }, {
345 desc: "not unsigned integer",
346 inputMessage: &pb3.Scalars{},
347 inputText: `{"sUint32": "not a number"}`,
348 wantErr: true,
349 }, {
350 desc: "number is not an unsigned integer",
351 inputMessage: &pb3.Scalars{},
352 inputText: `{"sUint32": -1}`,
353 wantErr: true,
354 }, {
355 desc: "string",
356 inputMessage: &pb2.Scalars{},
357 inputText: `{"optString": "谷歌"}`,
358 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700359 OptString: proto.String("谷歌"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800360 },
361 }, {
362 desc: "string with invalid UTF-8",
363 inputMessage: &pb3.Scalars{},
364 inputText: "{\"sString\": \"\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700365 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800366 }, {
367 desc: "not string",
368 inputMessage: &pb2.Scalars{},
369 inputText: `{"optString": 42}`,
370 wantErr: true,
371 }, {
372 desc: "bytes",
373 inputMessage: &pb3.Scalars{},
374 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
375 wantMessage: &pb3.Scalars{
376 SBytes: []byte("hello world"),
377 },
378 }, {
379 desc: "bytes padded",
380 inputMessage: &pb3.Scalars{},
381 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
382 wantMessage: &pb3.Scalars{
383 SBytes: []byte("hello world"),
384 },
385 }, {
386 desc: "not bytes",
387 inputMessage: &pb3.Scalars{},
388 inputText: `{"sBytes": true}`,
389 wantErr: true,
390 }, {
391 desc: "proto2 enum",
392 inputMessage: &pb2.Enums{},
393 inputText: `{
394 "optEnum": "ONE",
395 "optNestedEnum": "UNO"
396}`,
397 wantMessage: &pb2.Enums{
398 OptEnum: pb2.Enum_ONE.Enum(),
399 OptNestedEnum: pb2.Enums_UNO.Enum(),
400 },
401 }, {
402 desc: "proto3 enum",
403 inputMessage: &pb3.Enums{},
404 inputText: `{
405 "sEnum": "ONE",
406 "sNestedEnum": "DIEZ"
407}`,
408 wantMessage: &pb3.Enums{
409 SEnum: pb3.Enum_ONE,
410 SNestedEnum: pb3.Enums_DIEZ,
411 },
412 }, {
413 desc: "enum numeric value",
414 inputMessage: &pb3.Enums{},
415 inputText: `{
416 "sEnum": 2,
417 "sNestedEnum": 2
418}`,
419 wantMessage: &pb3.Enums{
420 SEnum: pb3.Enum_TWO,
421 SNestedEnum: pb3.Enums_DOS,
422 },
423 }, {
424 desc: "enum unnamed numeric value",
425 inputMessage: &pb3.Enums{},
426 inputText: `{
427 "sEnum": 101,
428 "sNestedEnum": -101
429}`,
430 wantMessage: &pb3.Enums{
431 SEnum: 101,
432 SNestedEnum: -101,
433 },
434 }, {
435 desc: "enum set to number string",
436 inputMessage: &pb3.Enums{},
437 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700438 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800439}`,
440 wantErr: true,
441 }, {
442 desc: "enum set to invalid named",
443 inputMessage: &pb3.Enums{},
444 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700445 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800446}`,
447 wantErr: true,
448 }, {
449 desc: "enum set to not enum",
450 inputMessage: &pb3.Enums{},
451 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700452 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800453}`,
454 wantErr: true,
455 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700456 desc: "enum set to JSON null",
457 inputMessage: &pb3.Enums{},
458 inputText: `{
459 "sEnum": null
460}`,
461 wantMessage: &pb3.Enums{},
462 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800463 desc: "proto name",
464 inputMessage: &pb3.JSONNames{},
465 inputText: `{
466 "s_string": "proto name used"
467}`,
468 wantMessage: &pb3.JSONNames{
469 SString: "proto name used",
470 },
471 }, {
Joe Tsai7fa1ee52019-09-15 00:32:55 -0700472 desc: "proto group name",
473 inputMessage: &pb2.Nests{},
474 inputText: `{
475 "OptGroup": {"optString": "hello"},
476 "RptGroup": [{"rptString": ["goodbye"]}]
477 }`,
478 wantMessage: &pb2.Nests{
479 Optgroup: &pb2.Nests_OptGroup{OptString: proto.String("hello")},
480 Rptgroup: []*pb2.Nests_RptGroup{{RptString: []string{"goodbye"}}},
481 },
482 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800483 desc: "json_name",
484 inputMessage: &pb3.JSONNames{},
485 inputText: `{
486 "foo_bar": "json_name used"
487}`,
488 wantMessage: &pb3.JSONNames{
489 SString: "json_name used",
490 },
491 }, {
492 desc: "camelCase name",
493 inputMessage: &pb3.JSONNames{},
494 inputText: `{
495 "sString": "camelcase used"
496}`,
497 wantErr: true,
498 }, {
499 desc: "proto name and json_name",
500 inputMessage: &pb3.JSONNames{},
501 inputText: `{
502 "foo_bar": "json_name used",
503 "s_string": "proto name used"
504}`,
505 wantErr: true,
506 }, {
507 desc: "duplicate field names",
508 inputMessage: &pb3.JSONNames{},
509 inputText: `{
510 "foo_bar": "one",
511 "foo_bar": "two",
512}`,
513 wantErr: true,
514 }, {
515 desc: "null message",
516 inputMessage: &pb2.Nests{},
517 inputText: "null",
518 wantErr: true,
519 }, {
520 desc: "proto2 nested message not set",
521 inputMessage: &pb2.Nests{},
522 inputText: "{}",
523 wantMessage: &pb2.Nests{},
524 }, {
525 desc: "proto2 nested message set to null",
526 inputMessage: &pb2.Nests{},
527 inputText: `{
528 "optNested": null,
529 "optgroup": null
530}`,
531 wantMessage: &pb2.Nests{},
532 }, {
533 desc: "proto2 nested message set to empty",
534 inputMessage: &pb2.Nests{},
535 inputText: `{
536 "optNested": {},
537 "optgroup": {}
538}`,
539 wantMessage: &pb2.Nests{
540 OptNested: &pb2.Nested{},
541 Optgroup: &pb2.Nests_OptGroup{},
542 },
543 }, {
544 desc: "proto2 nested messages",
545 inputMessage: &pb2.Nests{},
546 inputText: `{
547 "optNested": {
548 "optString": "nested message",
549 "optNested": {
550 "optString": "another nested message"
551 }
552 }
553}`,
554 wantMessage: &pb2.Nests{
555 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700556 OptString: proto.String("nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800557 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700558 OptString: proto.String("another nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800559 },
560 },
561 },
562 }, {
563 desc: "proto2 groups",
564 inputMessage: &pb2.Nests{},
565 inputText: `{
566 "optgroup": {
567 "optString": "inside a group",
568 "optNested": {
569 "optString": "nested message inside a group"
570 },
571 "optnestedgroup": {
572 "optFixed32": 47
573 }
574 }
575}`,
576 wantMessage: &pb2.Nests{
577 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700578 OptString: proto.String("inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800579 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700580 OptString: proto.String("nested message inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800581 },
582 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700583 OptFixed32: proto.Uint32(47),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800584 },
585 },
586 },
587 }, {
588 desc: "proto3 nested message not set",
589 inputMessage: &pb3.Nests{},
590 inputText: "{}",
591 wantMessage: &pb3.Nests{},
592 }, {
593 desc: "proto3 nested message set to null",
594 inputMessage: &pb3.Nests{},
595 inputText: `{"sNested": null}`,
596 wantMessage: &pb3.Nests{},
597 }, {
598 desc: "proto3 nested message set to empty",
599 inputMessage: &pb3.Nests{},
600 inputText: `{"sNested": {}}`,
601 wantMessage: &pb3.Nests{
602 SNested: &pb3.Nested{},
603 },
604 }, {
605 desc: "proto3 nested message",
606 inputMessage: &pb3.Nests{},
607 inputText: `{
608 "sNested": {
609 "sString": "nested message",
610 "sNested": {
611 "sString": "another nested message"
612 }
613 }
614}`,
615 wantMessage: &pb3.Nests{
616 SNested: &pb3.Nested{
617 SString: "nested message",
618 SNested: &pb3.Nested{
619 SString: "another nested message",
620 },
621 },
622 },
623 }, {
624 desc: "message set to non-message",
625 inputMessage: &pb3.Nests{},
626 inputText: `"not valid"`,
627 wantErr: true,
628 }, {
629 desc: "nested message set to non-message",
630 inputMessage: &pb3.Nests{},
631 inputText: `{"sNested": true}`,
632 wantErr: true,
633 }, {
634 desc: "oneof not set",
635 inputMessage: &pb3.Oneofs{},
636 inputText: "{}",
637 wantMessage: &pb3.Oneofs{},
638 }, {
639 desc: "oneof set to empty string",
640 inputMessage: &pb3.Oneofs{},
641 inputText: `{"oneofString": ""}`,
642 wantMessage: &pb3.Oneofs{
643 Union: &pb3.Oneofs_OneofString{},
644 },
645 }, {
646 desc: "oneof set to string",
647 inputMessage: &pb3.Oneofs{},
648 inputText: `{"oneofString": "hello"}`,
649 wantMessage: &pb3.Oneofs{
650 Union: &pb3.Oneofs_OneofString{
651 OneofString: "hello",
652 },
653 },
654 }, {
655 desc: "oneof set to enum",
656 inputMessage: &pb3.Oneofs{},
657 inputText: `{"oneofEnum": "ZERO"}`,
658 wantMessage: &pb3.Oneofs{
659 Union: &pb3.Oneofs_OneofEnum{
660 OneofEnum: pb3.Enum_ZERO,
661 },
662 },
663 }, {
664 desc: "oneof set to empty message",
665 inputMessage: &pb3.Oneofs{},
666 inputText: `{"oneofNested": {}}`,
667 wantMessage: &pb3.Oneofs{
668 Union: &pb3.Oneofs_OneofNested{
669 OneofNested: &pb3.Nested{},
670 },
671 },
672 }, {
673 desc: "oneof set to message",
674 inputMessage: &pb3.Oneofs{},
675 inputText: `{
676 "oneofNested": {
677 "sString": "nested message"
678 }
679}`,
680 wantMessage: &pb3.Oneofs{
681 Union: &pb3.Oneofs_OneofNested{
682 OneofNested: &pb3.Nested{
683 SString: "nested message",
684 },
685 },
686 },
687 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700688 desc: "oneof set to more than one field",
689 inputMessage: &pb3.Oneofs{},
690 inputText: `{
691 "oneofEnum": "ZERO",
692 "oneofString": "hello"
693}`,
694 wantErr: true,
695 }, {
696 desc: "oneof set to null and value",
697 inputMessage: &pb3.Oneofs{},
698 inputText: `{
699 "oneofEnum": "ZERO",
700 "oneofString": null
701}`,
702 wantMessage: &pb3.Oneofs{
703 Union: &pb3.Oneofs_OneofEnum{
704 OneofEnum: pb3.Enum_ZERO,
705 },
706 },
707 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800708 desc: "repeated null fields",
709 inputMessage: &pb2.Repeats{},
710 inputText: `{
711 "rptString": null,
712 "rptInt32" : null,
713 "rptFloat" : null,
714 "rptBytes" : null
715}`,
716 wantMessage: &pb2.Repeats{},
717 }, {
718 desc: "repeated scalars",
719 inputMessage: &pb2.Repeats{},
720 inputText: `{
721 "rptString": ["hello", "world"],
722 "rptInt32" : [-1, 0, 1],
723 "rptBool" : [false, true]
724}`,
725 wantMessage: &pb2.Repeats{
726 RptString: []string{"hello", "world"},
727 RptInt32: []int32{-1, 0, 1},
728 RptBool: []bool{false, true},
729 },
730 }, {
731 desc: "repeated enums",
732 inputMessage: &pb2.Enums{},
733 inputText: `{
734 "rptEnum" : ["TEN", 1, 42],
735 "rptNestedEnum": ["DOS", 2, -47]
736}`,
737 wantMessage: &pb2.Enums{
738 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
739 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
740 },
741 }, {
742 desc: "repeated messages",
743 inputMessage: &pb2.Nests{},
744 inputText: `{
745 "rptNested": [
746 {
747 "optString": "repeat nested one"
748 },
749 {
750 "optString": "repeat nested two",
751 "optNested": {
752 "optString": "inside repeat nested two"
753 }
754 },
755 {}
756 ]
757}`,
758 wantMessage: &pb2.Nests{
759 RptNested: []*pb2.Nested{
760 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700761 OptString: proto.String("repeat nested one"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800762 },
763 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700764 OptString: proto.String("repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800765 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700766 OptString: proto.String("inside repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800767 },
768 },
769 {},
770 },
771 },
772 }, {
773 desc: "repeated groups",
774 inputMessage: &pb2.Nests{},
775 inputText: `{
776 "rptgroup": [
777 {
778 "rptString": ["hello", "world"]
779 },
780 {}
781 ]
782}
783`,
784 wantMessage: &pb2.Nests{
785 Rptgroup: []*pb2.Nests_RptGroup{
786 {
787 RptString: []string{"hello", "world"},
788 },
789 {},
790 },
791 },
792 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700793 desc: "repeated string contains invalid UTF8",
794 inputMessage: &pb2.Repeats{},
795 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700796 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700797 }, {
798 desc: "repeated messages contain invalid UTF8",
799 inputMessage: &pb2.Nests{},
800 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700801 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700802 }, {
803 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800804 inputMessage: &pb2.Repeats{},
805 inputText: `{"rptString": ["hello", null, "world"]}`,
806 wantErr: true,
807 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700808 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800809 inputMessage: &pb2.Nests{},
810 inputText: `{"rptNested": [{}, null]}`,
811 wantErr: true,
812 }, {
813 desc: "map fields 1",
814 inputMessage: &pb3.Maps{},
815 inputText: `{
816 "int32ToStr": {
817 "-101": "-101",
818 "0" : "zero",
819 "255" : "0xff"
820 },
821 "boolToUint32": {
822 "false": 101,
823 "true" : "42"
824 }
825}`,
826 wantMessage: &pb3.Maps{
827 Int32ToStr: map[int32]string{
828 -101: "-101",
829 0xff: "0xff",
830 0: "zero",
831 },
832 BoolToUint32: map[bool]uint32{
833 true: 42,
834 false: 101,
835 },
836 },
837 }, {
838 desc: "map fields 2",
839 inputMessage: &pb3.Maps{},
840 inputText: `{
841 "uint64ToEnum": {
842 "1" : "ONE",
843 "2" : 2,
844 "10": 101
845 }
846}`,
847 wantMessage: &pb3.Maps{
848 Uint64ToEnum: map[uint64]pb3.Enum{
849 1: pb3.Enum_ONE,
850 2: pb3.Enum_TWO,
851 10: 101,
852 },
853 },
854 }, {
855 desc: "map fields 3",
856 inputMessage: &pb3.Maps{},
857 inputText: `{
858 "strToNested": {
859 "nested_one": {
860 "sString": "nested in a map"
861 },
862 "nested_two": {}
863 }
864}`,
865 wantMessage: &pb3.Maps{
866 StrToNested: map[string]*pb3.Nested{
867 "nested_one": {
868 SString: "nested in a map",
869 },
870 "nested_two": {},
871 },
872 },
873 }, {
874 desc: "map fields 4",
875 inputMessage: &pb3.Maps{},
876 inputText: `{
877 "strToOneofs": {
878 "nested": {
879 "oneofNested": {
880 "sString": "nested oneof in map field value"
881 }
882 },
883 "string": {
884 "oneofString": "hello"
885 }
886 }
887}`,
888 wantMessage: &pb3.Maps{
889 StrToOneofs: map[string]*pb3.Oneofs{
890 "string": {
891 Union: &pb3.Oneofs_OneofString{
892 OneofString: "hello",
893 },
894 },
895 "nested": {
896 Union: &pb3.Oneofs_OneofNested{
897 OneofNested: &pb3.Nested{
898 SString: "nested oneof in map field value",
899 },
900 },
901 },
902 },
903 },
904 }, {
905 desc: "map contains duplicate keys",
906 inputMessage: &pb3.Maps{},
907 inputText: `{
908 "int32ToStr": {
909 "0": "cero",
910 "0": "zero"
911 }
912}
913`,
914 wantErr: true,
915 }, {
916 desc: "map key empty string",
917 inputMessage: &pb3.Maps{},
918 inputText: `{
919 "strToNested": {
920 "": {}
921 }
922}`,
923 wantMessage: &pb3.Maps{
924 StrToNested: map[string]*pb3.Nested{
925 "": {},
926 },
927 },
928 }, {
929 desc: "map contains invalid key 1",
930 inputMessage: &pb3.Maps{},
931 inputText: `{
932 "int32ToStr": {
933 "invalid": "cero"
934}`,
935 wantErr: true,
936 }, {
937 desc: "map contains invalid key 2",
938 inputMessage: &pb3.Maps{},
939 inputText: `{
940 "int32ToStr": {
941 "1.02": "float"
942}`,
943 wantErr: true,
944 }, {
945 desc: "map contains invalid key 3",
946 inputMessage: &pb3.Maps{},
947 inputText: `{
948 "int32ToStr": {
949 "2147483648": "exceeds 32-bit integer max limit"
950}`,
951 wantErr: true,
952 }, {
953 desc: "map contains invalid key 4",
954 inputMessage: &pb3.Maps{},
955 inputText: `{
956 "uint64ToEnum": {
957 "-1": 0
958 }
959}`,
960 wantErr: true,
961 }, {
962 desc: "map contains invalid value",
963 inputMessage: &pb3.Maps{},
964 inputText: `{
965 "int32ToStr": {
966 "101": true
967}`,
968 wantErr: true,
969 }, {
970 desc: "map contains null for scalar value",
971 inputMessage: &pb3.Maps{},
972 inputText: `{
973 "int32ToStr": {
974 "101": null
975}`,
976 wantErr: true,
977 }, {
978 desc: "map contains null for message value",
979 inputMessage: &pb3.Maps{},
980 inputText: `{
981 "strToNested": {
982 "hello": null
983 }
984}`,
985 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -0700986 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700987 desc: "map contains contains message value with invalid UTF8",
988 inputMessage: &pb3.Maps{},
989 inputText: `{
990 "strToNested": {
991 "hello": {
992 "sString": "` + "abc\xff" + `"
993 }
994 }
995}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700996 wantErr: true,
997 }, {
998 desc: "map key contains invalid UTF8",
999 inputMessage: &pb3.Maps{},
1000 inputText: `{
1001 "strToNested": {
1002 "` + "abc\xff" + `": {}
1003 }
1004}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001005 wantErr: true,
1006 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001007 desc: "required fields not set",
1008 inputMessage: &pb2.Requireds{},
1009 wantErr: true,
1010 }, {
1011 desc: "required field set",
1012 inputMessage: &pb2.PartialRequired{},
1013 inputText: `{
1014 "reqString": "this is required"
1015}`,
1016 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001017 ReqString: proto.String("this is required"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001018 },
1019 }, {
1020 desc: "required fields partially set",
1021 inputMessage: &pb2.Requireds{},
1022 inputText: `{
1023 "reqBool": false,
1024 "reqSfixed64": 42,
1025 "reqString": "hello",
1026 "reqEnum": "ONE"
1027}`,
1028 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001029 ReqBool: proto.Bool(false),
1030 ReqSfixed64: proto.Int64(42),
1031 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001032 ReqEnum: pb2.Enum_ONE.Enum(),
1033 },
1034 wantErr: true,
1035 }, {
1036 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001037 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001038 inputMessage: &pb2.Requireds{},
1039 inputText: `{
1040 "reqBool": false,
1041 "reqSfixed64": 42,
1042 "reqString": "hello",
1043 "reqEnum": "ONE"
1044}`,
1045 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001046 ReqBool: proto.Bool(false),
1047 ReqSfixed64: proto.Int64(42),
1048 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001049 ReqEnum: pb2.Enum_ONE.Enum(),
1050 },
1051 }, {
1052 desc: "required fields all set",
1053 inputMessage: &pb2.Requireds{},
1054 inputText: `{
1055 "reqBool": false,
1056 "reqSfixed64": 42,
1057 "reqDouble": 1.23,
1058 "reqString": "hello",
1059 "reqEnum": "ONE",
1060 "reqNested": {}
1061}`,
1062 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001063 ReqBool: proto.Bool(false),
1064 ReqSfixed64: proto.Int64(42),
1065 ReqDouble: proto.Float64(1.23),
1066 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001067 ReqEnum: pb2.Enum_ONE.Enum(),
1068 ReqNested: &pb2.Nested{},
1069 },
1070 }, {
1071 desc: "indirect required field",
1072 inputMessage: &pb2.IndirectRequired{},
1073 inputText: `{
1074 "optNested": {}
1075}`,
1076 wantMessage: &pb2.IndirectRequired{
1077 OptNested: &pb2.NestedWithRequired{},
1078 },
1079 wantErr: true,
1080 }, {
1081 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001082 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001083 inputMessage: &pb2.IndirectRequired{},
1084 inputText: `{
1085 "optNested": {}
1086}`,
1087 wantMessage: &pb2.IndirectRequired{
1088 OptNested: &pb2.NestedWithRequired{},
1089 },
1090 }, {
1091 desc: "indirect required field in repeated",
1092 inputMessage: &pb2.IndirectRequired{},
1093 inputText: `{
1094 "rptNested": [
1095 {"reqString": "one"},
1096 {}
1097 ]
1098}`,
1099 wantMessage: &pb2.IndirectRequired{
1100 RptNested: []*pb2.NestedWithRequired{
1101 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001102 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001103 },
1104 {},
1105 },
1106 },
1107 wantErr: true,
1108 }, {
1109 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001110 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001111 inputMessage: &pb2.IndirectRequired{},
1112 inputText: `{
1113 "rptNested": [
1114 {"reqString": "one"},
1115 {}
1116 ]
1117}`,
1118 wantMessage: &pb2.IndirectRequired{
1119 RptNested: []*pb2.NestedWithRequired{
1120 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001121 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001122 },
1123 {},
1124 },
1125 },
1126 }, {
1127 desc: "indirect required field in map",
1128 inputMessage: &pb2.IndirectRequired{},
1129 inputText: `{
1130 "strToNested": {
1131 "missing": {},
1132 "contains": {
1133 "reqString": "here"
1134 }
1135 }
1136}`,
1137 wantMessage: &pb2.IndirectRequired{
1138 StrToNested: map[string]*pb2.NestedWithRequired{
1139 "missing": &pb2.NestedWithRequired{},
1140 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001141 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001142 },
1143 },
1144 },
1145 wantErr: true,
1146 }, {
1147 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001148 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001149 inputMessage: &pb2.IndirectRequired{},
1150 inputText: `{
1151 "strToNested": {
1152 "missing": {},
1153 "contains": {
1154 "reqString": "here"
1155 }
1156 }
1157}`,
1158 wantMessage: &pb2.IndirectRequired{
1159 StrToNested: map[string]*pb2.NestedWithRequired{
1160 "missing": &pb2.NestedWithRequired{},
1161 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001162 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001163 },
1164 },
1165 },
1166 }, {
1167 desc: "indirect required field in oneof",
1168 inputMessage: &pb2.IndirectRequired{},
1169 inputText: `{
1170 "oneofNested": {}
1171}`,
1172 wantMessage: &pb2.IndirectRequired{
1173 Union: &pb2.IndirectRequired_OneofNested{
1174 OneofNested: &pb2.NestedWithRequired{},
1175 },
1176 },
1177 wantErr: true,
1178 }, {
1179 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001180 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001181 inputMessage: &pb2.IndirectRequired{},
1182 inputText: `{
1183 "oneofNested": {}
1184}`,
1185 wantMessage: &pb2.IndirectRequired{
1186 Union: &pb2.IndirectRequired_OneofNested{
1187 OneofNested: &pb2.NestedWithRequired{},
1188 },
1189 },
1190 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001191 desc: "extensions of non-repeated fields",
1192 inputMessage: &pb2.Extensions{},
1193 inputText: `{
1194 "optString": "non-extension field",
1195 "optBool": true,
1196 "optInt32": 42,
1197 "[pb2.opt_ext_bool]": true,
1198 "[pb2.opt_ext_nested]": {
1199 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001200 "optNested": {
1201 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001202 }
1203 },
1204 "[pb2.opt_ext_string]": "extension field",
1205 "[pb2.opt_ext_enum]": "TEN"
1206}`,
1207 wantMessage: func() proto.Message {
1208 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001209 OptString: proto.String("non-extension field"),
1210 OptBool: proto.Bool(true),
1211 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001212 }
Damien Neil92f76182019-08-02 16:58:08 -07001213 proto.SetExtension(m, pb2.E_OptExtBool, true)
1214 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
1215 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1216 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001217 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001218 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001219 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001220 },
1221 })
1222 return m
1223 }(),
1224 }, {
1225 desc: "extensions of repeated fields",
1226 inputMessage: &pb2.Extensions{},
1227 inputText: `{
1228 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1229 "[pb2.rpt_ext_fixed32]": [42, 47],
1230 "[pb2.rpt_ext_nested]": [
1231 {"optString": "one"},
1232 {"optString": "two"},
1233 {"optString": "three"}
1234 ]
1235}`,
1236 wantMessage: func() proto.Message {
1237 m := &pb2.Extensions{}
Damien Neil293dc762019-08-29 11:42:57 -07001238 proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1239 proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
1240 proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001241 &pb2.Nested{OptString: proto.String("one")},
1242 &pb2.Nested{OptString: proto.String("two")},
1243 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001244 })
1245 return m
1246 }(),
1247 }, {
1248 desc: "extensions of non-repeated fields in another message",
1249 inputMessage: &pb2.Extensions{},
1250 inputText: `{
1251 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1252 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1253 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1254 "optString": "nested in an extension",
1255 "optNested": {
1256 "optString": "another nested in an extension"
1257 }
1258 },
1259 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1260}`,
1261 wantMessage: func() proto.Message {
1262 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001263 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1264 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1265 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1266 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001267 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001268 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001269 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001270 },
1271 })
1272 return m
1273 }(),
1274 }, {
1275 desc: "extensions of repeated fields in another message",
1276 inputMessage: &pb2.Extensions{},
1277 inputText: `{
1278 "optString": "non-extension field",
1279 "optBool": true,
1280 "optInt32": 42,
1281 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1282 {"optString": "one"},
1283 {"optString": "two"},
1284 {"optString": "three"}
1285 ],
1286 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1287 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1288}`,
1289 wantMessage: func() proto.Message {
1290 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001291 OptString: proto.String("non-extension field"),
1292 OptBool: proto.Bool(true),
1293 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001294 }
Damien Neil293dc762019-08-29 11:42:57 -07001295 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1296 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1297 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001298 &pb2.Nested{OptString: proto.String("one")},
1299 &pb2.Nested{OptString: proto.String("two")},
1300 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001301 })
1302 return m
1303 }(),
1304 }, {
1305 desc: "invalid extension field name",
1306 inputMessage: &pb2.Extensions{},
1307 inputText: `{ "[pb2.invalid_message_field]": true }`,
1308 wantErr: true,
1309 }, {
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001310 desc: "extensions of repeated field contains null",
1311 inputMessage: &pb2.Extensions{},
1312 inputText: `{
1313 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1314 {"optString": "one"},
1315 null,
1316 {"optString": "three"}
1317 ],
1318}`,
1319 wantErr: true,
1320 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001321 desc: "MessageSet",
1322 inputMessage: &pb2.MessageSet{},
1323 inputText: `{
1324 "[pb2.MessageSetExtension]": {
1325 "optString": "a messageset extension"
1326 },
1327 "[pb2.MessageSetExtension.ext_nested]": {
1328 "optString": "just a regular extension"
1329 },
1330 "[pb2.MessageSetExtension.not_message_set_extension]": {
1331 "optString": "not a messageset extension"
1332 }
1333}`,
1334 wantMessage: func() proto.Message {
1335 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001336 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001337 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001338 })
Damien Neil92f76182019-08-02 16:58:08 -07001339 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001340 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001341 })
Damien Neil92f76182019-08-02 16:58:08 -07001342 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001343 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001344 })
1345 return m
1346 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001347 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001348 }, {
1349 desc: "not real MessageSet 1",
1350 inputMessage: &pb2.FakeMessageSet{},
1351 inputText: `{
1352 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1353 "optString": "not a messageset extension"
1354 }
1355}`,
1356 wantMessage: func() proto.Message {
1357 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001358 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001359 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001360 })
1361 return m
1362 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001363 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001364 }, {
1365 desc: "not real MessageSet 2",
1366 inputMessage: &pb2.FakeMessageSet{},
1367 inputText: `{
1368 "[pb2.FakeMessageSetExtension]": {
1369 "optString": "not a messageset extension"
1370 }
1371}`,
1372 wantErr: true,
Joe Tsai1799d112019-08-08 13:31:59 -07001373 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001374 }, {
1375 desc: "not real MessageSet 3",
1376 inputMessage: &pb2.MessageSet{},
1377 inputText: `{
1378 "[pb2.message_set_extension]": {
1379 "optString": "another not a messageset extension"
1380 }
1381}`,
1382 wantMessage: func() proto.Message {
1383 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001384 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001385 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001386 })
1387 return m
1388 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001389 skip: !flags.ProtoLegacy,
Herbie Onge63c4c42019-03-22 22:20:22 -07001390 }, {
1391 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001392 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001393 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001394 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001395 }, {
1396 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001397 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001398 inputText: `{"unknown": null}`,
1399 wantErr: true,
1400 }, {
1401 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001402 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001403 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001404 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001405 }, {
1406 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001407 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001408 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001410 }, {
1411 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001412 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001413 inputText: `{}`,
1414 wantErr: true,
1415 }, {
1416 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001417 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001418 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001419 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001420 }, {
1421 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001422 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001423 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001424 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001425 }, {
1426 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001427 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001428 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001429 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001430 }, {
1431 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001432 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001433 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001435 }, {
1436 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001437 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001438 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001439 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001440 }, {
1441 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001442 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001443 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001445 }, {
1446 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001447 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001448 inputText: `1.23+40`,
1449 wantErr: true,
1450 }, {
1451 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001452 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001453 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001455 }, {
1456 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001457 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001458 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001459 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001460 }, {
1461 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001463 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001464 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001465 }, {
1466 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001467 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001468 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001469 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001470 }, {
1471 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001472 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001473 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001474 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001475 }, {
1476 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001477 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001478 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001479 wantErr: true,
1480 }, {
1481 desc: "StringValue field with invalid UTF8 error",
1482 inputMessage: &pb2.KnownTypes{},
1483 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001484 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001485 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001486 desc: "NullValue field with JSON null",
1487 inputMessage: &pb2.KnownTypes{},
1488 inputText: `{
1489 "optNull": null
1490}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001491 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001492 }, {
1493 desc: "NullValue field with string",
1494 inputMessage: &pb2.KnownTypes{},
1495 inputText: `{
1496 "optNull": "NULL_VALUE"
1497}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001498 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001499 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001500 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001501 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001502 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001503 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001504 }, {
1505 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001506 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001507 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001508 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001509 }, {
1510 desc: "Value field null",
1511 inputMessage: &pb2.KnownTypes{},
1512 inputText: `{
1513 "optValue": null
1514}`,
1515 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001516 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001517 },
1518 }, {
1519 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001520 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001521 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001522 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001523 }, {
1524 desc: "Value field bool",
1525 inputMessage: &pb2.KnownTypes{},
1526 inputText: `{
1527 "optValue": true
1528}`,
1529 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001530 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001531 },
1532 }, {
1533 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001534 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001535 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001536 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001537 }, {
1538 desc: "Value field number",
1539 inputMessage: &pb2.KnownTypes{},
1540 inputText: `{
1541 "optValue": 1.02
1542}`,
1543 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001544 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001545 },
1546 }, {
1547 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001548 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001549 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001550 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001551 }, {
1552 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001553 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001554 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001555 wantErr: true,
1556 }, {
1557 desc: "Value field string",
1558 inputMessage: &pb2.KnownTypes{},
1559 inputText: `{
1560 "optValue": "NaN"
1561}`,
1562 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001563 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001564 },
1565 }, {
1566 desc: "Value field string with invalid UTF8",
1567 inputMessage: &pb2.KnownTypes{},
1568 inputText: `{
1569 "optValue": "` + "\xff" + `"
1570}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001571 wantErr: true,
1572 }, {
1573 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001574 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001575 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001576 wantMessage: &structpb.Value{
1577 Kind: &structpb.Value_StructValue{
1578 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001579 },
1580 },
1581 }, {
1582 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001583 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001584 inputText: `{
1585 "string": "hello",
1586 "number": 123,
1587 "null": null,
1588 "bool": false,
1589 "struct": {
1590 "string": "world"
1591 },
1592 "list": []
1593}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001594 wantMessage: &structpb.Value{
1595 Kind: &structpb.Value_StructValue{
1596 &structpb.Struct{
1597 Fields: map[string]*structpb.Value{
1598 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1599 "number": {Kind: &structpb.Value_NumberValue{123}},
1600 "null": {Kind: &structpb.Value_NullValue{}},
1601 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001602 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001603 Kind: &structpb.Value_StructValue{
1604 &structpb.Struct{
1605 Fields: map[string]*structpb.Value{
1606 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001607 },
1608 },
1609 },
1610 },
1611 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001612 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001613 },
1614 },
1615 },
1616 },
1617 },
1618 }, {
1619 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001620 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001621 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001622 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001623 }, {
1624 desc: "Value field struct",
1625 inputMessage: &pb2.KnownTypes{},
1626 inputText: `{
1627 "optValue": {
1628 "string": "hello"
1629 }
1630}`,
1631 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001632 OptValue: &structpb.Value{
1633 Kind: &structpb.Value_StructValue{
1634 &structpb.Struct{
1635 Fields: map[string]*structpb.Value{
1636 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001637 },
1638 },
1639 },
1640 },
1641 },
1642 }, {
1643 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001644 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001645 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001646 wantMessage: &structpb.Value{
1647 Kind: &structpb.Value_ListValue{
1648 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001649 },
1650 },
1651 }, {
1652 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001653 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001654 inputText: `[
1655 "string",
1656 123,
1657 null,
1658 true,
1659 {},
1660 [
1661 "string",
1662 1.23,
1663 null,
1664 false
1665 ]
1666]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001667 wantMessage: &structpb.Value{
1668 Kind: &structpb.Value_ListValue{
1669 &structpb.ListValue{
1670 Values: []*structpb.Value{
1671 {Kind: &structpb.Value_StringValue{"string"}},
1672 {Kind: &structpb.Value_NumberValue{123}},
1673 {Kind: &structpb.Value_NullValue{}},
1674 {Kind: &structpb.Value_BoolValue{true}},
1675 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001676 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001677 Kind: &structpb.Value_ListValue{
1678 &structpb.ListValue{
1679 Values: []*structpb.Value{
1680 {Kind: &structpb.Value_StringValue{"string"}},
1681 {Kind: &structpb.Value_NumberValue{1.23}},
1682 {Kind: &structpb.Value_NullValue{}},
1683 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001684 },
1685 },
1686 },
1687 },
1688 },
1689 },
1690 },
1691 },
1692 }, {
1693 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001694 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001695 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001696 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001697 }, {
1698 desc: "Value field list with invalid UTF8 string",
1699 inputMessage: &pb2.KnownTypes{},
1700 inputText: `{
1701 "optValue": [ "` + "abc\xff" + `"]
1702}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001703 wantErr: true,
1704 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001705 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001706 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001707 inputText: `""`,
1708 wantErr: true,
1709 }, {
1710 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001711 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001712 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001713 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001714 }, {
1715 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001716 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001717 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001718 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001719 }, {
1720 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001721 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001722 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001723 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001724 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001725 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001726 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001727 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001728 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001729 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001730 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001731 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001732 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001733 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001734 }, {
1735 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001736 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001737 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001738 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001739 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001740 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001741 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001742 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001743 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001744 }, {
1745 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001746 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001747 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001748 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001749 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001750 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001751 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001752 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001753 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001754 }, {
1755 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001756 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001757 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001758 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001759 }, {
1760 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001761 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001762 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001764 }, {
1765 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001766 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001767 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001768 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001769 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001770 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001771 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001772 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001773 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001774 }, {
1775 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001776 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001777 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001778 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001779 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001780 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001781 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001782 inputText: `"315576000001s"`,
1783 wantErr: true,
1784 }, {
1785 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001786 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001787 inputText: `"-315576000001s"`,
1788 wantErr: true,
1789 }, {
1790 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001791 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001792 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001793 wantErr: true,
1794 }, {
1795 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001796 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001797 inputText: `"123"`,
1798 wantErr: true,
1799 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001800 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001801 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001802 inputText: `"123.+123s"`,
1803 wantErr: true,
1804 }, {
1805 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001806 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001807 inputText: `"123.123.s"`,
1808 wantErr: true,
1809 }, {
1810 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001811 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001812 inputText: `"01s"`,
1813 wantErr: true,
1814 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001815 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001816 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001817 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001818 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001819 }, {
1820 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001821 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001822 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001824 }, {
1825 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001826 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001827 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 }, {
1830 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001831 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001832 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 }, {
1835 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001836 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001837 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001838 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001839 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001840 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001841 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001842 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001844 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001845 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001846 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001847 inputText: `"9999-12-31T23:59:59-01:00"`,
1848 wantErr: true,
1849 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001850 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001851 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001852 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001853 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001854 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001855 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001856 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001857 inputText: `"0001-01-01T00:00:00+01:00"`,
1858 wantErr: true,
1859 }, {
1860 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001861 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001862 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1863 wantErr: true,
1864 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001865 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001866 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001867 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001868 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001869 }, {
1870 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001871 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001872 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001873 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001874 Paths: []string{
1875 "foo",
1876 "foo_bar",
1877 "foo.bar_qux",
1878 "_foo",
1879 },
1880 },
1881 }, {
1882 desc: "FieldMask field",
1883 inputMessage: &pb2.KnownTypes{},
1884 inputText: `{
1885 "optFieldmask": "foo, qux.fooBar"
1886}`,
1887 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001888 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001889 Paths: []string{
1890 "foo",
1891 "qux.foo_bar",
1892 },
1893 },
1894 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001895 }, {
1896 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001897 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001898 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001899 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001900 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001901 desc: "Any with non-custom message",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001902 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001903 inputText: `{
1904 "@type": "foo/pb2.Nested",
1905 "optString": "embedded inside Any",
1906 "optNested": {
1907 "optString": "inception"
1908 }
1909}`,
1910 wantMessage: func() proto.Message {
1911 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001912 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001913 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001914 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001915 },
1916 }
1917 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1918 if err != nil {
1919 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1920 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001921 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001922 TypeUrl: "foo/pb2.Nested",
1923 Value: b,
1924 }
1925 }(),
1926 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001927 desc: "Any with empty embedded message",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001928 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001929 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001930 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001931 }, {
1932 desc: "Any without registered type",
Damien Neilc1507ac2019-10-08 13:24:16 -07001933 umo: protojson.UnmarshalOptions{Resolver: new(preg.Types)},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001934 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001935 inputText: `{"@type": "foo/pb2.Nested"}`,
1936 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001937 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001938 desc: "Any with missing required",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001939 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001940 inputText: `{
1941 "@type": "pb2.PartialRequired",
1942 "optString": "embedded inside Any"
1943}`,
1944 wantMessage: func() proto.Message {
1945 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001946 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001947 }
Damien Neil96c229a2019-04-03 12:17:24 -07001948 b, err := proto.MarshalOptions{
1949 Deterministic: true,
1950 AllowPartial: true,
1951 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001952 if err != nil {
1953 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1954 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001955 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001956 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001957 Value: b,
1958 }
1959 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001960 }, {
1961 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001962 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001963 AllowPartial: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001964 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001965 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001966 inputText: `{
1967 "@type": "pb2.PartialRequired",
1968 "optString": "embedded inside Any"
1969}`,
1970 wantMessage: func() proto.Message {
1971 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001972 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001973 }
Damien Neil96c229a2019-04-03 12:17:24 -07001974 b, err := proto.MarshalOptions{
1975 Deterministic: true,
1976 AllowPartial: true,
1977 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001978 if err != nil {
1979 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1980 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001981 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001982 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001983 Value: b,
1984 }
1985 }(),
1986 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001987 desc: "Any with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001988 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001989 inputText: `{
1990 "optString": "` + "abc\xff" + `",
1991 "@type": "foo/pb2.Nested"
1992}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001993 wantErr: true,
1994 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001995 desc: "Any with BoolValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001996 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001997 inputText: `{
1998 "@type": "type.googleapis.com/google.protobuf.BoolValue",
1999 "value": true
2000}`,
2001 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002002 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002003 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2004 if err != nil {
2005 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2006 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002007 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002008 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2009 Value: b,
2010 }
2011 }(),
2012 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002013 desc: "Any with Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002014 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002015 inputText: `{
2016 "value": {},
2017 "@type": "type.googleapis.com/google.protobuf.Empty"
2018}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002019 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002020 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2021 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002022 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002023 desc: "Any with missing Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002024 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002025 inputText: `{
2026 "@type": "type.googleapis.com/google.protobuf.Empty"
2027}`,
2028 wantErr: true,
2029 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002030 desc: "Any with StringValue containing invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002031 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002032 inputText: `{
2033 "@type": "google.protobuf.StringValue",
2034 "value": "` + "abc\xff" + `"
2035}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002036 wantErr: true,
2037 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002038 desc: "Any with Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002039 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002040 inputText: `{
2041 "@type": "google.protobuf.Int64Value",
2042 "value": "42"
2043}`,
2044 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002045 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002046 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2047 if err != nil {
2048 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2049 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002050 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002051 TypeUrl: "google.protobuf.Int64Value",
2052 Value: b,
2053 }
2054 }(),
2055 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002056 desc: "Any with invalid Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002057 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002058 inputText: `{
2059 "@type": "google.protobuf.Int64Value",
2060 "value": "forty-two"
2061}`,
2062 wantErr: true,
2063 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002064 desc: "Any with invalid UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002065 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002066 inputText: `{
2067 "@type": "google.protobuf.UInt64Value",
2068 "value": -42
2069}`,
2070 wantErr: true,
2071 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002072 desc: "Any with Duration",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002073 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002074 inputText: `{
2075 "@type": "type.googleapis.com/google.protobuf.Duration",
2076 "value": "0s"
2077}`,
2078 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002079 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002080 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2081 if err != nil {
2082 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2083 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002084 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002085 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2086 Value: b,
2087 }
2088 }(),
2089 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002090 desc: "Any with Value of StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002091 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002092 inputText: `{
2093 "@type": "google.protobuf.Value",
2094 "value": "` + "abc\xff" + `"
2095}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002096 wantErr: true,
2097 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002098 desc: "Any with Value of NullValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002099 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002100 inputText: `{
2101 "@type": "google.protobuf.Value",
2102 "value": null
2103}`,
2104 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002105 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002106 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2107 if err != nil {
2108 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2109 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002110 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002111 TypeUrl: "google.protobuf.Value",
2112 Value: b,
2113 }
2114 }(),
2115 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002116 desc: "Any with Struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002117 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002118 inputText: `{
2119 "@type": "google.protobuf.Struct",
2120 "value": {
2121 "bool": true,
2122 "null": null,
2123 "string": "hello",
2124 "struct": {
2125 "string": "world"
2126 }
2127 }
2128}`,
2129 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002130 m := &structpb.Struct{
2131 Fields: map[string]*structpb.Value{
2132 "bool": {Kind: &structpb.Value_BoolValue{true}},
2133 "null": {Kind: &structpb.Value_NullValue{}},
2134 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002135 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002136 Kind: &structpb.Value_StructValue{
2137 &structpb.Struct{
2138 Fields: map[string]*structpb.Value{
2139 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002140 },
2141 },
2142 },
2143 },
2144 },
2145 }
2146 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2147 if err != nil {
2148 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2149 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002150 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002151 TypeUrl: "google.protobuf.Struct",
2152 Value: b,
2153 }
2154 }(),
2155 }, {
2156 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002157 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002158 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002159 inputText: `{
2160 "value": {}
2161}`,
2162 wantErr: true,
2163 }, {
2164 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002165 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002166 inputText: `{
2167 "@type": ""
2168}`,
2169 wantErr: true,
2170 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002171 desc: "Any with duplicate @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002172 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002173 inputText: `{
2174 "@type": "google.protobuf.StringValue",
2175 "value": "hello",
2176 "@type": "pb2.Nested"
2177}`,
2178 wantErr: true,
2179 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002180 desc: "Any with duplicate value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002181 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002182 inputText: `{
2183 "@type": "google.protobuf.StringValue",
2184 "value": "hello",
2185 "value": "world"
2186}`,
2187 wantErr: true,
2188 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002189 desc: "Any with unknown field",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002190 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002191 inputText: `{
2192 "@type": "pb2.Nested",
2193 "optString": "hello",
2194 "unknown": "world"
2195}`,
2196 wantErr: true,
2197 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002198 desc: "Any with embedded type containing Any",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002199 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002200 inputText: `{
2201 "@type": "pb2.KnownTypes",
2202 "optAny": {
2203 "@type": "google.protobuf.StringValue",
2204 "value": "` + "abc\xff" + `"
2205 }
2206}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002207 wantErr: true,
2208 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002209 desc: "well known types as field values",
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002210 inputMessage: &pb2.KnownTypes{},
2211 inputText: `{
2212 "optBool": false,
2213 "optInt32": 42,
2214 "optInt64": "42",
2215 "optUint32": 42,
2216 "optUint64": "42",
2217 "optFloat": 1.23,
2218 "optDouble": 3.1415,
2219 "optString": "hello",
2220 "optBytes": "aGVsbG8=",
2221 "optDuration": "123s",
2222 "optTimestamp": "2019-03-19T23:03:21Z",
2223 "optStruct": {
2224 "string": "hello"
2225 },
2226 "optList": [
2227 null,
2228 "",
2229 {},
2230 []
2231 ],
2232 "optValue": "world",
2233 "optEmpty": {},
2234 "optAny": {
2235 "@type": "google.protobuf.Empty",
2236 "value": {}
2237 },
2238 "optFieldmask": "fooBar,barFoo"
2239}`,
2240 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002241 OptBool: &wrapperspb.BoolValue{Value: false},
2242 OptInt32: &wrapperspb.Int32Value{Value: 42},
2243 OptInt64: &wrapperspb.Int64Value{Value: 42},
2244 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2245 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2246 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2247 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2248 OptString: &wrapperspb.StringValue{Value: "hello"},
2249 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2250 OptDuration: &durationpb.Duration{Seconds: 123},
2251 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2252 OptStruct: &structpb.Struct{
2253 Fields: map[string]*structpb.Value{
2254 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002255 },
2256 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002257 OptList: &structpb.ListValue{
2258 Values: []*structpb.Value{
2259 {Kind: &structpb.Value_NullValue{}},
2260 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002261 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002262 Kind: &structpb.Value_StructValue{
2263 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002264 },
2265 },
2266 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002267 Kind: &structpb.Value_ListValue{
2268 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002269 },
2270 },
2271 },
2272 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002273 OptValue: &structpb.Value{
2274 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002275 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002276 OptEmpty: &emptypb.Empty{},
2277 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002278 TypeUrl: "google.protobuf.Empty",
2279 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002280 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002281 Paths: []string{"foo_bar", "bar_foo"},
2282 },
2283 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002284 }, {
2285 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002286 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002287 inputMessage: &pb3.Nests{},
2288 inputText: `{
2289 "sNested": {
2290 "unknown": {
2291 "foo": 1,
2292 "bar": [1, 2, 3]
2293 }
2294 },
2295 "unknown": "not known"
2296}`,
2297 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2298 }, {
2299 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002300 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002301 inputMessage: &pb2.Nests{},
2302 inputText: `{
2303 "rptNested": [
2304 {"unknown": "blah"},
2305 {"optString": "hello"}
2306 ]
2307}`,
2308 wantMessage: &pb2.Nests{
2309 RptNested: []*pb2.Nested{
2310 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002311 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002312 },
2313 },
2314 }, {
2315 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002316 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002317 inputMessage: &pb3.Maps{},
2318 inputText: `{
2319 "strToNested": {
2320 "nested_one": {
2321 "unknown": "what you see is not"
2322 }
2323 }
2324}`,
2325 wantMessage: &pb3.Maps{
2326 StrToNested: map[string]*pb3.Nested{
2327 "nested_one": {},
2328 },
2329 },
2330 }, {
2331 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002332 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002333 inputMessage: &pb2.Extensions{},
2334 inputText: `{
2335 "[pb2.opt_ext_nested]": {
2336 "unknown": []
2337 }
2338}`,
2339 wantMessage: func() proto.Message {
2340 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07002341 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
Herbie Ong4f0be712019-04-25 17:57:12 -07002342 return m
2343 }(),
2344 }, {
2345 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002346 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002347 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002348 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002349 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002350 }, {
2351 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002352 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002353 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002354 inputText: `{
2355 "value": {"foo": "bar"},
2356 "unknown": true
2357}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002358 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002359 }, {
2360 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002361 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002362 DiscardUnknown: true,
Herbie Ong4f0be712019-04-25 17:57:12 -07002363 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002364 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002365 inputText: `{
2366 "@type": "foo/pb2.Nested",
2367 "unknown": "none"
2368}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002369 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002370 TypeUrl: "foo/pb2.Nested",
2371 },
2372 }, {
2373 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002374 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002375 DiscardUnknown: true,
Herbie Ong4f0be712019-04-25 17:57:12 -07002376 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002377 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002378 inputText: `{
2379 "@type": "type.googleapis.com/google.protobuf.Empty",
2380 "value": {"unknown": 47}
2381}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002382 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002383 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2384 },
Joe Tsaid47ea192019-07-09 22:38:15 -07002385 }, {
2386 desc: "weak fields",
2387 inputMessage: &testpb.TestWeak{},
2388 inputText: `{"weak_message1":{"a":1}}`,
2389 wantMessage: func() *testpb.TestWeak {
2390 m := new(testpb.TestWeak)
2391 m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
2392 return m
2393 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07002394 skip: !flags.ProtoLegacy,
Joe Tsaid47ea192019-07-09 22:38:15 -07002395 }, {
2396 desc: "weak fields; unknown field",
2397 inputMessage: &testpb.TestWeak{},
2398 inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
2399 wantErr: true, // weak_message2 is unknown since the package containing it is not imported
Joe Tsai1799d112019-08-08 13:31:59 -07002400 skip: !flags.ProtoLegacy,
Herbie Ongc96a79d2019-03-08 10:49:17 -08002401 }}
2402
2403 for _, tt := range tests {
2404 tt := tt
Joe Tsaid47ea192019-07-09 22:38:15 -07002405 if tt.skip {
2406 continue
2407 }
Herbie Ongc96a79d2019-03-08 10:49:17 -08002408 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002409 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002410 if err != nil && !tt.wantErr {
2411 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2412 }
2413 if err == nil && tt.wantErr {
2414 t.Error("Unmarshal() got nil error, want error\n\n")
2415 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002416 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002417 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2418 }
2419 })
2420 }
2421}