blob: 8f92209a8369e414d0b88cf28d3fd376d6f52fbf [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
5package jsonpb_test
6
7import (
Damien Neilbc310b52019-04-11 11:46:55 -07008 "bytes"
Herbie Ongc96a79d2019-03-08 10:49:17 -08009 "math"
10 "testing"
11
12 protoV1 "github.com/golang/protobuf/proto"
13 "github.com/golang/protobuf/v2/encoding/jsonpb"
14 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
15 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
16 "github.com/golang/protobuf/v2/internal/scalar"
17 "github.com/golang/protobuf/v2/proto"
Herbie Onge52379a2019-03-15 18:00:19 -070018 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Joe Tsai4fddeba2019-03-20 18:29:32 -070019 "github.com/golang/protobuf/v2/runtime/protoiface"
Herbie Onge63c4c42019-03-22 22:20:22 -070020
21 knownpb "github.com/golang/protobuf/v2/types/known"
Herbie Ongc96a79d2019-03-08 10:49:17 -080022)
23
Herbie Onge52379a2019-03-15 18:00:19 -070024func init() {
25 // TODO: remove these registerExtension calls when generated code registers
26 // to V2 global registry.
27 registerExtension(pb2.E_OptExtBool)
28 registerExtension(pb2.E_OptExtString)
29 registerExtension(pb2.E_OptExtEnum)
30 registerExtension(pb2.E_OptExtNested)
31 registerExtension(pb2.E_RptExtFixed32)
32 registerExtension(pb2.E_RptExtEnum)
33 registerExtension(pb2.E_RptExtNested)
34 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
35 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
36 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
37 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
38 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
39 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
40 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
41 registerExtension(pb2.E_MessageSetExtension)
42 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
43 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
44 registerExtension(pb2.E_MessageSetExtension_ExtNested)
45 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
46}
47
Joe Tsai4fddeba2019-03-20 18:29:32 -070048func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Onge52379a2019-03-15 18:00:19 -070049 preg.GlobalTypes.Register(xd.Type)
50}
51
Herbie Ongc96a79d2019-03-08 10:49:17 -080052func TestUnmarshal(t *testing.T) {
53 tests := []struct {
54 desc string
55 umo jsonpb.UnmarshalOptions
56 inputMessage proto.Message
57 inputText string
58 wantMessage proto.Message
59 // TODO: verify expected error message substring.
60 wantErr bool
61 }{{
62 desc: "proto2 empty message",
63 inputMessage: &pb2.Scalars{},
64 inputText: "{}",
65 wantMessage: &pb2.Scalars{},
66 }, {
67 desc: "unexpected value instead of EOF",
68 inputMessage: &pb2.Scalars{},
69 inputText: "{} {}",
70 wantErr: true,
71 }, {
72 desc: "proto2 optional scalars set to zero values",
73 inputMessage: &pb2.Scalars{},
74 inputText: `{
75 "optBool": false,
76 "optInt32": 0,
77 "optInt64": 0,
78 "optUint32": 0,
79 "optUint64": 0,
80 "optSint32": 0,
81 "optSint64": 0,
82 "optFixed32": 0,
83 "optFixed64": 0,
84 "optSfixed32": 0,
85 "optSfixed64": 0,
86 "optFloat": 0,
87 "optDouble": 0,
88 "optBytes": "",
89 "optString": ""
90}`,
91 wantMessage: &pb2.Scalars{
92 OptBool: scalar.Bool(false),
93 OptInt32: scalar.Int32(0),
94 OptInt64: scalar.Int64(0),
95 OptUint32: scalar.Uint32(0),
96 OptUint64: scalar.Uint64(0),
97 OptSint32: scalar.Int32(0),
98 OptSint64: scalar.Int64(0),
99 OptFixed32: scalar.Uint32(0),
100 OptFixed64: scalar.Uint64(0),
101 OptSfixed32: scalar.Int32(0),
102 OptSfixed64: scalar.Int64(0),
103 OptFloat: scalar.Float32(0),
104 OptDouble: scalar.Float64(0),
105 OptBytes: []byte{},
106 OptString: scalar.String(""),
107 },
108 }, {
109 desc: "proto3 scalars set to zero values",
110 inputMessage: &pb3.Scalars{},
111 inputText: `{
112 "sBool": false,
113 "sInt32": 0,
114 "sInt64": 0,
115 "sUint32": 0,
116 "sUint64": 0,
117 "sSint32": 0,
118 "sSint64": 0,
119 "sFixed32": 0,
120 "sFixed64": 0,
121 "sSfixed32": 0,
122 "sSfixed64": 0,
123 "sFloat": 0,
124 "sDouble": 0,
125 "sBytes": "",
126 "sString": ""
127}`,
128 wantMessage: &pb3.Scalars{},
129 }, {
130 desc: "proto2 optional scalars set to null",
131 inputMessage: &pb2.Scalars{},
132 inputText: `{
133 "optBool": null,
134 "optInt32": null,
135 "optInt64": null,
136 "optUint32": null,
137 "optUint64": null,
138 "optSint32": null,
139 "optSint64": null,
140 "optFixed32": null,
141 "optFixed64": null,
142 "optSfixed32": null,
143 "optSfixed64": null,
144 "optFloat": null,
145 "optDouble": null,
146 "optBytes": null,
147 "optString": null
148}`,
149 wantMessage: &pb2.Scalars{},
150 }, {
151 desc: "proto3 scalars set to null",
152 inputMessage: &pb3.Scalars{},
153 inputText: `{
154 "sBool": null,
155 "sInt32": null,
156 "sInt64": null,
157 "sUint32": null,
158 "sUint64": null,
159 "sSint32": null,
160 "sSint64": null,
161 "sFixed32": null,
162 "sFixed64": null,
163 "sSfixed32": null,
164 "sSfixed64": null,
165 "sFloat": null,
166 "sDouble": null,
167 "sBytes": null,
168 "sString": null
169}`,
170 wantMessage: &pb3.Scalars{},
171 }, {
172 desc: "boolean",
173 inputMessage: &pb3.Scalars{},
174 inputText: `{"sBool": true}`,
175 wantMessage: &pb3.Scalars{
176 SBool: true,
177 },
178 }, {
179 desc: "not boolean",
180 inputMessage: &pb3.Scalars{},
181 inputText: `{"sBool": "true"}`,
182 wantErr: true,
183 }, {
184 desc: "float and double",
185 inputMessage: &pb3.Scalars{},
186 inputText: `{
187 "sFloat": 1.234,
188 "sDouble": 5.678
189}`,
190 wantMessage: &pb3.Scalars{
191 SFloat: 1.234,
192 SDouble: 5.678,
193 },
194 }, {
195 desc: "float and double in string",
196 inputMessage: &pb3.Scalars{},
197 inputText: `{
198 "sFloat": "1.234",
199 "sDouble": "5.678"
200}`,
201 wantMessage: &pb3.Scalars{
202 SFloat: 1.234,
203 SDouble: 5.678,
204 },
205 }, {
206 desc: "float and double in E notation",
207 inputMessage: &pb3.Scalars{},
208 inputText: `{
209 "sFloat": 12.34E-1,
210 "sDouble": 5.678e4
211}`,
212 wantMessage: &pb3.Scalars{
213 SFloat: 1.234,
214 SDouble: 56780,
215 },
216 }, {
217 desc: "float and double in string E notation",
218 inputMessage: &pb3.Scalars{},
219 inputText: `{
220 "sFloat": "12.34E-1",
221 "sDouble": "5.678e4"
222}`,
223 wantMessage: &pb3.Scalars{
224 SFloat: 1.234,
225 SDouble: 56780,
226 },
227 }, {
228 desc: "float exceeds limit",
229 inputMessage: &pb3.Scalars{},
230 inputText: `{"sFloat": 3.4e39}`,
231 wantErr: true,
232 }, {
233 desc: "float in string exceeds limit",
234 inputMessage: &pb3.Scalars{},
235 inputText: `{"sFloat": "-3.4e39"}`,
236 wantErr: true,
237 }, {
238 desc: "double exceeds limit",
239 inputMessage: &pb3.Scalars{},
240 inputText: `{"sFloat": -1.79e+309}`,
241 wantErr: true,
242 }, {
243 desc: "double in string exceeds limit",
244 inputMessage: &pb3.Scalars{},
245 inputText: `{"sFloat": "1.79e+309"}`,
246 wantErr: true,
247 }, {
248 desc: "infinites",
249 inputMessage: &pb3.Scalars{},
250 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
251 wantMessage: &pb3.Scalars{
252 SFloat: float32(math.Inf(+1)),
253 SDouble: math.Inf(-1),
254 },
255 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700256 desc: "float string with leading space",
257 inputMessage: &pb3.Scalars{},
258 inputText: `{"sFloat": " 1.234"}`,
259 wantErr: true,
260 }, {
261 desc: "double string with trailing space",
262 inputMessage: &pb3.Scalars{},
263 inputText: `{"sDouble": "5.678 "}`,
264 wantErr: true,
265 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800266 desc: "not float",
267 inputMessage: &pb3.Scalars{},
268 inputText: `{"sFloat": true}`,
269 wantErr: true,
270 }, {
271 desc: "not double",
272 inputMessage: &pb3.Scalars{},
273 inputText: `{"sDouble": "not a number"}`,
274 wantErr: true,
275 }, {
276 desc: "integers",
277 inputMessage: &pb3.Scalars{},
278 inputText: `{
279 "sInt32": 1234,
280 "sInt64": -1234,
281 "sUint32": 1e2,
282 "sUint64": 100E-2,
283 "sSint32": 1.0,
284 "sSint64": -1.0,
285 "sFixed32": 1.234e+5,
286 "sFixed64": 1200E-2,
287 "sSfixed32": -1.234e05,
288 "sSfixed64": -1200e-02
289}`,
290 wantMessage: &pb3.Scalars{
291 SInt32: 1234,
292 SInt64: -1234,
293 SUint32: 100,
294 SUint64: 1,
295 SSint32: 1,
296 SSint64: -1,
297 SFixed32: 123400,
298 SFixed64: 12,
299 SSfixed32: -123400,
300 SSfixed64: -12,
301 },
302 }, {
303 desc: "integers in string",
304 inputMessage: &pb3.Scalars{},
305 inputText: `{
306 "sInt32": "1234",
307 "sInt64": "-1234",
308 "sUint32": "1e2",
309 "sUint64": "100E-2",
310 "sSint32": "1.0",
311 "sSint64": "-1.0",
312 "sFixed32": "1.234e+5",
313 "sFixed64": "1200E-2",
314 "sSfixed32": "-1.234e05",
315 "sSfixed64": "-1200e-02"
316}`,
317 wantMessage: &pb3.Scalars{
318 SInt32: 1234,
319 SInt64: -1234,
320 SUint32: 100,
321 SUint64: 1,
322 SSint32: 1,
323 SSint64: -1,
324 SFixed32: 123400,
325 SFixed64: 12,
326 SSfixed32: -123400,
327 SSfixed64: -12,
328 },
329 }, {
330 desc: "integers in escaped string",
331 inputMessage: &pb3.Scalars{},
332 inputText: `{"sInt32": "\u0031\u0032"}`,
333 wantMessage: &pb3.Scalars{
334 SInt32: 12,
335 },
336 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700337 desc: "integer string with leading space",
338 inputMessage: &pb3.Scalars{},
339 inputText: `{"sInt32": " 1234"}`,
340 wantErr: true,
341 }, {
342 desc: "integer string with trailing space",
343 inputMessage: &pb3.Scalars{},
344 inputText: `{"sUint32": "1e2 "}`,
345 wantErr: true,
346 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800347 desc: "number is not an integer",
348 inputMessage: &pb3.Scalars{},
349 inputText: `{"sInt32": 1.001}`,
350 wantErr: true,
351 }, {
352 desc: "32-bit int exceeds limit",
353 inputMessage: &pb3.Scalars{},
354 inputText: `{"sInt32": 2e10}`,
355 wantErr: true,
356 }, {
357 desc: "64-bit int exceeds limit",
358 inputMessage: &pb3.Scalars{},
359 inputText: `{"sSfixed64": -9e19}`,
360 wantErr: true,
361 }, {
362 desc: "not integer",
363 inputMessage: &pb3.Scalars{},
364 inputText: `{"sInt32": "not a number"}`,
365 wantErr: true,
366 }, {
367 desc: "not unsigned integer",
368 inputMessage: &pb3.Scalars{},
369 inputText: `{"sUint32": "not a number"}`,
370 wantErr: true,
371 }, {
372 desc: "number is not an unsigned integer",
373 inputMessage: &pb3.Scalars{},
374 inputText: `{"sUint32": -1}`,
375 wantErr: true,
376 }, {
377 desc: "string",
378 inputMessage: &pb2.Scalars{},
379 inputText: `{"optString": "谷歌"}`,
380 wantMessage: &pb2.Scalars{
381 OptString: scalar.String("谷歌"),
382 },
383 }, {
384 desc: "string with invalid UTF-8",
385 inputMessage: &pb3.Scalars{},
386 inputText: "{\"sString\": \"\xff\"}",
387 wantMessage: &pb3.Scalars{
388 SString: "\xff",
389 },
390 wantErr: true,
391 }, {
392 desc: "not string",
393 inputMessage: &pb2.Scalars{},
394 inputText: `{"optString": 42}`,
395 wantErr: true,
396 }, {
397 desc: "bytes",
398 inputMessage: &pb3.Scalars{},
399 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
400 wantMessage: &pb3.Scalars{
401 SBytes: []byte("hello world"),
402 },
403 }, {
404 desc: "bytes padded",
405 inputMessage: &pb3.Scalars{},
406 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
407 wantMessage: &pb3.Scalars{
408 SBytes: []byte("hello world"),
409 },
410 }, {
411 desc: "not bytes",
412 inputMessage: &pb3.Scalars{},
413 inputText: `{"sBytes": true}`,
414 wantErr: true,
415 }, {
416 desc: "proto2 enum",
417 inputMessage: &pb2.Enums{},
418 inputText: `{
419 "optEnum": "ONE",
420 "optNestedEnum": "UNO"
421}`,
422 wantMessage: &pb2.Enums{
423 OptEnum: pb2.Enum_ONE.Enum(),
424 OptNestedEnum: pb2.Enums_UNO.Enum(),
425 },
426 }, {
427 desc: "proto3 enum",
428 inputMessage: &pb3.Enums{},
429 inputText: `{
430 "sEnum": "ONE",
431 "sNestedEnum": "DIEZ"
432}`,
433 wantMessage: &pb3.Enums{
434 SEnum: pb3.Enum_ONE,
435 SNestedEnum: pb3.Enums_DIEZ,
436 },
437 }, {
438 desc: "enum numeric value",
439 inputMessage: &pb3.Enums{},
440 inputText: `{
441 "sEnum": 2,
442 "sNestedEnum": 2
443}`,
444 wantMessage: &pb3.Enums{
445 SEnum: pb3.Enum_TWO,
446 SNestedEnum: pb3.Enums_DOS,
447 },
448 }, {
449 desc: "enum unnamed numeric value",
450 inputMessage: &pb3.Enums{},
451 inputText: `{
452 "sEnum": 101,
453 "sNestedEnum": -101
454}`,
455 wantMessage: &pb3.Enums{
456 SEnum: 101,
457 SNestedEnum: -101,
458 },
459 }, {
460 desc: "enum set to number string",
461 inputMessage: &pb3.Enums{},
462 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700463 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800464}`,
465 wantErr: true,
466 }, {
467 desc: "enum set to invalid named",
468 inputMessage: &pb3.Enums{},
469 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700470 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800471}`,
472 wantErr: true,
473 }, {
474 desc: "enum set to not enum",
475 inputMessage: &pb3.Enums{},
476 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700477 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800478}`,
479 wantErr: true,
480 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700481 desc: "enum set to JSON null",
482 inputMessage: &pb3.Enums{},
483 inputText: `{
484 "sEnum": null
485}`,
486 wantMessage: &pb3.Enums{},
487 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800488 desc: "proto name",
489 inputMessage: &pb3.JSONNames{},
490 inputText: `{
491 "s_string": "proto name used"
492}`,
493 wantMessage: &pb3.JSONNames{
494 SString: "proto name used",
495 },
496 }, {
497 desc: "json_name",
498 inputMessage: &pb3.JSONNames{},
499 inputText: `{
500 "foo_bar": "json_name used"
501}`,
502 wantMessage: &pb3.JSONNames{
503 SString: "json_name used",
504 },
505 }, {
506 desc: "camelCase name",
507 inputMessage: &pb3.JSONNames{},
508 inputText: `{
509 "sString": "camelcase used"
510}`,
511 wantErr: true,
512 }, {
513 desc: "proto name and json_name",
514 inputMessage: &pb3.JSONNames{},
515 inputText: `{
516 "foo_bar": "json_name used",
517 "s_string": "proto name used"
518}`,
519 wantErr: true,
520 }, {
521 desc: "duplicate field names",
522 inputMessage: &pb3.JSONNames{},
523 inputText: `{
524 "foo_bar": "one",
525 "foo_bar": "two",
526}`,
527 wantErr: true,
528 }, {
529 desc: "null message",
530 inputMessage: &pb2.Nests{},
531 inputText: "null",
532 wantErr: true,
533 }, {
534 desc: "proto2 nested message not set",
535 inputMessage: &pb2.Nests{},
536 inputText: "{}",
537 wantMessage: &pb2.Nests{},
538 }, {
539 desc: "proto2 nested message set to null",
540 inputMessage: &pb2.Nests{},
541 inputText: `{
542 "optNested": null,
543 "optgroup": null
544}`,
545 wantMessage: &pb2.Nests{},
546 }, {
547 desc: "proto2 nested message set to empty",
548 inputMessage: &pb2.Nests{},
549 inputText: `{
550 "optNested": {},
551 "optgroup": {}
552}`,
553 wantMessage: &pb2.Nests{
554 OptNested: &pb2.Nested{},
555 Optgroup: &pb2.Nests_OptGroup{},
556 },
557 }, {
558 desc: "proto2 nested messages",
559 inputMessage: &pb2.Nests{},
560 inputText: `{
561 "optNested": {
562 "optString": "nested message",
563 "optNested": {
564 "optString": "another nested message"
565 }
566 }
567}`,
568 wantMessage: &pb2.Nests{
569 OptNested: &pb2.Nested{
570 OptString: scalar.String("nested message"),
571 OptNested: &pb2.Nested{
572 OptString: scalar.String("another nested message"),
573 },
574 },
575 },
576 }, {
577 desc: "proto2 groups",
578 inputMessage: &pb2.Nests{},
579 inputText: `{
580 "optgroup": {
581 "optString": "inside a group",
582 "optNested": {
583 "optString": "nested message inside a group"
584 },
585 "optnestedgroup": {
586 "optFixed32": 47
587 }
588 }
589}`,
590 wantMessage: &pb2.Nests{
591 Optgroup: &pb2.Nests_OptGroup{
592 OptString: scalar.String("inside a group"),
593 OptNested: &pb2.Nested{
594 OptString: scalar.String("nested message inside a group"),
595 },
596 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
597 OptFixed32: scalar.Uint32(47),
598 },
599 },
600 },
601 }, {
602 desc: "proto3 nested message not set",
603 inputMessage: &pb3.Nests{},
604 inputText: "{}",
605 wantMessage: &pb3.Nests{},
606 }, {
607 desc: "proto3 nested message set to null",
608 inputMessage: &pb3.Nests{},
609 inputText: `{"sNested": null}`,
610 wantMessage: &pb3.Nests{},
611 }, {
612 desc: "proto3 nested message set to empty",
613 inputMessage: &pb3.Nests{},
614 inputText: `{"sNested": {}}`,
615 wantMessage: &pb3.Nests{
616 SNested: &pb3.Nested{},
617 },
618 }, {
619 desc: "proto3 nested message",
620 inputMessage: &pb3.Nests{},
621 inputText: `{
622 "sNested": {
623 "sString": "nested message",
624 "sNested": {
625 "sString": "another nested message"
626 }
627 }
628}`,
629 wantMessage: &pb3.Nests{
630 SNested: &pb3.Nested{
631 SString: "nested message",
632 SNested: &pb3.Nested{
633 SString: "another nested message",
634 },
635 },
636 },
637 }, {
638 desc: "message set to non-message",
639 inputMessage: &pb3.Nests{},
640 inputText: `"not valid"`,
641 wantErr: true,
642 }, {
643 desc: "nested message set to non-message",
644 inputMessage: &pb3.Nests{},
645 inputText: `{"sNested": true}`,
646 wantErr: true,
647 }, {
648 desc: "oneof not set",
649 inputMessage: &pb3.Oneofs{},
650 inputText: "{}",
651 wantMessage: &pb3.Oneofs{},
652 }, {
653 desc: "oneof set to empty string",
654 inputMessage: &pb3.Oneofs{},
655 inputText: `{"oneofString": ""}`,
656 wantMessage: &pb3.Oneofs{
657 Union: &pb3.Oneofs_OneofString{},
658 },
659 }, {
660 desc: "oneof set to string",
661 inputMessage: &pb3.Oneofs{},
662 inputText: `{"oneofString": "hello"}`,
663 wantMessage: &pb3.Oneofs{
664 Union: &pb3.Oneofs_OneofString{
665 OneofString: "hello",
666 },
667 },
668 }, {
669 desc: "oneof set to enum",
670 inputMessage: &pb3.Oneofs{},
671 inputText: `{"oneofEnum": "ZERO"}`,
672 wantMessage: &pb3.Oneofs{
673 Union: &pb3.Oneofs_OneofEnum{
674 OneofEnum: pb3.Enum_ZERO,
675 },
676 },
677 }, {
678 desc: "oneof set to empty message",
679 inputMessage: &pb3.Oneofs{},
680 inputText: `{"oneofNested": {}}`,
681 wantMessage: &pb3.Oneofs{
682 Union: &pb3.Oneofs_OneofNested{
683 OneofNested: &pb3.Nested{},
684 },
685 },
686 }, {
687 desc: "oneof set to message",
688 inputMessage: &pb3.Oneofs{},
689 inputText: `{
690 "oneofNested": {
691 "sString": "nested message"
692 }
693}`,
694 wantMessage: &pb3.Oneofs{
695 Union: &pb3.Oneofs_OneofNested{
696 OneofNested: &pb3.Nested{
697 SString: "nested message",
698 },
699 },
700 },
701 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700702 desc: "oneof set to more than one field",
703 inputMessage: &pb3.Oneofs{},
704 inputText: `{
705 "oneofEnum": "ZERO",
706 "oneofString": "hello"
707}`,
708 wantErr: true,
709 }, {
710 desc: "oneof set to null and value",
711 inputMessage: &pb3.Oneofs{},
712 inputText: `{
713 "oneofEnum": "ZERO",
714 "oneofString": null
715}`,
716 wantMessage: &pb3.Oneofs{
717 Union: &pb3.Oneofs_OneofEnum{
718 OneofEnum: pb3.Enum_ZERO,
719 },
720 },
721 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800722 desc: "repeated null fields",
723 inputMessage: &pb2.Repeats{},
724 inputText: `{
725 "rptString": null,
726 "rptInt32" : null,
727 "rptFloat" : null,
728 "rptBytes" : null
729}`,
730 wantMessage: &pb2.Repeats{},
731 }, {
732 desc: "repeated scalars",
733 inputMessage: &pb2.Repeats{},
734 inputText: `{
735 "rptString": ["hello", "world"],
736 "rptInt32" : [-1, 0, 1],
737 "rptBool" : [false, true]
738}`,
739 wantMessage: &pb2.Repeats{
740 RptString: []string{"hello", "world"},
741 RptInt32: []int32{-1, 0, 1},
742 RptBool: []bool{false, true},
743 },
744 }, {
745 desc: "repeated enums",
746 inputMessage: &pb2.Enums{},
747 inputText: `{
748 "rptEnum" : ["TEN", 1, 42],
749 "rptNestedEnum": ["DOS", 2, -47]
750}`,
751 wantMessage: &pb2.Enums{
752 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
753 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
754 },
755 }, {
756 desc: "repeated messages",
757 inputMessage: &pb2.Nests{},
758 inputText: `{
759 "rptNested": [
760 {
761 "optString": "repeat nested one"
762 },
763 {
764 "optString": "repeat nested two",
765 "optNested": {
766 "optString": "inside repeat nested two"
767 }
768 },
769 {}
770 ]
771}`,
772 wantMessage: &pb2.Nests{
773 RptNested: []*pb2.Nested{
774 {
775 OptString: scalar.String("repeat nested one"),
776 },
777 {
778 OptString: scalar.String("repeat nested two"),
779 OptNested: &pb2.Nested{
780 OptString: scalar.String("inside repeat nested two"),
781 },
782 },
783 {},
784 },
785 },
786 }, {
787 desc: "repeated groups",
788 inputMessage: &pb2.Nests{},
789 inputText: `{
790 "rptgroup": [
791 {
792 "rptString": ["hello", "world"]
793 },
794 {}
795 ]
796}
797`,
798 wantMessage: &pb2.Nests{
799 Rptgroup: []*pb2.Nests_RptGroup{
800 {
801 RptString: []string{"hello", "world"},
802 },
803 {},
804 },
805 },
806 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700807 desc: "repeated string contains invalid UTF8",
808 inputMessage: &pb2.Repeats{},
809 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
810 wantMessage: &pb2.Repeats{
811 RptString: []string{"abc\xff"},
812 },
813 wantErr: true,
814 }, {
815 desc: "repeated messages contain invalid UTF8",
816 inputMessage: &pb2.Nests{},
817 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
818 wantMessage: &pb2.Nests{
819 RptNested: []*pb2.Nested{{OptString: scalar.String("abc\xff")}},
820 },
821 wantErr: true,
822 }, {
823 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800824 inputMessage: &pb2.Repeats{},
825 inputText: `{"rptString": ["hello", null, "world"]}`,
826 wantErr: true,
827 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700828 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800829 inputMessage: &pb2.Nests{},
830 inputText: `{"rptNested": [{}, null]}`,
831 wantErr: true,
832 }, {
833 desc: "map fields 1",
834 inputMessage: &pb3.Maps{},
835 inputText: `{
836 "int32ToStr": {
837 "-101": "-101",
838 "0" : "zero",
839 "255" : "0xff"
840 },
841 "boolToUint32": {
842 "false": 101,
843 "true" : "42"
844 }
845}`,
846 wantMessage: &pb3.Maps{
847 Int32ToStr: map[int32]string{
848 -101: "-101",
849 0xff: "0xff",
850 0: "zero",
851 },
852 BoolToUint32: map[bool]uint32{
853 true: 42,
854 false: 101,
855 },
856 },
857 }, {
858 desc: "map fields 2",
859 inputMessage: &pb3.Maps{},
860 inputText: `{
861 "uint64ToEnum": {
862 "1" : "ONE",
863 "2" : 2,
864 "10": 101
865 }
866}`,
867 wantMessage: &pb3.Maps{
868 Uint64ToEnum: map[uint64]pb3.Enum{
869 1: pb3.Enum_ONE,
870 2: pb3.Enum_TWO,
871 10: 101,
872 },
873 },
874 }, {
875 desc: "map fields 3",
876 inputMessage: &pb3.Maps{},
877 inputText: `{
878 "strToNested": {
879 "nested_one": {
880 "sString": "nested in a map"
881 },
882 "nested_two": {}
883 }
884}`,
885 wantMessage: &pb3.Maps{
886 StrToNested: map[string]*pb3.Nested{
887 "nested_one": {
888 SString: "nested in a map",
889 },
890 "nested_two": {},
891 },
892 },
893 }, {
894 desc: "map fields 4",
895 inputMessage: &pb3.Maps{},
896 inputText: `{
897 "strToOneofs": {
898 "nested": {
899 "oneofNested": {
900 "sString": "nested oneof in map field value"
901 }
902 },
903 "string": {
904 "oneofString": "hello"
905 }
906 }
907}`,
908 wantMessage: &pb3.Maps{
909 StrToOneofs: map[string]*pb3.Oneofs{
910 "string": {
911 Union: &pb3.Oneofs_OneofString{
912 OneofString: "hello",
913 },
914 },
915 "nested": {
916 Union: &pb3.Oneofs_OneofNested{
917 OneofNested: &pb3.Nested{
918 SString: "nested oneof in map field value",
919 },
920 },
921 },
922 },
923 },
924 }, {
925 desc: "map contains duplicate keys",
926 inputMessage: &pb3.Maps{},
927 inputText: `{
928 "int32ToStr": {
929 "0": "cero",
930 "0": "zero"
931 }
932}
933`,
934 wantErr: true,
935 }, {
936 desc: "map key empty string",
937 inputMessage: &pb3.Maps{},
938 inputText: `{
939 "strToNested": {
940 "": {}
941 }
942}`,
943 wantMessage: &pb3.Maps{
944 StrToNested: map[string]*pb3.Nested{
945 "": {},
946 },
947 },
948 }, {
949 desc: "map contains invalid key 1",
950 inputMessage: &pb3.Maps{},
951 inputText: `{
952 "int32ToStr": {
953 "invalid": "cero"
954}`,
955 wantErr: true,
956 }, {
957 desc: "map contains invalid key 2",
958 inputMessage: &pb3.Maps{},
959 inputText: `{
960 "int32ToStr": {
961 "1.02": "float"
962}`,
963 wantErr: true,
964 }, {
965 desc: "map contains invalid key 3",
966 inputMessage: &pb3.Maps{},
967 inputText: `{
968 "int32ToStr": {
969 "2147483648": "exceeds 32-bit integer max limit"
970}`,
971 wantErr: true,
972 }, {
973 desc: "map contains invalid key 4",
974 inputMessage: &pb3.Maps{},
975 inputText: `{
976 "uint64ToEnum": {
977 "-1": 0
978 }
979}`,
980 wantErr: true,
981 }, {
982 desc: "map contains invalid value",
983 inputMessage: &pb3.Maps{},
984 inputText: `{
985 "int32ToStr": {
986 "101": true
987}`,
988 wantErr: true,
989 }, {
990 desc: "map contains null for scalar value",
991 inputMessage: &pb3.Maps{},
992 inputText: `{
993 "int32ToStr": {
994 "101": null
995}`,
996 wantErr: true,
997 }, {
998 desc: "map contains null for message value",
999 inputMessage: &pb3.Maps{},
1000 inputText: `{
1001 "strToNested": {
1002 "hello": null
1003 }
1004}`,
1005 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -07001006 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001007 desc: "map contains contains message value with invalid UTF8",
1008 inputMessage: &pb3.Maps{},
1009 inputText: `{
1010 "strToNested": {
1011 "hello": {
1012 "sString": "` + "abc\xff" + `"
1013 }
1014 }
1015}`,
1016 wantMessage: &pb3.Maps{
1017 StrToNested: map[string]*pb3.Nested{
1018 "hello": {SString: "abc\xff"},
1019 },
1020 },
1021 wantErr: true,
1022 }, {
1023 desc: "map key contains invalid UTF8",
1024 inputMessage: &pb3.Maps{},
1025 inputText: `{
1026 "strToNested": {
1027 "` + "abc\xff" + `": {}
1028 }
1029}`,
1030 wantMessage: &pb3.Maps{
1031 StrToNested: map[string]*pb3.Nested{
1032 "abc\xff": {},
1033 },
1034 },
1035 wantErr: true,
1036 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001037 desc: "required fields not set",
1038 inputMessage: &pb2.Requireds{},
1039 wantErr: true,
1040 }, {
1041 desc: "required field set",
1042 inputMessage: &pb2.PartialRequired{},
1043 inputText: `{
1044 "reqString": "this is required"
1045}`,
1046 wantMessage: &pb2.PartialRequired{
1047 ReqString: scalar.String("this is required"),
1048 },
1049 }, {
1050 desc: "required fields partially set",
1051 inputMessage: &pb2.Requireds{},
1052 inputText: `{
1053 "reqBool": false,
1054 "reqSfixed64": 42,
1055 "reqString": "hello",
1056 "reqEnum": "ONE"
1057}`,
1058 wantMessage: &pb2.Requireds{
1059 ReqBool: scalar.Bool(false),
1060 ReqSfixed64: scalar.Int64(42),
1061 ReqString: scalar.String("hello"),
1062 ReqEnum: pb2.Enum_ONE.Enum(),
1063 },
1064 wantErr: true,
1065 }, {
1066 desc: "required fields partially set with AllowPartial",
1067 umo: jsonpb.UnmarshalOptions{AllowPartial: true},
1068 inputMessage: &pb2.Requireds{},
1069 inputText: `{
1070 "reqBool": false,
1071 "reqSfixed64": 42,
1072 "reqString": "hello",
1073 "reqEnum": "ONE"
1074}`,
1075 wantMessage: &pb2.Requireds{
1076 ReqBool: scalar.Bool(false),
1077 ReqSfixed64: scalar.Int64(42),
1078 ReqString: scalar.String("hello"),
1079 ReqEnum: pb2.Enum_ONE.Enum(),
1080 },
1081 }, {
1082 desc: "required fields all set",
1083 inputMessage: &pb2.Requireds{},
1084 inputText: `{
1085 "reqBool": false,
1086 "reqSfixed64": 42,
1087 "reqDouble": 1.23,
1088 "reqString": "hello",
1089 "reqEnum": "ONE",
1090 "reqNested": {}
1091}`,
1092 wantMessage: &pb2.Requireds{
1093 ReqBool: scalar.Bool(false),
1094 ReqSfixed64: scalar.Int64(42),
1095 ReqDouble: scalar.Float64(1.23),
1096 ReqString: scalar.String("hello"),
1097 ReqEnum: pb2.Enum_ONE.Enum(),
1098 ReqNested: &pb2.Nested{},
1099 },
1100 }, {
1101 desc: "indirect required field",
1102 inputMessage: &pb2.IndirectRequired{},
1103 inputText: `{
1104 "optNested": {}
1105}`,
1106 wantMessage: &pb2.IndirectRequired{
1107 OptNested: &pb2.NestedWithRequired{},
1108 },
1109 wantErr: true,
1110 }, {
1111 desc: "indirect required field with AllowPartial",
1112 umo: jsonpb.UnmarshalOptions{AllowPartial: true},
1113 inputMessage: &pb2.IndirectRequired{},
1114 inputText: `{
1115 "optNested": {}
1116}`,
1117 wantMessage: &pb2.IndirectRequired{
1118 OptNested: &pb2.NestedWithRequired{},
1119 },
1120 }, {
1121 desc: "indirect required field in repeated",
1122 inputMessage: &pb2.IndirectRequired{},
1123 inputText: `{
1124 "rptNested": [
1125 {"reqString": "one"},
1126 {}
1127 ]
1128}`,
1129 wantMessage: &pb2.IndirectRequired{
1130 RptNested: []*pb2.NestedWithRequired{
1131 {
1132 ReqString: scalar.String("one"),
1133 },
1134 {},
1135 },
1136 },
1137 wantErr: true,
1138 }, {
1139 desc: "indirect required field in repeated with AllowPartial",
1140 umo: jsonpb.UnmarshalOptions{AllowPartial: true},
1141 inputMessage: &pb2.IndirectRequired{},
1142 inputText: `{
1143 "rptNested": [
1144 {"reqString": "one"},
1145 {}
1146 ]
1147}`,
1148 wantMessage: &pb2.IndirectRequired{
1149 RptNested: []*pb2.NestedWithRequired{
1150 {
1151 ReqString: scalar.String("one"),
1152 },
1153 {},
1154 },
1155 },
1156 }, {
1157 desc: "indirect required field in map",
1158 inputMessage: &pb2.IndirectRequired{},
1159 inputText: `{
1160 "strToNested": {
1161 "missing": {},
1162 "contains": {
1163 "reqString": "here"
1164 }
1165 }
1166}`,
1167 wantMessage: &pb2.IndirectRequired{
1168 StrToNested: map[string]*pb2.NestedWithRequired{
1169 "missing": &pb2.NestedWithRequired{},
1170 "contains": &pb2.NestedWithRequired{
1171 ReqString: scalar.String("here"),
1172 },
1173 },
1174 },
1175 wantErr: true,
1176 }, {
1177 desc: "indirect required field in map with AllowPartial",
1178 umo: jsonpb.UnmarshalOptions{AllowPartial: true},
1179 inputMessage: &pb2.IndirectRequired{},
1180 inputText: `{
1181 "strToNested": {
1182 "missing": {},
1183 "contains": {
1184 "reqString": "here"
1185 }
1186 }
1187}`,
1188 wantMessage: &pb2.IndirectRequired{
1189 StrToNested: map[string]*pb2.NestedWithRequired{
1190 "missing": &pb2.NestedWithRequired{},
1191 "contains": &pb2.NestedWithRequired{
1192 ReqString: scalar.String("here"),
1193 },
1194 },
1195 },
1196 }, {
1197 desc: "indirect required field in oneof",
1198 inputMessage: &pb2.IndirectRequired{},
1199 inputText: `{
1200 "oneofNested": {}
1201}`,
1202 wantMessage: &pb2.IndirectRequired{
1203 Union: &pb2.IndirectRequired_OneofNested{
1204 OneofNested: &pb2.NestedWithRequired{},
1205 },
1206 },
1207 wantErr: true,
1208 }, {
1209 desc: "indirect required field in oneof with AllowPartial",
1210 umo: jsonpb.UnmarshalOptions{AllowPartial: true},
1211 inputMessage: &pb2.IndirectRequired{},
1212 inputText: `{
1213 "oneofNested": {}
1214}`,
1215 wantMessage: &pb2.IndirectRequired{
1216 Union: &pb2.IndirectRequired_OneofNested{
1217 OneofNested: &pb2.NestedWithRequired{},
1218 },
1219 },
1220 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001221 desc: "extensions of non-repeated fields",
1222 inputMessage: &pb2.Extensions{},
1223 inputText: `{
1224 "optString": "non-extension field",
1225 "optBool": true,
1226 "optInt32": 42,
1227 "[pb2.opt_ext_bool]": true,
1228 "[pb2.opt_ext_nested]": {
1229 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001230 "optNested": {
1231 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001232 }
1233 },
1234 "[pb2.opt_ext_string]": "extension field",
1235 "[pb2.opt_ext_enum]": "TEN"
1236}`,
1237 wantMessage: func() proto.Message {
1238 m := &pb2.Extensions{
1239 OptString: scalar.String("non-extension field"),
1240 OptBool: scalar.Bool(true),
1241 OptInt32: scalar.Int32(42),
1242 }
1243 setExtension(m, pb2.E_OptExtBool, true)
1244 setExtension(m, pb2.E_OptExtString, "extension field")
1245 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1246 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1247 OptString: scalar.String("nested in an extension"),
1248 OptNested: &pb2.Nested{
1249 OptString: scalar.String("another nested in an extension"),
1250 },
1251 })
1252 return m
1253 }(),
1254 }, {
1255 desc: "extensions of repeated fields",
1256 inputMessage: &pb2.Extensions{},
1257 inputText: `{
1258 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1259 "[pb2.rpt_ext_fixed32]": [42, 47],
1260 "[pb2.rpt_ext_nested]": [
1261 {"optString": "one"},
1262 {"optString": "two"},
1263 {"optString": "three"}
1264 ]
1265}`,
1266 wantMessage: func() proto.Message {
1267 m := &pb2.Extensions{}
1268 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1269 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1270 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1271 &pb2.Nested{OptString: scalar.String("one")},
1272 &pb2.Nested{OptString: scalar.String("two")},
1273 &pb2.Nested{OptString: scalar.String("three")},
1274 })
1275 return m
1276 }(),
1277 }, {
1278 desc: "extensions of non-repeated fields in another message",
1279 inputMessage: &pb2.Extensions{},
1280 inputText: `{
1281 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1282 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1283 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1284 "optString": "nested in an extension",
1285 "optNested": {
1286 "optString": "another nested in an extension"
1287 }
1288 },
1289 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1290}`,
1291 wantMessage: func() proto.Message {
1292 m := &pb2.Extensions{}
1293 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1294 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1295 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1296 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1297 OptString: scalar.String("nested in an extension"),
1298 OptNested: &pb2.Nested{
1299 OptString: scalar.String("another nested in an extension"),
1300 },
1301 })
1302 return m
1303 }(),
1304 }, {
1305 desc: "extensions of repeated fields in another message",
1306 inputMessage: &pb2.Extensions{},
1307 inputText: `{
1308 "optString": "non-extension field",
1309 "optBool": true,
1310 "optInt32": 42,
1311 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1312 {"optString": "one"},
1313 {"optString": "two"},
1314 {"optString": "three"}
1315 ],
1316 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1317 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1318}`,
1319 wantMessage: func() proto.Message {
1320 m := &pb2.Extensions{
1321 OptString: scalar.String("non-extension field"),
1322 OptBool: scalar.Bool(true),
1323 OptInt32: scalar.Int32(42),
1324 }
1325 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1326 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1327 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1328 &pb2.Nested{OptString: scalar.String("one")},
1329 &pb2.Nested{OptString: scalar.String("two")},
1330 &pb2.Nested{OptString: scalar.String("three")},
1331 })
1332 return m
1333 }(),
1334 }, {
1335 desc: "invalid extension field name",
1336 inputMessage: &pb2.Extensions{},
1337 inputText: `{ "[pb2.invalid_message_field]": true }`,
1338 wantErr: true,
1339 }, {
1340 desc: "MessageSet",
1341 inputMessage: &pb2.MessageSet{},
1342 inputText: `{
1343 "[pb2.MessageSetExtension]": {
1344 "optString": "a messageset extension"
1345 },
1346 "[pb2.MessageSetExtension.ext_nested]": {
1347 "optString": "just a regular extension"
1348 },
1349 "[pb2.MessageSetExtension.not_message_set_extension]": {
1350 "optString": "not a messageset extension"
1351 }
1352}`,
1353 wantMessage: func() proto.Message {
1354 m := &pb2.MessageSet{}
1355 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1356 OptString: scalar.String("a messageset extension"),
1357 })
1358 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1359 OptString: scalar.String("not a messageset extension"),
1360 })
1361 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1362 OptString: scalar.String("just a regular extension"),
1363 })
1364 return m
1365 }(),
1366 }, {
1367 desc: "extension field set to null",
1368 inputMessage: &pb2.Extensions{},
1369 inputText: `{
1370 "[pb2.ExtensionsContainer.opt_ext_bool]": null,
1371 "[pb2.ExtensionsContainer.opt_ext_nested]": null
1372}`,
1373 wantMessage: func() proto.Message {
1374 m := &pb2.Extensions{}
1375 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, nil)
1376 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, nil)
1377 return m
1378 }(),
1379 }, {
1380 desc: "extensions of repeated field contains null",
1381 inputMessage: &pb2.Extensions{},
1382 inputText: `{
1383 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1384 {"optString": "one"},
1385 null,
1386 {"optString": "three"}
1387 ],
1388}`,
1389 wantErr: true,
1390 }, {
1391 desc: "not real MessageSet 1",
1392 inputMessage: &pb2.FakeMessageSet{},
1393 inputText: `{
1394 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1395 "optString": "not a messageset extension"
1396 }
1397}`,
1398 wantMessage: func() proto.Message {
1399 m := &pb2.FakeMessageSet{}
1400 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1401 OptString: scalar.String("not a messageset extension"),
1402 })
1403 return m
1404 }(),
1405 }, {
1406 desc: "not real MessageSet 2",
1407 inputMessage: &pb2.FakeMessageSet{},
1408 inputText: `{
1409 "[pb2.FakeMessageSetExtension]": {
1410 "optString": "not a messageset extension"
1411 }
1412}`,
1413 wantErr: true,
1414 }, {
1415 desc: "not real MessageSet 3",
1416 inputMessage: &pb2.MessageSet{},
1417 inputText: `{
1418 "[pb2.message_set_extension]": {
1419 "optString": "another not a messageset extension"
1420 }
1421}`,
1422 wantMessage: func() proto.Message {
1423 m := &pb2.MessageSet{}
1424 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1425 OptString: scalar.String("another not a messageset extension"),
1426 })
1427 return m
1428 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001429 }, {
1430 desc: "Empty",
1431 inputMessage: &knownpb.Empty{},
1432 inputText: `{}`,
1433 wantMessage: &knownpb.Empty{},
1434 }, {
1435 desc: "Empty contains unknown",
1436 inputMessage: &knownpb.Empty{},
1437 inputText: `{"unknown": null}`,
1438 wantErr: true,
1439 }, {
1440 desc: "BoolValue false",
1441 inputMessage: &knownpb.BoolValue{},
1442 inputText: `false`,
1443 wantMessage: &knownpb.BoolValue{},
1444 }, {
1445 desc: "BoolValue true",
1446 inputMessage: &knownpb.BoolValue{},
1447 inputText: `true`,
1448 wantMessage: &knownpb.BoolValue{Value: true},
1449 }, {
1450 desc: "BoolValue invalid value",
1451 inputMessage: &knownpb.BoolValue{},
1452 inputText: `{}`,
1453 wantErr: true,
1454 }, {
1455 desc: "Int32Value",
1456 inputMessage: &knownpb.Int32Value{},
1457 inputText: `42`,
1458 wantMessage: &knownpb.Int32Value{Value: 42},
1459 }, {
1460 desc: "Int32Value in JSON string",
1461 inputMessage: &knownpb.Int32Value{},
1462 inputText: `"1.23e3"`,
1463 wantMessage: &knownpb.Int32Value{Value: 1230},
1464 }, {
1465 desc: "Int64Value",
1466 inputMessage: &knownpb.Int64Value{},
1467 inputText: `"42"`,
1468 wantMessage: &knownpb.Int64Value{Value: 42},
1469 }, {
1470 desc: "UInt32Value",
1471 inputMessage: &knownpb.UInt32Value{},
1472 inputText: `42`,
1473 wantMessage: &knownpb.UInt32Value{Value: 42},
1474 }, {
1475 desc: "UInt64Value",
1476 inputMessage: &knownpb.UInt64Value{},
1477 inputText: `"42"`,
1478 wantMessage: &knownpb.UInt64Value{Value: 42},
1479 }, {
1480 desc: "FloatValue",
1481 inputMessage: &knownpb.FloatValue{},
1482 inputText: `1.02`,
1483 wantMessage: &knownpb.FloatValue{Value: 1.02},
1484 }, {
1485 desc: "FloatValue exceeds max limit",
1486 inputMessage: &knownpb.FloatValue{},
1487 inputText: `1.23+40`,
1488 wantErr: true,
1489 }, {
1490 desc: "FloatValue Infinity",
1491 inputMessage: &knownpb.FloatValue{},
1492 inputText: `"-Infinity"`,
1493 wantMessage: &knownpb.FloatValue{Value: float32(math.Inf(-1))},
1494 }, {
1495 desc: "DoubleValue",
1496 inputMessage: &knownpb.DoubleValue{},
1497 inputText: `1.02`,
1498 wantMessage: &knownpb.DoubleValue{Value: 1.02},
1499 }, {
1500 desc: "DoubleValue Infinity",
1501 inputMessage: &knownpb.DoubleValue{},
1502 inputText: `"Infinity"`,
1503 wantMessage: &knownpb.DoubleValue{Value: math.Inf(+1)},
1504 }, {
1505 desc: "StringValue empty",
1506 inputMessage: &knownpb.StringValue{},
1507 inputText: `""`,
1508 wantMessage: &knownpb.StringValue{},
1509 }, {
1510 desc: "StringValue",
1511 inputMessage: &knownpb.StringValue{},
1512 inputText: `"谷歌"`,
1513 wantMessage: &knownpb.StringValue{Value: "谷歌"},
1514 }, {
1515 desc: "StringValue with invalid UTF8 error",
1516 inputMessage: &knownpb.StringValue{},
1517 inputText: "\"abc\xff\"",
1518 wantMessage: &knownpb.StringValue{Value: "abc\xff"},
1519 wantErr: true,
1520 }, {
1521 desc: "StringValue field with invalid UTF8 error",
1522 inputMessage: &pb2.KnownTypes{},
1523 inputText: "{\n \"optString\": \"abc\xff\"\n}",
1524 wantMessage: &pb2.KnownTypes{
1525 OptString: &knownpb.StringValue{Value: "abc\xff"},
1526 },
1527 wantErr: true,
1528 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001529 desc: "NullValue field with JSON null",
1530 inputMessage: &pb2.KnownTypes{},
1531 inputText: `{
1532 "optNull": null
1533}`,
1534 wantMessage: &pb2.KnownTypes{OptNull: new(knownpb.NullValue)},
1535 }, {
1536 desc: "NullValue field with string",
1537 inputMessage: &pb2.KnownTypes{},
1538 inputText: `{
1539 "optNull": "NULL_VALUE"
1540}`,
1541 wantMessage: &pb2.KnownTypes{OptNull: new(knownpb.NullValue)},
1542 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001543 desc: "BytesValue",
1544 inputMessage: &knownpb.BytesValue{},
1545 inputText: `"aGVsbG8="`,
1546 wantMessage: &knownpb.BytesValue{Value: []byte("hello")},
1547 }, {
1548 desc: "Value null",
1549 inputMessage: &knownpb.Value{},
1550 inputText: `null`,
1551 wantMessage: &knownpb.Value{Kind: &knownpb.Value_NullValue{}},
1552 }, {
1553 desc: "Value field null",
1554 inputMessage: &pb2.KnownTypes{},
1555 inputText: `{
1556 "optValue": null
1557}`,
1558 wantMessage: &pb2.KnownTypes{
1559 OptValue: &knownpb.Value{Kind: &knownpb.Value_NullValue{}},
1560 },
1561 }, {
1562 desc: "Value bool",
1563 inputMessage: &knownpb.Value{},
1564 inputText: `false`,
1565 wantMessage: &knownpb.Value{Kind: &knownpb.Value_BoolValue{}},
1566 }, {
1567 desc: "Value field bool",
1568 inputMessage: &pb2.KnownTypes{},
1569 inputText: `{
1570 "optValue": true
1571}`,
1572 wantMessage: &pb2.KnownTypes{
1573 OptValue: &knownpb.Value{Kind: &knownpb.Value_BoolValue{true}},
1574 },
1575 }, {
1576 desc: "Value number",
1577 inputMessage: &knownpb.Value{},
1578 inputText: `1.02`,
1579 wantMessage: &knownpb.Value{Kind: &knownpb.Value_NumberValue{1.02}},
1580 }, {
1581 desc: "Value field number",
1582 inputMessage: &pb2.KnownTypes{},
1583 inputText: `{
1584 "optValue": 1.02
1585}`,
1586 wantMessage: &pb2.KnownTypes{
1587 OptValue: &knownpb.Value{Kind: &knownpb.Value_NumberValue{1.02}},
1588 },
1589 }, {
1590 desc: "Value string",
1591 inputMessage: &knownpb.Value{},
1592 inputText: `"hello"`,
1593 wantMessage: &knownpb.Value{Kind: &knownpb.Value_StringValue{"hello"}},
1594 }, {
1595 desc: "Value string with invalid UTF8",
1596 inputMessage: &knownpb.Value{},
1597 inputText: "\"\xff\"",
1598 wantMessage: &knownpb.Value{Kind: &knownpb.Value_StringValue{"\xff"}},
1599 wantErr: true,
1600 }, {
1601 desc: "Value field string",
1602 inputMessage: &pb2.KnownTypes{},
1603 inputText: `{
1604 "optValue": "NaN"
1605}`,
1606 wantMessage: &pb2.KnownTypes{
1607 OptValue: &knownpb.Value{Kind: &knownpb.Value_StringValue{"NaN"}},
1608 },
1609 }, {
1610 desc: "Value field string with invalid UTF8",
1611 inputMessage: &pb2.KnownTypes{},
1612 inputText: `{
1613 "optValue": "` + "\xff" + `"
1614}`,
1615 wantMessage: &pb2.KnownTypes{
1616 OptValue: &knownpb.Value{Kind: &knownpb.Value_StringValue{"\xff"}},
1617 },
1618 wantErr: true,
1619 }, {
1620 desc: "Value empty struct",
1621 inputMessage: &knownpb.Value{},
1622 inputText: `{}`,
1623 wantMessage: &knownpb.Value{
1624 Kind: &knownpb.Value_StructValue{
1625 &knownpb.Struct{Fields: map[string]*knownpb.Value{}},
1626 },
1627 },
1628 }, {
1629 desc: "Value struct",
1630 inputMessage: &knownpb.Value{},
1631 inputText: `{
1632 "string": "hello",
1633 "number": 123,
1634 "null": null,
1635 "bool": false,
1636 "struct": {
1637 "string": "world"
1638 },
1639 "list": []
1640}`,
1641 wantMessage: &knownpb.Value{
1642 Kind: &knownpb.Value_StructValue{
1643 &knownpb.Struct{
1644 Fields: map[string]*knownpb.Value{
1645 "string": {Kind: &knownpb.Value_StringValue{"hello"}},
1646 "number": {Kind: &knownpb.Value_NumberValue{123}},
1647 "null": {Kind: &knownpb.Value_NullValue{}},
1648 "bool": {Kind: &knownpb.Value_BoolValue{false}},
1649 "struct": {
1650 Kind: &knownpb.Value_StructValue{
1651 &knownpb.Struct{
1652 Fields: map[string]*knownpb.Value{
1653 "string": {Kind: &knownpb.Value_StringValue{"world"}},
1654 },
1655 },
1656 },
1657 },
1658 "list": {
1659 Kind: &knownpb.Value_ListValue{&knownpb.ListValue{}},
1660 },
1661 },
1662 },
1663 },
1664 },
1665 }, {
1666 desc: "Value struct with invalid UTF8 string",
1667 inputMessage: &knownpb.Value{},
1668 inputText: "{\"string\": \"abc\xff\"}",
1669 wantMessage: &knownpb.Value{
1670 Kind: &knownpb.Value_StructValue{
1671 &knownpb.Struct{
1672 Fields: map[string]*knownpb.Value{
1673 "string": {Kind: &knownpb.Value_StringValue{"abc\xff"}},
1674 },
1675 },
1676 },
1677 },
1678 wantErr: true,
1679 }, {
1680 desc: "Value field struct",
1681 inputMessage: &pb2.KnownTypes{},
1682 inputText: `{
1683 "optValue": {
1684 "string": "hello"
1685 }
1686}`,
1687 wantMessage: &pb2.KnownTypes{
1688 OptValue: &knownpb.Value{
1689 Kind: &knownpb.Value_StructValue{
1690 &knownpb.Struct{
1691 Fields: map[string]*knownpb.Value{
1692 "string": {Kind: &knownpb.Value_StringValue{"hello"}},
1693 },
1694 },
1695 },
1696 },
1697 },
1698 }, {
1699 desc: "Value empty list",
1700 inputMessage: &knownpb.Value{},
1701 inputText: `[]`,
1702 wantMessage: &knownpb.Value{
1703 Kind: &knownpb.Value_ListValue{
1704 &knownpb.ListValue{Values: []*knownpb.Value{}},
1705 },
1706 },
1707 }, {
1708 desc: "Value list",
1709 inputMessage: &knownpb.Value{},
1710 inputText: `[
1711 "string",
1712 123,
1713 null,
1714 true,
1715 {},
1716 [
1717 "string",
1718 1.23,
1719 null,
1720 false
1721 ]
1722]`,
1723 wantMessage: &knownpb.Value{
1724 Kind: &knownpb.Value_ListValue{
1725 &knownpb.ListValue{
1726 Values: []*knownpb.Value{
1727 {Kind: &knownpb.Value_StringValue{"string"}},
1728 {Kind: &knownpb.Value_NumberValue{123}},
1729 {Kind: &knownpb.Value_NullValue{}},
1730 {Kind: &knownpb.Value_BoolValue{true}},
1731 {Kind: &knownpb.Value_StructValue{&knownpb.Struct{}}},
1732 {
1733 Kind: &knownpb.Value_ListValue{
1734 &knownpb.ListValue{
1735 Values: []*knownpb.Value{
1736 {Kind: &knownpb.Value_StringValue{"string"}},
1737 {Kind: &knownpb.Value_NumberValue{1.23}},
1738 {Kind: &knownpb.Value_NullValue{}},
1739 {Kind: &knownpb.Value_BoolValue{false}},
1740 },
1741 },
1742 },
1743 },
1744 },
1745 },
1746 },
1747 },
1748 }, {
1749 desc: "Value list with invalid UTF8 string",
1750 inputMessage: &knownpb.Value{},
1751 inputText: "[\"abc\xff\"]",
1752 wantMessage: &knownpb.Value{
1753 Kind: &knownpb.Value_ListValue{
1754 &knownpb.ListValue{
1755 Values: []*knownpb.Value{
1756 {Kind: &knownpb.Value_StringValue{"abc\xff"}},
1757 },
1758 },
1759 },
1760 },
1761 wantErr: true,
1762 }, {
1763 desc: "Value field list with invalid UTF8 string",
1764 inputMessage: &pb2.KnownTypes{},
1765 inputText: `{
1766 "optValue": [ "` + "abc\xff" + `"]
1767}`,
1768 wantMessage: &pb2.KnownTypes{
1769 OptValue: &knownpb.Value{
1770 Kind: &knownpb.Value_ListValue{
1771 &knownpb.ListValue{
1772 Values: []*knownpb.Value{
1773 {Kind: &knownpb.Value_StringValue{"abc\xff"}},
1774 },
1775 },
1776 },
1777 },
1778 },
1779 wantErr: true,
1780 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001781 desc: "Duration empty string",
1782 inputMessage: &knownpb.Duration{},
1783 inputText: `""`,
1784 wantErr: true,
1785 }, {
1786 desc: "Duration with secs",
1787 inputMessage: &knownpb.Duration{},
1788 inputText: `"3s"`,
1789 wantMessage: &knownpb.Duration{Seconds: 3},
1790 }, {
1791 desc: "Duration with escaped unicode",
1792 inputMessage: &knownpb.Duration{},
1793 inputText: `"\u0033s"`,
1794 wantMessage: &knownpb.Duration{Seconds: 3},
1795 }, {
1796 desc: "Duration with -secs",
1797 inputMessage: &knownpb.Duration{},
1798 inputText: `"-3s"`,
1799 wantMessage: &knownpb.Duration{Seconds: -3},
1800 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001801 desc: "Duration with plus sign",
1802 inputMessage: &knownpb.Duration{},
1803 inputText: `"+3s"`,
1804 wantMessage: &knownpb.Duration{Seconds: 3},
1805 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001806 desc: "Duration with nanos",
1807 inputMessage: &knownpb.Duration{},
1808 inputText: `"0.001s"`,
1809 wantMessage: &knownpb.Duration{Nanos: 1e6},
1810 }, {
1811 desc: "Duration with -nanos",
1812 inputMessage: &knownpb.Duration{},
1813 inputText: `"-0.001s"`,
1814 wantMessage: &knownpb.Duration{Nanos: -1e6},
1815 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001816 desc: "Duration with -nanos",
1817 inputMessage: &knownpb.Duration{},
1818 inputText: `"-.001s"`,
1819 wantMessage: &knownpb.Duration{Nanos: -1e6},
1820 }, {
1821 desc: "Duration with +nanos",
1822 inputMessage: &knownpb.Duration{},
1823 inputText: `"+.001s"`,
1824 wantMessage: &knownpb.Duration{Nanos: 1e6},
1825 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001826 desc: "Duration with -secs -nanos",
1827 inputMessage: &knownpb.Duration{},
1828 inputText: `"-123.000000450s"`,
1829 wantMessage: &knownpb.Duration{Seconds: -123, Nanos: -450},
1830 }, {
1831 desc: "Duration with large secs",
1832 inputMessage: &knownpb.Duration{},
1833 inputText: `"10000000000.000000001s"`,
1834 wantMessage: &knownpb.Duration{Seconds: 1e10, Nanos: 1},
1835 }, {
1836 desc: "Duration with decimal without fractional",
1837 inputMessage: &knownpb.Duration{},
1838 inputText: `"3.s"`,
1839 wantMessage: &knownpb.Duration{Seconds: 3},
1840 }, {
1841 desc: "Duration with decimal without integer",
1842 inputMessage: &knownpb.Duration{},
1843 inputText: `"0.5s"`,
1844 wantMessage: &knownpb.Duration{Nanos: 5e8},
1845 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001846 desc: "Duration max value",
1847 inputMessage: &knownpb.Duration{},
1848 inputText: `"315576000000.999999999s"`,
1849 wantMessage: &knownpb.Duration{Seconds: 315576000000, Nanos: 999999999},
1850 }, {
1851 desc: "Duration min value",
1852 inputMessage: &knownpb.Duration{},
1853 inputText: `"-315576000000.999999999s"`,
1854 wantMessage: &knownpb.Duration{Seconds: -315576000000, Nanos: -999999999},
1855 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001856 desc: "Duration with +secs out of range",
1857 inputMessage: &knownpb.Duration{},
1858 inputText: `"315576000001s"`,
1859 wantErr: true,
1860 }, {
1861 desc: "Duration with -secs out of range",
1862 inputMessage: &knownpb.Duration{},
1863 inputText: `"-315576000001s"`,
1864 wantErr: true,
1865 }, {
1866 desc: "Duration with nanos beyond 9 digits",
1867 inputMessage: &knownpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001868 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001869 wantErr: true,
1870 }, {
1871 desc: "Duration without suffix s",
1872 inputMessage: &knownpb.Duration{},
1873 inputText: `"123"`,
1874 wantErr: true,
1875 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001876 desc: "Duration invalid signed fraction",
1877 inputMessage: &knownpb.Duration{},
1878 inputText: `"123.+123s"`,
1879 wantErr: true,
1880 }, {
1881 desc: "Duration invalid multiple .",
1882 inputMessage: &knownpb.Duration{},
1883 inputText: `"123.123.s"`,
1884 wantErr: true,
1885 }, {
1886 desc: "Duration invalid integer",
1887 inputMessage: &knownpb.Duration{},
1888 inputText: `"01s"`,
1889 wantErr: true,
1890 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001891 desc: "Timestamp zero",
1892 inputMessage: &knownpb.Timestamp{},
1893 inputText: `"1970-01-01T00:00:00Z"`,
1894 wantMessage: &knownpb.Timestamp{},
1895 }, {
1896 desc: "Timestamp with tz adjustment",
1897 inputMessage: &knownpb.Timestamp{},
1898 inputText: `"1970-01-01T00:00:00+01:00"`,
1899 wantMessage: &knownpb.Timestamp{Seconds: -3600},
1900 }, {
1901 desc: "Timestamp UTC",
1902 inputMessage: &knownpb.Timestamp{},
1903 inputText: `"2019-03-19T23:03:21Z"`,
1904 wantMessage: &knownpb.Timestamp{Seconds: 1553036601},
1905 }, {
1906 desc: "Timestamp with escaped unicode",
1907 inputMessage: &knownpb.Timestamp{},
1908 inputText: `"2019-0\u0033-19T23:03:21Z"`,
1909 wantMessage: &knownpb.Timestamp{Seconds: 1553036601},
1910 }, {
1911 desc: "Timestamp with nanos",
1912 inputMessage: &knownpb.Timestamp{},
1913 inputText: `"2019-03-19T23:03:21.000000001Z"`,
1914 wantMessage: &knownpb.Timestamp{Seconds: 1553036601, Nanos: 1},
1915 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001916 desc: "Timestamp max value",
Herbie Ongc4450372019-03-27 09:59:51 -07001917 inputMessage: &knownpb.Timestamp{},
1918 inputText: `"9999-12-31T23:59:59.999999999Z"`,
1919 wantMessage: &knownpb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
1920 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001921 desc: "Timestamp above max value",
Herbie Ongc4450372019-03-27 09:59:51 -07001922 inputMessage: &knownpb.Timestamp{},
1923 inputText: `"9999-12-31T23:59:59-01:00"`,
1924 wantErr: true,
1925 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001926 desc: "Timestamp min value",
Herbie Ongc4450372019-03-27 09:59:51 -07001927 inputMessage: &knownpb.Timestamp{},
1928 inputText: `"0001-01-01T00:00:00Z"`,
1929 wantMessage: &knownpb.Timestamp{Seconds: -62135596800},
1930 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001931 desc: "Timestamp below min value",
Herbie Ongc4450372019-03-27 09:59:51 -07001932 inputMessage: &knownpb.Timestamp{},
1933 inputText: `"0001-01-01T00:00:00+01:00"`,
1934 wantErr: true,
1935 }, {
1936 desc: "Timestamp with nanos beyond 9 digits",
1937 inputMessage: &knownpb.Timestamp{},
1938 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1939 wantErr: true,
1940 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001941 desc: "FieldMask empty",
1942 inputMessage: &knownpb.FieldMask{},
1943 inputText: `""`,
1944 wantMessage: &knownpb.FieldMask{Paths: []string{}},
1945 }, {
1946 desc: "FieldMask",
1947 inputMessage: &knownpb.FieldMask{},
1948 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
1949 wantMessage: &knownpb.FieldMask{
1950 Paths: []string{
1951 "foo",
1952 "foo_bar",
1953 "foo.bar_qux",
1954 "_foo",
1955 },
1956 },
1957 }, {
1958 desc: "FieldMask field",
1959 inputMessage: &pb2.KnownTypes{},
1960 inputText: `{
1961 "optFieldmask": "foo, qux.fooBar"
1962}`,
1963 wantMessage: &pb2.KnownTypes{
1964 OptFieldmask: &knownpb.FieldMask{
1965 Paths: []string{
1966 "foo",
1967 "qux.foo_bar",
1968 },
1969 },
1970 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001971 }, {
1972 desc: "Any empty",
1973 inputMessage: &knownpb.Any{},
1974 inputText: `{}`,
1975 wantMessage: &knownpb.Any{},
1976 }, {
1977 desc: "Any with non-custom message",
1978 umo: jsonpb.UnmarshalOptions{
1979 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1980 },
1981 inputMessage: &knownpb.Any{},
1982 inputText: `{
1983 "@type": "foo/pb2.Nested",
1984 "optString": "embedded inside Any",
1985 "optNested": {
1986 "optString": "inception"
1987 }
1988}`,
1989 wantMessage: func() proto.Message {
1990 m := &pb2.Nested{
1991 OptString: scalar.String("embedded inside Any"),
1992 OptNested: &pb2.Nested{
1993 OptString: scalar.String("inception"),
1994 },
1995 }
1996 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1997 if err != nil {
1998 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1999 }
2000 return &knownpb.Any{
2001 TypeUrl: "foo/pb2.Nested",
2002 Value: b,
2003 }
2004 }(),
2005 }, {
2006 desc: "Any with empty embedded message",
2007 umo: jsonpb.UnmarshalOptions{
2008 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
2009 },
2010 inputMessage: &knownpb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002011 inputText: `{"@type": "foo/pb2.Nested"}`,
2012 wantMessage: &knownpb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002013 }, {
2014 desc: "Any without registered type",
2015 umo: jsonpb.UnmarshalOptions{Resolver: preg.NewTypes()},
2016 inputMessage: &knownpb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002017 inputText: `{"@type": "foo/pb2.Nested"}`,
2018 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002019 }, {
2020 desc: "Any with missing required error",
2021 umo: jsonpb.UnmarshalOptions{
2022 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
2023 },
2024 inputMessage: &knownpb.Any{},
2025 inputText: `{
2026 "@type": "pb2.PartialRequired",
2027 "optString": "embedded inside Any"
2028}`,
2029 wantMessage: func() proto.Message {
2030 m := &pb2.PartialRequired{
2031 OptString: scalar.String("embedded inside Any"),
2032 }
Damien Neil96c229a2019-04-03 12:17:24 -07002033 b, err := proto.MarshalOptions{
2034 Deterministic: true,
2035 AllowPartial: true,
2036 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002037 if err != nil {
2038 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2039 }
2040 return &knownpb.Any{
2041 TypeUrl: string(m.ProtoReflect().Type().FullName()),
2042 Value: b,
2043 }
2044 }(),
2045 wantErr: true,
2046 }, {
2047 desc: "Any with partial required and AllowPartial",
2048 umo: jsonpb.UnmarshalOptions{
2049 AllowPartial: true,
2050 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
2051 },
2052 inputMessage: &knownpb.Any{},
2053 inputText: `{
2054 "@type": "pb2.PartialRequired",
2055 "optString": "embedded inside Any"
2056}`,
2057 wantMessage: func() proto.Message {
2058 m := &pb2.PartialRequired{
2059 OptString: scalar.String("embedded inside Any"),
2060 }
Damien Neil96c229a2019-04-03 12:17:24 -07002061 b, err := proto.MarshalOptions{
2062 Deterministic: true,
2063 AllowPartial: true,
2064 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002065 if err != nil {
2066 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2067 }
2068 return &knownpb.Any{
2069 TypeUrl: string(m.ProtoReflect().Type().FullName()),
2070 Value: b,
2071 }
2072 }(),
2073 }, {
2074 desc: "Any with invalid UTF8",
2075 umo: jsonpb.UnmarshalOptions{
2076 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
2077 },
2078 inputMessage: &knownpb.Any{},
2079 inputText: `{
2080 "optString": "` + "abc\xff" + `",
2081 "@type": "foo/pb2.Nested"
2082}`,
2083 wantMessage: func() proto.Message {
2084 m := &pb2.Nested{
2085 OptString: scalar.String("abc\xff"),
2086 }
2087 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2088 if err != nil {
2089 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2090 }
2091 return &knownpb.Any{
2092 TypeUrl: "foo/pb2.Nested",
2093 Value: b,
2094 }
2095 }(),
2096 wantErr: true,
2097 }, {
2098 desc: "Any with BoolValue",
2099 umo: jsonpb.UnmarshalOptions{
2100 Resolver: preg.NewTypes((&knownpb.BoolValue{}).ProtoReflect().Type()),
2101 },
2102 inputMessage: &knownpb.Any{},
2103 inputText: `{
2104 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2105 "value": true
2106}`,
2107 wantMessage: func() proto.Message {
2108 m := &knownpb.BoolValue{Value: true}
2109 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2110 if err != nil {
2111 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2112 }
2113 return &knownpb.Any{
2114 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2115 Value: b,
2116 }
2117 }(),
2118 }, {
2119 desc: "Any with Empty",
2120 umo: jsonpb.UnmarshalOptions{
2121 Resolver: preg.NewTypes((&knownpb.Empty{}).ProtoReflect().Type()),
2122 },
2123 inputMessage: &knownpb.Any{},
2124 inputText: `{
2125 "value": {},
2126 "@type": "type.googleapis.com/google.protobuf.Empty"
2127}`,
Herbie Ong4f0be712019-04-25 17:57:12 -07002128 wantMessage: &knownpb.Any{
2129 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2130 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002131 }, {
2132 desc: "Any with missing Empty",
2133 umo: jsonpb.UnmarshalOptions{
2134 Resolver: preg.NewTypes((&knownpb.Empty{}).ProtoReflect().Type()),
2135 },
2136 inputMessage: &knownpb.Any{},
2137 inputText: `{
2138 "@type": "type.googleapis.com/google.protobuf.Empty"
2139}`,
2140 wantErr: true,
2141 }, {
2142 desc: "Any with StringValue containing invalid UTF8",
2143 umo: jsonpb.UnmarshalOptions{
2144 Resolver: preg.NewTypes((&knownpb.StringValue{}).ProtoReflect().Type()),
2145 },
2146 inputMessage: &knownpb.Any{},
2147 inputText: `{
2148 "@type": "google.protobuf.StringValue",
2149 "value": "` + "abc\xff" + `"
2150}`,
2151 wantMessage: func() proto.Message {
Damien Neilbc310b52019-04-11 11:46:55 -07002152 m := &knownpb.StringValue{Value: "abcd"}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002153 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2154 if err != nil {
2155 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2156 }
2157 return &knownpb.Any{
2158 TypeUrl: "google.protobuf.StringValue",
Damien Neilbc310b52019-04-11 11:46:55 -07002159 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002160 }
2161 }(),
2162 wantErr: true,
2163 }, {
2164 desc: "Any with Int64Value",
2165 umo: jsonpb.UnmarshalOptions{
2166 Resolver: preg.NewTypes((&knownpb.Int64Value{}).ProtoReflect().Type()),
2167 },
2168 inputMessage: &knownpb.Any{},
2169 inputText: `{
2170 "@type": "google.protobuf.Int64Value",
2171 "value": "42"
2172}`,
2173 wantMessage: func() proto.Message {
2174 m := &knownpb.Int64Value{Value: 42}
2175 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2176 if err != nil {
2177 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2178 }
2179 return &knownpb.Any{
2180 TypeUrl: "google.protobuf.Int64Value",
2181 Value: b,
2182 }
2183 }(),
2184 }, {
2185 desc: "Any with invalid Int64Value",
2186 umo: jsonpb.UnmarshalOptions{
2187 Resolver: preg.NewTypes((&knownpb.Int64Value{}).ProtoReflect().Type()),
2188 },
2189 inputMessage: &knownpb.Any{},
2190 inputText: `{
2191 "@type": "google.protobuf.Int64Value",
2192 "value": "forty-two"
2193}`,
2194 wantErr: true,
2195 }, {
2196 desc: "Any with invalid UInt64Value",
2197 umo: jsonpb.UnmarshalOptions{
2198 Resolver: preg.NewTypes((&knownpb.UInt64Value{}).ProtoReflect().Type()),
2199 },
2200 inputMessage: &knownpb.Any{},
2201 inputText: `{
2202 "@type": "google.protobuf.UInt64Value",
2203 "value": -42
2204}`,
2205 wantErr: true,
2206 }, {
2207 desc: "Any with Duration",
2208 umo: jsonpb.UnmarshalOptions{
2209 Resolver: preg.NewTypes((&knownpb.Duration{}).ProtoReflect().Type()),
2210 },
2211 inputMessage: &knownpb.Any{},
2212 inputText: `{
2213 "@type": "type.googleapis.com/google.protobuf.Duration",
2214 "value": "0s"
2215}`,
2216 wantMessage: func() proto.Message {
2217 m := &knownpb.Duration{}
2218 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2219 if err != nil {
2220 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2221 }
2222 return &knownpb.Any{
2223 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2224 Value: b,
2225 }
2226 }(),
2227 }, {
2228 desc: "Any with Value of StringValue",
2229 umo: jsonpb.UnmarshalOptions{
2230 Resolver: preg.NewTypes((&knownpb.Value{}).ProtoReflect().Type()),
2231 },
2232 inputMessage: &knownpb.Any{},
2233 inputText: `{
2234 "@type": "google.protobuf.Value",
2235 "value": "` + "abc\xff" + `"
2236}`,
2237 wantMessage: func() proto.Message {
Damien Neilbc310b52019-04-11 11:46:55 -07002238 m := &knownpb.Value{Kind: &knownpb.Value_StringValue{"abcd"}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002239 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2240 if err != nil {
2241 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2242 }
2243 return &knownpb.Any{
2244 TypeUrl: "google.protobuf.Value",
Damien Neilbc310b52019-04-11 11:46:55 -07002245 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002246 }
2247 }(),
2248 wantErr: true,
2249 }, {
2250 desc: "Any with Value of NullValue",
2251 umo: jsonpb.UnmarshalOptions{
2252 Resolver: preg.NewTypes((&knownpb.Value{}).ProtoReflect().Type()),
2253 },
2254 inputMessage: &knownpb.Any{},
2255 inputText: `{
2256 "@type": "google.protobuf.Value",
2257 "value": null
2258}`,
2259 wantMessage: func() proto.Message {
2260 m := &knownpb.Value{Kind: &knownpb.Value_NullValue{}}
2261 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2262 if err != nil {
2263 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2264 }
2265 return &knownpb.Any{
2266 TypeUrl: "google.protobuf.Value",
2267 Value: b,
2268 }
2269 }(),
2270 }, {
2271 desc: "Any with Struct",
2272 umo: jsonpb.UnmarshalOptions{
2273 Resolver: preg.NewTypes(
2274 (&knownpb.Struct{}).ProtoReflect().Type(),
2275 (&knownpb.Value{}).ProtoReflect().Type(),
2276 (&knownpb.BoolValue{}).ProtoReflect().Type(),
2277 knownpb.NullValue_NULL_VALUE.Type(),
2278 (&knownpb.StringValue{}).ProtoReflect().Type(),
2279 ),
2280 },
2281 inputMessage: &knownpb.Any{},
2282 inputText: `{
2283 "@type": "google.protobuf.Struct",
2284 "value": {
2285 "bool": true,
2286 "null": null,
2287 "string": "hello",
2288 "struct": {
2289 "string": "world"
2290 }
2291 }
2292}`,
2293 wantMessage: func() proto.Message {
2294 m := &knownpb.Struct{
2295 Fields: map[string]*knownpb.Value{
2296 "bool": {Kind: &knownpb.Value_BoolValue{true}},
2297 "null": {Kind: &knownpb.Value_NullValue{}},
2298 "string": {Kind: &knownpb.Value_StringValue{"hello"}},
2299 "struct": {
2300 Kind: &knownpb.Value_StructValue{
2301 &knownpb.Struct{
2302 Fields: map[string]*knownpb.Value{
2303 "string": {Kind: &knownpb.Value_StringValue{"world"}},
2304 },
2305 },
2306 },
2307 },
2308 },
2309 }
2310 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2311 if err != nil {
2312 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2313 }
2314 return &knownpb.Any{
2315 TypeUrl: "google.protobuf.Struct",
2316 Value: b,
2317 }
2318 }(),
2319 }, {
2320 desc: "Any with missing @type",
2321 umo: jsonpb.UnmarshalOptions{},
2322 inputMessage: &knownpb.Any{},
2323 inputText: `{
2324 "value": {}
2325}`,
2326 wantErr: true,
2327 }, {
2328 desc: "Any with empty @type",
2329 inputMessage: &knownpb.Any{},
2330 inputText: `{
2331 "@type": ""
2332}`,
2333 wantErr: true,
2334 }, {
2335 desc: "Any with duplicate @type",
2336 umo: jsonpb.UnmarshalOptions{
2337 Resolver: preg.NewTypes(
2338 (&pb2.Nested{}).ProtoReflect().Type(),
2339 (&knownpb.StringValue{}).ProtoReflect().Type(),
2340 ),
2341 },
2342 inputMessage: &knownpb.Any{},
2343 inputText: `{
2344 "@type": "google.protobuf.StringValue",
2345 "value": "hello",
2346 "@type": "pb2.Nested"
2347}`,
2348 wantErr: true,
2349 }, {
2350 desc: "Any with duplicate value",
2351 umo: jsonpb.UnmarshalOptions{
2352 Resolver: preg.NewTypes((&knownpb.StringValue{}).ProtoReflect().Type()),
2353 },
2354 inputMessage: &knownpb.Any{},
2355 inputText: `{
2356 "@type": "google.protobuf.StringValue",
2357 "value": "hello",
2358 "value": "world"
2359}`,
2360 wantErr: true,
2361 }, {
2362 desc: "Any with unknown field",
2363 umo: jsonpb.UnmarshalOptions{
2364 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
2365 },
2366 inputMessage: &knownpb.Any{},
2367 inputText: `{
2368 "@type": "pb2.Nested",
2369 "optString": "hello",
2370 "unknown": "world"
2371}`,
2372 wantErr: true,
2373 }, {
2374 desc: "Any with embedded type containing Any",
2375 umo: jsonpb.UnmarshalOptions{
2376 Resolver: preg.NewTypes(
2377 (&pb2.KnownTypes{}).ProtoReflect().Type(),
2378 (&knownpb.Any{}).ProtoReflect().Type(),
2379 (&knownpb.StringValue{}).ProtoReflect().Type(),
2380 ),
2381 },
2382 inputMessage: &knownpb.Any{},
2383 inputText: `{
2384 "@type": "pb2.KnownTypes",
2385 "optAny": {
2386 "@type": "google.protobuf.StringValue",
2387 "value": "` + "abc\xff" + `"
2388 }
2389}`,
2390 wantMessage: func() proto.Message {
Damien Neilbc310b52019-04-11 11:46:55 -07002391 m1 := &knownpb.StringValue{Value: "abcd"}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002392 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
2393 if err != nil {
2394 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2395 }
2396 m2 := &knownpb.Any{
2397 TypeUrl: "google.protobuf.StringValue",
2398 Value: b,
2399 }
2400 m3 := &pb2.KnownTypes{OptAny: m2}
2401 b, err = proto.MarshalOptions{Deterministic: true}.Marshal(m3)
2402 if err != nil {
2403 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2404 }
2405 return &knownpb.Any{
2406 TypeUrl: "pb2.KnownTypes",
Damien Neilbc310b52019-04-11 11:46:55 -07002407 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002408 }
2409 }(),
2410 wantErr: true,
2411 }, {
2412 desc: "well known types as field values",
2413 umo: jsonpb.UnmarshalOptions{
2414 Resolver: preg.NewTypes((&knownpb.Empty{}).ProtoReflect().Type()),
2415 },
2416 inputMessage: &pb2.KnownTypes{},
2417 inputText: `{
2418 "optBool": false,
2419 "optInt32": 42,
2420 "optInt64": "42",
2421 "optUint32": 42,
2422 "optUint64": "42",
2423 "optFloat": 1.23,
2424 "optDouble": 3.1415,
2425 "optString": "hello",
2426 "optBytes": "aGVsbG8=",
2427 "optDuration": "123s",
2428 "optTimestamp": "2019-03-19T23:03:21Z",
2429 "optStruct": {
2430 "string": "hello"
2431 },
2432 "optList": [
2433 null,
2434 "",
2435 {},
2436 []
2437 ],
2438 "optValue": "world",
2439 "optEmpty": {},
2440 "optAny": {
2441 "@type": "google.protobuf.Empty",
2442 "value": {}
2443 },
2444 "optFieldmask": "fooBar,barFoo"
2445}`,
2446 wantMessage: &pb2.KnownTypes{
2447 OptBool: &knownpb.BoolValue{Value: false},
2448 OptInt32: &knownpb.Int32Value{Value: 42},
2449 OptInt64: &knownpb.Int64Value{Value: 42},
2450 OptUint32: &knownpb.UInt32Value{Value: 42},
2451 OptUint64: &knownpb.UInt64Value{Value: 42},
2452 OptFloat: &knownpb.FloatValue{Value: 1.23},
2453 OptDouble: &knownpb.DoubleValue{Value: 3.1415},
2454 OptString: &knownpb.StringValue{Value: "hello"},
2455 OptBytes: &knownpb.BytesValue{Value: []byte("hello")},
2456 OptDuration: &knownpb.Duration{Seconds: 123},
2457 OptTimestamp: &knownpb.Timestamp{Seconds: 1553036601},
2458 OptStruct: &knownpb.Struct{
2459 Fields: map[string]*knownpb.Value{
2460 "string": {Kind: &knownpb.Value_StringValue{"hello"}},
2461 },
2462 },
2463 OptList: &knownpb.ListValue{
2464 Values: []*knownpb.Value{
2465 {Kind: &knownpb.Value_NullValue{}},
2466 {Kind: &knownpb.Value_StringValue{}},
2467 {
2468 Kind: &knownpb.Value_StructValue{
2469 &knownpb.Struct{Fields: map[string]*knownpb.Value{}},
2470 },
2471 },
2472 {
2473 Kind: &knownpb.Value_ListValue{
2474 &knownpb.ListValue{Values: []*knownpb.Value{}},
2475 },
2476 },
2477 },
2478 },
2479 OptValue: &knownpb.Value{
2480 Kind: &knownpb.Value_StringValue{"world"},
2481 },
2482 OptEmpty: &knownpb.Empty{},
2483 OptAny: &knownpb.Any{
2484 TypeUrl: "google.protobuf.Empty",
2485 },
2486 OptFieldmask: &knownpb.FieldMask{
2487 Paths: []string{"foo_bar", "bar_foo"},
2488 },
2489 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002490 }, {
2491 desc: "DiscardUnknown: regular messages",
2492 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2493 inputMessage: &pb3.Nests{},
2494 inputText: `{
2495 "sNested": {
2496 "unknown": {
2497 "foo": 1,
2498 "bar": [1, 2, 3]
2499 }
2500 },
2501 "unknown": "not known"
2502}`,
2503 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2504 }, {
2505 desc: "DiscardUnknown: repeated",
2506 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2507 inputMessage: &pb2.Nests{},
2508 inputText: `{
2509 "rptNested": [
2510 {"unknown": "blah"},
2511 {"optString": "hello"}
2512 ]
2513}`,
2514 wantMessage: &pb2.Nests{
2515 RptNested: []*pb2.Nested{
2516 {},
2517 {OptString: scalar.String("hello")},
2518 },
2519 },
2520 }, {
2521 desc: "DiscardUnknown: map",
2522 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2523 inputMessage: &pb3.Maps{},
2524 inputText: `{
2525 "strToNested": {
2526 "nested_one": {
2527 "unknown": "what you see is not"
2528 }
2529 }
2530}`,
2531 wantMessage: &pb3.Maps{
2532 StrToNested: map[string]*pb3.Nested{
2533 "nested_one": {},
2534 },
2535 },
2536 }, {
2537 desc: "DiscardUnknown: extension",
2538 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2539 inputMessage: &pb2.Extensions{},
2540 inputText: `{
2541 "[pb2.opt_ext_nested]": {
2542 "unknown": []
2543 }
2544}`,
2545 wantMessage: func() proto.Message {
2546 m := &pb2.Extensions{}
2547 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2548 return m
2549 }(),
2550 }, {
2551 desc: "DiscardUnknown: Empty",
2552 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2553 inputMessage: &knownpb.Empty{},
2554 inputText: `{"unknown": "something"}`,
2555 wantMessage: &knownpb.Empty{},
2556 }, {
2557 desc: "DiscardUnknown: Any without type",
2558 umo: jsonpb.UnmarshalOptions{DiscardUnknown: true},
2559 inputMessage: &knownpb.Any{},
2560 inputText: `{
2561 "value": {"foo": "bar"},
2562 "unknown": true
2563}`,
2564 wantMessage: &knownpb.Any{},
2565 }, {
2566 desc: "DiscardUnknown: Any",
2567 umo: jsonpb.UnmarshalOptions{
2568 DiscardUnknown: true,
2569 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
2570 },
2571 inputMessage: &knownpb.Any{},
2572 inputText: `{
2573 "@type": "foo/pb2.Nested",
2574 "unknown": "none"
2575}`,
2576 wantMessage: &knownpb.Any{
2577 TypeUrl: "foo/pb2.Nested",
2578 },
2579 }, {
2580 desc: "DiscardUnknown: Any with Empty",
2581 umo: jsonpb.UnmarshalOptions{
2582 DiscardUnknown: true,
2583 Resolver: preg.NewTypes((&knownpb.Empty{}).ProtoReflect().Type()),
2584 },
2585 inputMessage: &knownpb.Any{},
2586 inputText: `{
2587 "@type": "type.googleapis.com/google.protobuf.Empty",
2588 "value": {"unknown": 47}
2589}`,
2590 wantMessage: &knownpb.Any{
2591 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2592 },
Herbie Ongc96a79d2019-03-08 10:49:17 -08002593 }}
2594
2595 for _, tt := range tests {
2596 tt := tt
2597 t.Run(tt.desc, func(t *testing.T) {
2598 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
2599 if err != nil && !tt.wantErr {
2600 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2601 }
2602 if err == nil && tt.wantErr {
2603 t.Error("Unmarshal() got nil error, want error\n\n")
2604 }
2605 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
2606 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2607 }
2608 })
2609 }
2610}