blob: c680c8aa99872e92ed9820abac0d91dcce22cef6 [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 (
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"
Damien Neil5c5b5312019-05-14 12:44:37 -070013 "google.golang.org/protobuf/encoding/protojson"
Damien Neile89e6242019-05-13 23:55:40 -070014 "google.golang.org/protobuf/encoding/testprotos/pb2"
15 "google.golang.org/protobuf/encoding/testprotos/pb3"
16 pimpl "google.golang.org/protobuf/internal/impl"
17 "google.golang.org/protobuf/internal/scalar"
18 "google.golang.org/protobuf/proto"
19 preg "google.golang.org/protobuf/reflect/protoregistry"
20 "google.golang.org/protobuf/runtime/protoiface"
Herbie Onge63c4c42019-03-22 22:20:22 -070021
Joe Tsaia95b29f2019-05-16 12:47:20 -070022 "google.golang.org/protobuf/types/known/anypb"
23 "google.golang.org/protobuf/types/known/durationpb"
24 "google.golang.org/protobuf/types/known/emptypb"
25 "google.golang.org/protobuf/types/known/fieldmaskpb"
26 "google.golang.org/protobuf/types/known/structpb"
27 "google.golang.org/protobuf/types/known/timestamppb"
28 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080029)
30
Herbie Onge52379a2019-03-15 18:00:19 -070031func init() {
32 // TODO: remove these registerExtension calls when generated code registers
33 // to V2 global registry.
34 registerExtension(pb2.E_OptExtBool)
35 registerExtension(pb2.E_OptExtString)
36 registerExtension(pb2.E_OptExtEnum)
37 registerExtension(pb2.E_OptExtNested)
38 registerExtension(pb2.E_RptExtFixed32)
39 registerExtension(pb2.E_RptExtEnum)
40 registerExtension(pb2.E_RptExtNested)
41 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
42 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
43 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
44 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
45 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
46 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
47 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
48 registerExtension(pb2.E_MessageSetExtension)
49 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
50 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
51 registerExtension(pb2.E_MessageSetExtension_ExtNested)
52 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
53}
54
Joe Tsai4fddeba2019-03-20 18:29:32 -070055func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Onge52379a2019-03-15 18:00:19 -070056 preg.GlobalTypes.Register(xd.Type)
57}
58
Herbie Ongc96a79d2019-03-08 10:49:17 -080059func TestUnmarshal(t *testing.T) {
60 tests := []struct {
61 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070062 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080063 inputMessage proto.Message
64 inputText string
65 wantMessage proto.Message
66 // TODO: verify expected error message substring.
67 wantErr bool
68 }{{
69 desc: "proto2 empty message",
70 inputMessage: &pb2.Scalars{},
71 inputText: "{}",
72 wantMessage: &pb2.Scalars{},
73 }, {
74 desc: "unexpected value instead of EOF",
75 inputMessage: &pb2.Scalars{},
76 inputText: "{} {}",
77 wantErr: true,
78 }, {
79 desc: "proto2 optional scalars set to zero values",
80 inputMessage: &pb2.Scalars{},
81 inputText: `{
82 "optBool": false,
83 "optInt32": 0,
84 "optInt64": 0,
85 "optUint32": 0,
86 "optUint64": 0,
87 "optSint32": 0,
88 "optSint64": 0,
89 "optFixed32": 0,
90 "optFixed64": 0,
91 "optSfixed32": 0,
92 "optSfixed64": 0,
93 "optFloat": 0,
94 "optDouble": 0,
95 "optBytes": "",
96 "optString": ""
97}`,
98 wantMessage: &pb2.Scalars{
99 OptBool: scalar.Bool(false),
100 OptInt32: scalar.Int32(0),
101 OptInt64: scalar.Int64(0),
102 OptUint32: scalar.Uint32(0),
103 OptUint64: scalar.Uint64(0),
104 OptSint32: scalar.Int32(0),
105 OptSint64: scalar.Int64(0),
106 OptFixed32: scalar.Uint32(0),
107 OptFixed64: scalar.Uint64(0),
108 OptSfixed32: scalar.Int32(0),
109 OptSfixed64: scalar.Int64(0),
110 OptFloat: scalar.Float32(0),
111 OptDouble: scalar.Float64(0),
112 OptBytes: []byte{},
113 OptString: scalar.String(""),
114 },
115 }, {
116 desc: "proto3 scalars set to zero values",
117 inputMessage: &pb3.Scalars{},
118 inputText: `{
119 "sBool": false,
120 "sInt32": 0,
121 "sInt64": 0,
122 "sUint32": 0,
123 "sUint64": 0,
124 "sSint32": 0,
125 "sSint64": 0,
126 "sFixed32": 0,
127 "sFixed64": 0,
128 "sSfixed32": 0,
129 "sSfixed64": 0,
130 "sFloat": 0,
131 "sDouble": 0,
132 "sBytes": "",
133 "sString": ""
134}`,
135 wantMessage: &pb3.Scalars{},
136 }, {
137 desc: "proto2 optional scalars set to null",
138 inputMessage: &pb2.Scalars{},
139 inputText: `{
140 "optBool": null,
141 "optInt32": null,
142 "optInt64": null,
143 "optUint32": null,
144 "optUint64": null,
145 "optSint32": null,
146 "optSint64": null,
147 "optFixed32": null,
148 "optFixed64": null,
149 "optSfixed32": null,
150 "optSfixed64": null,
151 "optFloat": null,
152 "optDouble": null,
153 "optBytes": null,
154 "optString": null
155}`,
156 wantMessage: &pb2.Scalars{},
157 }, {
158 desc: "proto3 scalars set to null",
159 inputMessage: &pb3.Scalars{},
160 inputText: `{
161 "sBool": null,
162 "sInt32": null,
163 "sInt64": null,
164 "sUint32": null,
165 "sUint64": null,
166 "sSint32": null,
167 "sSint64": null,
168 "sFixed32": null,
169 "sFixed64": null,
170 "sSfixed32": null,
171 "sSfixed64": null,
172 "sFloat": null,
173 "sDouble": null,
174 "sBytes": null,
175 "sString": null
176}`,
177 wantMessage: &pb3.Scalars{},
178 }, {
179 desc: "boolean",
180 inputMessage: &pb3.Scalars{},
181 inputText: `{"sBool": true}`,
182 wantMessage: &pb3.Scalars{
183 SBool: true,
184 },
185 }, {
186 desc: "not boolean",
187 inputMessage: &pb3.Scalars{},
188 inputText: `{"sBool": "true"}`,
189 wantErr: true,
190 }, {
191 desc: "float and double",
192 inputMessage: &pb3.Scalars{},
193 inputText: `{
194 "sFloat": 1.234,
195 "sDouble": 5.678
196}`,
197 wantMessage: &pb3.Scalars{
198 SFloat: 1.234,
199 SDouble: 5.678,
200 },
201 }, {
202 desc: "float and double in string",
203 inputMessage: &pb3.Scalars{},
204 inputText: `{
205 "sFloat": "1.234",
206 "sDouble": "5.678"
207}`,
208 wantMessage: &pb3.Scalars{
209 SFloat: 1.234,
210 SDouble: 5.678,
211 },
212 }, {
213 desc: "float and double in E notation",
214 inputMessage: &pb3.Scalars{},
215 inputText: `{
216 "sFloat": 12.34E-1,
217 "sDouble": 5.678e4
218}`,
219 wantMessage: &pb3.Scalars{
220 SFloat: 1.234,
221 SDouble: 56780,
222 },
223 }, {
224 desc: "float and double in string E notation",
225 inputMessage: &pb3.Scalars{},
226 inputText: `{
227 "sFloat": "12.34E-1",
228 "sDouble": "5.678e4"
229}`,
230 wantMessage: &pb3.Scalars{
231 SFloat: 1.234,
232 SDouble: 56780,
233 },
234 }, {
235 desc: "float exceeds limit",
236 inputMessage: &pb3.Scalars{},
237 inputText: `{"sFloat": 3.4e39}`,
238 wantErr: true,
239 }, {
240 desc: "float in string exceeds limit",
241 inputMessage: &pb3.Scalars{},
242 inputText: `{"sFloat": "-3.4e39"}`,
243 wantErr: true,
244 }, {
245 desc: "double exceeds limit",
246 inputMessage: &pb3.Scalars{},
247 inputText: `{"sFloat": -1.79e+309}`,
248 wantErr: true,
249 }, {
250 desc: "double in string exceeds limit",
251 inputMessage: &pb3.Scalars{},
252 inputText: `{"sFloat": "1.79e+309"}`,
253 wantErr: true,
254 }, {
255 desc: "infinites",
256 inputMessage: &pb3.Scalars{},
257 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
258 wantMessage: &pb3.Scalars{
259 SFloat: float32(math.Inf(+1)),
260 SDouble: math.Inf(-1),
261 },
262 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700263 desc: "float string with leading space",
264 inputMessage: &pb3.Scalars{},
265 inputText: `{"sFloat": " 1.234"}`,
266 wantErr: true,
267 }, {
268 desc: "double string with trailing space",
269 inputMessage: &pb3.Scalars{},
270 inputText: `{"sDouble": "5.678 "}`,
271 wantErr: true,
272 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800273 desc: "not float",
274 inputMessage: &pb3.Scalars{},
275 inputText: `{"sFloat": true}`,
276 wantErr: true,
277 }, {
278 desc: "not double",
279 inputMessage: &pb3.Scalars{},
280 inputText: `{"sDouble": "not a number"}`,
281 wantErr: true,
282 }, {
283 desc: "integers",
284 inputMessage: &pb3.Scalars{},
285 inputText: `{
286 "sInt32": 1234,
287 "sInt64": -1234,
288 "sUint32": 1e2,
289 "sUint64": 100E-2,
290 "sSint32": 1.0,
291 "sSint64": -1.0,
292 "sFixed32": 1.234e+5,
293 "sFixed64": 1200E-2,
294 "sSfixed32": -1.234e05,
295 "sSfixed64": -1200e-02
296}`,
297 wantMessage: &pb3.Scalars{
298 SInt32: 1234,
299 SInt64: -1234,
300 SUint32: 100,
301 SUint64: 1,
302 SSint32: 1,
303 SSint64: -1,
304 SFixed32: 123400,
305 SFixed64: 12,
306 SSfixed32: -123400,
307 SSfixed64: -12,
308 },
309 }, {
310 desc: "integers in string",
311 inputMessage: &pb3.Scalars{},
312 inputText: `{
313 "sInt32": "1234",
314 "sInt64": "-1234",
315 "sUint32": "1e2",
316 "sUint64": "100E-2",
317 "sSint32": "1.0",
318 "sSint64": "-1.0",
319 "sFixed32": "1.234e+5",
320 "sFixed64": "1200E-2",
321 "sSfixed32": "-1.234e05",
322 "sSfixed64": "-1200e-02"
323}`,
324 wantMessage: &pb3.Scalars{
325 SInt32: 1234,
326 SInt64: -1234,
327 SUint32: 100,
328 SUint64: 1,
329 SSint32: 1,
330 SSint64: -1,
331 SFixed32: 123400,
332 SFixed64: 12,
333 SSfixed32: -123400,
334 SSfixed64: -12,
335 },
336 }, {
337 desc: "integers in escaped string",
338 inputMessage: &pb3.Scalars{},
339 inputText: `{"sInt32": "\u0031\u0032"}`,
340 wantMessage: &pb3.Scalars{
341 SInt32: 12,
342 },
343 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700344 desc: "integer string with leading space",
345 inputMessage: &pb3.Scalars{},
346 inputText: `{"sInt32": " 1234"}`,
347 wantErr: true,
348 }, {
349 desc: "integer string with trailing space",
350 inputMessage: &pb3.Scalars{},
351 inputText: `{"sUint32": "1e2 "}`,
352 wantErr: true,
353 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800354 desc: "number is not an integer",
355 inputMessage: &pb3.Scalars{},
356 inputText: `{"sInt32": 1.001}`,
357 wantErr: true,
358 }, {
359 desc: "32-bit int exceeds limit",
360 inputMessage: &pb3.Scalars{},
361 inputText: `{"sInt32": 2e10}`,
362 wantErr: true,
363 }, {
364 desc: "64-bit int exceeds limit",
365 inputMessage: &pb3.Scalars{},
366 inputText: `{"sSfixed64": -9e19}`,
367 wantErr: true,
368 }, {
369 desc: "not integer",
370 inputMessage: &pb3.Scalars{},
371 inputText: `{"sInt32": "not a number"}`,
372 wantErr: true,
373 }, {
374 desc: "not unsigned integer",
375 inputMessage: &pb3.Scalars{},
376 inputText: `{"sUint32": "not a number"}`,
377 wantErr: true,
378 }, {
379 desc: "number is not an unsigned integer",
380 inputMessage: &pb3.Scalars{},
381 inputText: `{"sUint32": -1}`,
382 wantErr: true,
383 }, {
384 desc: "string",
385 inputMessage: &pb2.Scalars{},
386 inputText: `{"optString": "谷歌"}`,
387 wantMessage: &pb2.Scalars{
388 OptString: scalar.String("谷歌"),
389 },
390 }, {
391 desc: "string with invalid UTF-8",
392 inputMessage: &pb3.Scalars{},
393 inputText: "{\"sString\": \"\xff\"}",
394 wantMessage: &pb3.Scalars{
395 SString: "\xff",
396 },
397 wantErr: true,
398 }, {
399 desc: "not string",
400 inputMessage: &pb2.Scalars{},
401 inputText: `{"optString": 42}`,
402 wantErr: true,
403 }, {
404 desc: "bytes",
405 inputMessage: &pb3.Scalars{},
406 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
407 wantMessage: &pb3.Scalars{
408 SBytes: []byte("hello world"),
409 },
410 }, {
411 desc: "bytes padded",
412 inputMessage: &pb3.Scalars{},
413 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
414 wantMessage: &pb3.Scalars{
415 SBytes: []byte("hello world"),
416 },
417 }, {
418 desc: "not bytes",
419 inputMessage: &pb3.Scalars{},
420 inputText: `{"sBytes": true}`,
421 wantErr: true,
422 }, {
423 desc: "proto2 enum",
424 inputMessage: &pb2.Enums{},
425 inputText: `{
426 "optEnum": "ONE",
427 "optNestedEnum": "UNO"
428}`,
429 wantMessage: &pb2.Enums{
430 OptEnum: pb2.Enum_ONE.Enum(),
431 OptNestedEnum: pb2.Enums_UNO.Enum(),
432 },
433 }, {
434 desc: "proto3 enum",
435 inputMessage: &pb3.Enums{},
436 inputText: `{
437 "sEnum": "ONE",
438 "sNestedEnum": "DIEZ"
439}`,
440 wantMessage: &pb3.Enums{
441 SEnum: pb3.Enum_ONE,
442 SNestedEnum: pb3.Enums_DIEZ,
443 },
444 }, {
445 desc: "enum numeric value",
446 inputMessage: &pb3.Enums{},
447 inputText: `{
448 "sEnum": 2,
449 "sNestedEnum": 2
450}`,
451 wantMessage: &pb3.Enums{
452 SEnum: pb3.Enum_TWO,
453 SNestedEnum: pb3.Enums_DOS,
454 },
455 }, {
456 desc: "enum unnamed numeric value",
457 inputMessage: &pb3.Enums{},
458 inputText: `{
459 "sEnum": 101,
460 "sNestedEnum": -101
461}`,
462 wantMessage: &pb3.Enums{
463 SEnum: 101,
464 SNestedEnum: -101,
465 },
466 }, {
467 desc: "enum set to number string",
468 inputMessage: &pb3.Enums{},
469 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700470 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800471}`,
472 wantErr: true,
473 }, {
474 desc: "enum set to invalid named",
475 inputMessage: &pb3.Enums{},
476 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700477 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800478}`,
479 wantErr: true,
480 }, {
481 desc: "enum set to not enum",
482 inputMessage: &pb3.Enums{},
483 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700484 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800485}`,
486 wantErr: true,
487 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700488 desc: "enum set to JSON null",
489 inputMessage: &pb3.Enums{},
490 inputText: `{
491 "sEnum": null
492}`,
493 wantMessage: &pb3.Enums{},
494 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800495 desc: "proto name",
496 inputMessage: &pb3.JSONNames{},
497 inputText: `{
498 "s_string": "proto name used"
499}`,
500 wantMessage: &pb3.JSONNames{
501 SString: "proto name used",
502 },
503 }, {
504 desc: "json_name",
505 inputMessage: &pb3.JSONNames{},
506 inputText: `{
507 "foo_bar": "json_name used"
508}`,
509 wantMessage: &pb3.JSONNames{
510 SString: "json_name used",
511 },
512 }, {
513 desc: "camelCase name",
514 inputMessage: &pb3.JSONNames{},
515 inputText: `{
516 "sString": "camelcase used"
517}`,
518 wantErr: true,
519 }, {
520 desc: "proto name and json_name",
521 inputMessage: &pb3.JSONNames{},
522 inputText: `{
523 "foo_bar": "json_name used",
524 "s_string": "proto name used"
525}`,
526 wantErr: true,
527 }, {
528 desc: "duplicate field names",
529 inputMessage: &pb3.JSONNames{},
530 inputText: `{
531 "foo_bar": "one",
532 "foo_bar": "two",
533}`,
534 wantErr: true,
535 }, {
536 desc: "null message",
537 inputMessage: &pb2.Nests{},
538 inputText: "null",
539 wantErr: true,
540 }, {
541 desc: "proto2 nested message not set",
542 inputMessage: &pb2.Nests{},
543 inputText: "{}",
544 wantMessage: &pb2.Nests{},
545 }, {
546 desc: "proto2 nested message set to null",
547 inputMessage: &pb2.Nests{},
548 inputText: `{
549 "optNested": null,
550 "optgroup": null
551}`,
552 wantMessage: &pb2.Nests{},
553 }, {
554 desc: "proto2 nested message set to empty",
555 inputMessage: &pb2.Nests{},
556 inputText: `{
557 "optNested": {},
558 "optgroup": {}
559}`,
560 wantMessage: &pb2.Nests{
561 OptNested: &pb2.Nested{},
562 Optgroup: &pb2.Nests_OptGroup{},
563 },
564 }, {
565 desc: "proto2 nested messages",
566 inputMessage: &pb2.Nests{},
567 inputText: `{
568 "optNested": {
569 "optString": "nested message",
570 "optNested": {
571 "optString": "another nested message"
572 }
573 }
574}`,
575 wantMessage: &pb2.Nests{
576 OptNested: &pb2.Nested{
577 OptString: scalar.String("nested message"),
578 OptNested: &pb2.Nested{
579 OptString: scalar.String("another nested message"),
580 },
581 },
582 },
583 }, {
584 desc: "proto2 groups",
585 inputMessage: &pb2.Nests{},
586 inputText: `{
587 "optgroup": {
588 "optString": "inside a group",
589 "optNested": {
590 "optString": "nested message inside a group"
591 },
592 "optnestedgroup": {
593 "optFixed32": 47
594 }
595 }
596}`,
597 wantMessage: &pb2.Nests{
598 Optgroup: &pb2.Nests_OptGroup{
599 OptString: scalar.String("inside a group"),
600 OptNested: &pb2.Nested{
601 OptString: scalar.String("nested message inside a group"),
602 },
603 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
604 OptFixed32: scalar.Uint32(47),
605 },
606 },
607 },
608 }, {
609 desc: "proto3 nested message not set",
610 inputMessage: &pb3.Nests{},
611 inputText: "{}",
612 wantMessage: &pb3.Nests{},
613 }, {
614 desc: "proto3 nested message set to null",
615 inputMessage: &pb3.Nests{},
616 inputText: `{"sNested": null}`,
617 wantMessage: &pb3.Nests{},
618 }, {
619 desc: "proto3 nested message set to empty",
620 inputMessage: &pb3.Nests{},
621 inputText: `{"sNested": {}}`,
622 wantMessage: &pb3.Nests{
623 SNested: &pb3.Nested{},
624 },
625 }, {
626 desc: "proto3 nested message",
627 inputMessage: &pb3.Nests{},
628 inputText: `{
629 "sNested": {
630 "sString": "nested message",
631 "sNested": {
632 "sString": "another nested message"
633 }
634 }
635}`,
636 wantMessage: &pb3.Nests{
637 SNested: &pb3.Nested{
638 SString: "nested message",
639 SNested: &pb3.Nested{
640 SString: "another nested message",
641 },
642 },
643 },
644 }, {
645 desc: "message set to non-message",
646 inputMessage: &pb3.Nests{},
647 inputText: `"not valid"`,
648 wantErr: true,
649 }, {
650 desc: "nested message set to non-message",
651 inputMessage: &pb3.Nests{},
652 inputText: `{"sNested": true}`,
653 wantErr: true,
654 }, {
655 desc: "oneof not set",
656 inputMessage: &pb3.Oneofs{},
657 inputText: "{}",
658 wantMessage: &pb3.Oneofs{},
659 }, {
660 desc: "oneof set to empty string",
661 inputMessage: &pb3.Oneofs{},
662 inputText: `{"oneofString": ""}`,
663 wantMessage: &pb3.Oneofs{
664 Union: &pb3.Oneofs_OneofString{},
665 },
666 }, {
667 desc: "oneof set to string",
668 inputMessage: &pb3.Oneofs{},
669 inputText: `{"oneofString": "hello"}`,
670 wantMessage: &pb3.Oneofs{
671 Union: &pb3.Oneofs_OneofString{
672 OneofString: "hello",
673 },
674 },
675 }, {
676 desc: "oneof set to enum",
677 inputMessage: &pb3.Oneofs{},
678 inputText: `{"oneofEnum": "ZERO"}`,
679 wantMessage: &pb3.Oneofs{
680 Union: &pb3.Oneofs_OneofEnum{
681 OneofEnum: pb3.Enum_ZERO,
682 },
683 },
684 }, {
685 desc: "oneof set to empty message",
686 inputMessage: &pb3.Oneofs{},
687 inputText: `{"oneofNested": {}}`,
688 wantMessage: &pb3.Oneofs{
689 Union: &pb3.Oneofs_OneofNested{
690 OneofNested: &pb3.Nested{},
691 },
692 },
693 }, {
694 desc: "oneof set to message",
695 inputMessage: &pb3.Oneofs{},
696 inputText: `{
697 "oneofNested": {
698 "sString": "nested message"
699 }
700}`,
701 wantMessage: &pb3.Oneofs{
702 Union: &pb3.Oneofs_OneofNested{
703 OneofNested: &pb3.Nested{
704 SString: "nested message",
705 },
706 },
707 },
708 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700709 desc: "oneof set to more than one field",
710 inputMessage: &pb3.Oneofs{},
711 inputText: `{
712 "oneofEnum": "ZERO",
713 "oneofString": "hello"
714}`,
715 wantErr: true,
716 }, {
717 desc: "oneof set to null and value",
718 inputMessage: &pb3.Oneofs{},
719 inputText: `{
720 "oneofEnum": "ZERO",
721 "oneofString": null
722}`,
723 wantMessage: &pb3.Oneofs{
724 Union: &pb3.Oneofs_OneofEnum{
725 OneofEnum: pb3.Enum_ZERO,
726 },
727 },
728 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800729 desc: "repeated null fields",
730 inputMessage: &pb2.Repeats{},
731 inputText: `{
732 "rptString": null,
733 "rptInt32" : null,
734 "rptFloat" : null,
735 "rptBytes" : null
736}`,
737 wantMessage: &pb2.Repeats{},
738 }, {
739 desc: "repeated scalars",
740 inputMessage: &pb2.Repeats{},
741 inputText: `{
742 "rptString": ["hello", "world"],
743 "rptInt32" : [-1, 0, 1],
744 "rptBool" : [false, true]
745}`,
746 wantMessage: &pb2.Repeats{
747 RptString: []string{"hello", "world"},
748 RptInt32: []int32{-1, 0, 1},
749 RptBool: []bool{false, true},
750 },
751 }, {
752 desc: "repeated enums",
753 inputMessage: &pb2.Enums{},
754 inputText: `{
755 "rptEnum" : ["TEN", 1, 42],
756 "rptNestedEnum": ["DOS", 2, -47]
757}`,
758 wantMessage: &pb2.Enums{
759 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
760 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
761 },
762 }, {
763 desc: "repeated messages",
764 inputMessage: &pb2.Nests{},
765 inputText: `{
766 "rptNested": [
767 {
768 "optString": "repeat nested one"
769 },
770 {
771 "optString": "repeat nested two",
772 "optNested": {
773 "optString": "inside repeat nested two"
774 }
775 },
776 {}
777 ]
778}`,
779 wantMessage: &pb2.Nests{
780 RptNested: []*pb2.Nested{
781 {
782 OptString: scalar.String("repeat nested one"),
783 },
784 {
785 OptString: scalar.String("repeat nested two"),
786 OptNested: &pb2.Nested{
787 OptString: scalar.String("inside repeat nested two"),
788 },
789 },
790 {},
791 },
792 },
793 }, {
794 desc: "repeated groups",
795 inputMessage: &pb2.Nests{},
796 inputText: `{
797 "rptgroup": [
798 {
799 "rptString": ["hello", "world"]
800 },
801 {}
802 ]
803}
804`,
805 wantMessage: &pb2.Nests{
806 Rptgroup: []*pb2.Nests_RptGroup{
807 {
808 RptString: []string{"hello", "world"},
809 },
810 {},
811 },
812 },
813 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700814 desc: "repeated string contains invalid UTF8",
815 inputMessage: &pb2.Repeats{},
816 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
817 wantMessage: &pb2.Repeats{
818 RptString: []string{"abc\xff"},
819 },
820 wantErr: true,
821 }, {
822 desc: "repeated messages contain invalid UTF8",
823 inputMessage: &pb2.Nests{},
824 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
825 wantMessage: &pb2.Nests{
826 RptNested: []*pb2.Nested{{OptString: scalar.String("abc\xff")}},
827 },
828 wantErr: true,
829 }, {
830 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800831 inputMessage: &pb2.Repeats{},
832 inputText: `{"rptString": ["hello", null, "world"]}`,
833 wantErr: true,
834 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700835 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800836 inputMessage: &pb2.Nests{},
837 inputText: `{"rptNested": [{}, null]}`,
838 wantErr: true,
839 }, {
840 desc: "map fields 1",
841 inputMessage: &pb3.Maps{},
842 inputText: `{
843 "int32ToStr": {
844 "-101": "-101",
845 "0" : "zero",
846 "255" : "0xff"
847 },
848 "boolToUint32": {
849 "false": 101,
850 "true" : "42"
851 }
852}`,
853 wantMessage: &pb3.Maps{
854 Int32ToStr: map[int32]string{
855 -101: "-101",
856 0xff: "0xff",
857 0: "zero",
858 },
859 BoolToUint32: map[bool]uint32{
860 true: 42,
861 false: 101,
862 },
863 },
864 }, {
865 desc: "map fields 2",
866 inputMessage: &pb3.Maps{},
867 inputText: `{
868 "uint64ToEnum": {
869 "1" : "ONE",
870 "2" : 2,
871 "10": 101
872 }
873}`,
874 wantMessage: &pb3.Maps{
875 Uint64ToEnum: map[uint64]pb3.Enum{
876 1: pb3.Enum_ONE,
877 2: pb3.Enum_TWO,
878 10: 101,
879 },
880 },
881 }, {
882 desc: "map fields 3",
883 inputMessage: &pb3.Maps{},
884 inputText: `{
885 "strToNested": {
886 "nested_one": {
887 "sString": "nested in a map"
888 },
889 "nested_two": {}
890 }
891}`,
892 wantMessage: &pb3.Maps{
893 StrToNested: map[string]*pb3.Nested{
894 "nested_one": {
895 SString: "nested in a map",
896 },
897 "nested_two": {},
898 },
899 },
900 }, {
901 desc: "map fields 4",
902 inputMessage: &pb3.Maps{},
903 inputText: `{
904 "strToOneofs": {
905 "nested": {
906 "oneofNested": {
907 "sString": "nested oneof in map field value"
908 }
909 },
910 "string": {
911 "oneofString": "hello"
912 }
913 }
914}`,
915 wantMessage: &pb3.Maps{
916 StrToOneofs: map[string]*pb3.Oneofs{
917 "string": {
918 Union: &pb3.Oneofs_OneofString{
919 OneofString: "hello",
920 },
921 },
922 "nested": {
923 Union: &pb3.Oneofs_OneofNested{
924 OneofNested: &pb3.Nested{
925 SString: "nested oneof in map field value",
926 },
927 },
928 },
929 },
930 },
931 }, {
932 desc: "map contains duplicate keys",
933 inputMessage: &pb3.Maps{},
934 inputText: `{
935 "int32ToStr": {
936 "0": "cero",
937 "0": "zero"
938 }
939}
940`,
941 wantErr: true,
942 }, {
943 desc: "map key empty string",
944 inputMessage: &pb3.Maps{},
945 inputText: `{
946 "strToNested": {
947 "": {}
948 }
949}`,
950 wantMessage: &pb3.Maps{
951 StrToNested: map[string]*pb3.Nested{
952 "": {},
953 },
954 },
955 }, {
956 desc: "map contains invalid key 1",
957 inputMessage: &pb3.Maps{},
958 inputText: `{
959 "int32ToStr": {
960 "invalid": "cero"
961}`,
962 wantErr: true,
963 }, {
964 desc: "map contains invalid key 2",
965 inputMessage: &pb3.Maps{},
966 inputText: `{
967 "int32ToStr": {
968 "1.02": "float"
969}`,
970 wantErr: true,
971 }, {
972 desc: "map contains invalid key 3",
973 inputMessage: &pb3.Maps{},
974 inputText: `{
975 "int32ToStr": {
976 "2147483648": "exceeds 32-bit integer max limit"
977}`,
978 wantErr: true,
979 }, {
980 desc: "map contains invalid key 4",
981 inputMessage: &pb3.Maps{},
982 inputText: `{
983 "uint64ToEnum": {
984 "-1": 0
985 }
986}`,
987 wantErr: true,
988 }, {
989 desc: "map contains invalid value",
990 inputMessage: &pb3.Maps{},
991 inputText: `{
992 "int32ToStr": {
993 "101": true
994}`,
995 wantErr: true,
996 }, {
997 desc: "map contains null for scalar value",
998 inputMessage: &pb3.Maps{},
999 inputText: `{
1000 "int32ToStr": {
1001 "101": null
1002}`,
1003 wantErr: true,
1004 }, {
1005 desc: "map contains null for message value",
1006 inputMessage: &pb3.Maps{},
1007 inputText: `{
1008 "strToNested": {
1009 "hello": null
1010 }
1011}`,
1012 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -07001013 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001014 desc: "map contains contains message value with invalid UTF8",
1015 inputMessage: &pb3.Maps{},
1016 inputText: `{
1017 "strToNested": {
1018 "hello": {
1019 "sString": "` + "abc\xff" + `"
1020 }
1021 }
1022}`,
1023 wantMessage: &pb3.Maps{
1024 StrToNested: map[string]*pb3.Nested{
1025 "hello": {SString: "abc\xff"},
1026 },
1027 },
1028 wantErr: true,
1029 }, {
1030 desc: "map key contains invalid UTF8",
1031 inputMessage: &pb3.Maps{},
1032 inputText: `{
1033 "strToNested": {
1034 "` + "abc\xff" + `": {}
1035 }
1036}`,
1037 wantMessage: &pb3.Maps{
1038 StrToNested: map[string]*pb3.Nested{
1039 "abc\xff": {},
1040 },
1041 },
1042 wantErr: true,
1043 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001044 desc: "required fields not set",
1045 inputMessage: &pb2.Requireds{},
1046 wantErr: true,
1047 }, {
1048 desc: "required field set",
1049 inputMessage: &pb2.PartialRequired{},
1050 inputText: `{
1051 "reqString": "this is required"
1052}`,
1053 wantMessage: &pb2.PartialRequired{
1054 ReqString: scalar.String("this is required"),
1055 },
1056 }, {
1057 desc: "required fields partially set",
1058 inputMessage: &pb2.Requireds{},
1059 inputText: `{
1060 "reqBool": false,
1061 "reqSfixed64": 42,
1062 "reqString": "hello",
1063 "reqEnum": "ONE"
1064}`,
1065 wantMessage: &pb2.Requireds{
1066 ReqBool: scalar.Bool(false),
1067 ReqSfixed64: scalar.Int64(42),
1068 ReqString: scalar.String("hello"),
1069 ReqEnum: pb2.Enum_ONE.Enum(),
1070 },
1071 wantErr: true,
1072 }, {
1073 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001074 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001075 inputMessage: &pb2.Requireds{},
1076 inputText: `{
1077 "reqBool": false,
1078 "reqSfixed64": 42,
1079 "reqString": "hello",
1080 "reqEnum": "ONE"
1081}`,
1082 wantMessage: &pb2.Requireds{
1083 ReqBool: scalar.Bool(false),
1084 ReqSfixed64: scalar.Int64(42),
1085 ReqString: scalar.String("hello"),
1086 ReqEnum: pb2.Enum_ONE.Enum(),
1087 },
1088 }, {
1089 desc: "required fields all set",
1090 inputMessage: &pb2.Requireds{},
1091 inputText: `{
1092 "reqBool": false,
1093 "reqSfixed64": 42,
1094 "reqDouble": 1.23,
1095 "reqString": "hello",
1096 "reqEnum": "ONE",
1097 "reqNested": {}
1098}`,
1099 wantMessage: &pb2.Requireds{
1100 ReqBool: scalar.Bool(false),
1101 ReqSfixed64: scalar.Int64(42),
1102 ReqDouble: scalar.Float64(1.23),
1103 ReqString: scalar.String("hello"),
1104 ReqEnum: pb2.Enum_ONE.Enum(),
1105 ReqNested: &pb2.Nested{},
1106 },
1107 }, {
1108 desc: "indirect required field",
1109 inputMessage: &pb2.IndirectRequired{},
1110 inputText: `{
1111 "optNested": {}
1112}`,
1113 wantMessage: &pb2.IndirectRequired{
1114 OptNested: &pb2.NestedWithRequired{},
1115 },
1116 wantErr: true,
1117 }, {
1118 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001119 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001120 inputMessage: &pb2.IndirectRequired{},
1121 inputText: `{
1122 "optNested": {}
1123}`,
1124 wantMessage: &pb2.IndirectRequired{
1125 OptNested: &pb2.NestedWithRequired{},
1126 },
1127 }, {
1128 desc: "indirect required field in repeated",
1129 inputMessage: &pb2.IndirectRequired{},
1130 inputText: `{
1131 "rptNested": [
1132 {"reqString": "one"},
1133 {}
1134 ]
1135}`,
1136 wantMessage: &pb2.IndirectRequired{
1137 RptNested: []*pb2.NestedWithRequired{
1138 {
1139 ReqString: scalar.String("one"),
1140 },
1141 {},
1142 },
1143 },
1144 wantErr: true,
1145 }, {
1146 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001147 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001148 inputMessage: &pb2.IndirectRequired{},
1149 inputText: `{
1150 "rptNested": [
1151 {"reqString": "one"},
1152 {}
1153 ]
1154}`,
1155 wantMessage: &pb2.IndirectRequired{
1156 RptNested: []*pb2.NestedWithRequired{
1157 {
1158 ReqString: scalar.String("one"),
1159 },
1160 {},
1161 },
1162 },
1163 }, {
1164 desc: "indirect required field in map",
1165 inputMessage: &pb2.IndirectRequired{},
1166 inputText: `{
1167 "strToNested": {
1168 "missing": {},
1169 "contains": {
1170 "reqString": "here"
1171 }
1172 }
1173}`,
1174 wantMessage: &pb2.IndirectRequired{
1175 StrToNested: map[string]*pb2.NestedWithRequired{
1176 "missing": &pb2.NestedWithRequired{},
1177 "contains": &pb2.NestedWithRequired{
1178 ReqString: scalar.String("here"),
1179 },
1180 },
1181 },
1182 wantErr: true,
1183 }, {
1184 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001185 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001186 inputMessage: &pb2.IndirectRequired{},
1187 inputText: `{
1188 "strToNested": {
1189 "missing": {},
1190 "contains": {
1191 "reqString": "here"
1192 }
1193 }
1194}`,
1195 wantMessage: &pb2.IndirectRequired{
1196 StrToNested: map[string]*pb2.NestedWithRequired{
1197 "missing": &pb2.NestedWithRequired{},
1198 "contains": &pb2.NestedWithRequired{
1199 ReqString: scalar.String("here"),
1200 },
1201 },
1202 },
1203 }, {
1204 desc: "indirect required field in oneof",
1205 inputMessage: &pb2.IndirectRequired{},
1206 inputText: `{
1207 "oneofNested": {}
1208}`,
1209 wantMessage: &pb2.IndirectRequired{
1210 Union: &pb2.IndirectRequired_OneofNested{
1211 OneofNested: &pb2.NestedWithRequired{},
1212 },
1213 },
1214 wantErr: true,
1215 }, {
1216 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001217 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001218 inputMessage: &pb2.IndirectRequired{},
1219 inputText: `{
1220 "oneofNested": {}
1221}`,
1222 wantMessage: &pb2.IndirectRequired{
1223 Union: &pb2.IndirectRequired_OneofNested{
1224 OneofNested: &pb2.NestedWithRequired{},
1225 },
1226 },
1227 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001228 desc: "extensions of non-repeated fields",
1229 inputMessage: &pb2.Extensions{},
1230 inputText: `{
1231 "optString": "non-extension field",
1232 "optBool": true,
1233 "optInt32": 42,
1234 "[pb2.opt_ext_bool]": true,
1235 "[pb2.opt_ext_nested]": {
1236 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001237 "optNested": {
1238 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001239 }
1240 },
1241 "[pb2.opt_ext_string]": "extension field",
1242 "[pb2.opt_ext_enum]": "TEN"
1243}`,
1244 wantMessage: func() proto.Message {
1245 m := &pb2.Extensions{
1246 OptString: scalar.String("non-extension field"),
1247 OptBool: scalar.Bool(true),
1248 OptInt32: scalar.Int32(42),
1249 }
1250 setExtension(m, pb2.E_OptExtBool, true)
1251 setExtension(m, pb2.E_OptExtString, "extension field")
1252 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1253 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1254 OptString: scalar.String("nested in an extension"),
1255 OptNested: &pb2.Nested{
1256 OptString: scalar.String("another nested in an extension"),
1257 },
1258 })
1259 return m
1260 }(),
1261 }, {
1262 desc: "extensions of repeated fields",
1263 inputMessage: &pb2.Extensions{},
1264 inputText: `{
1265 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1266 "[pb2.rpt_ext_fixed32]": [42, 47],
1267 "[pb2.rpt_ext_nested]": [
1268 {"optString": "one"},
1269 {"optString": "two"},
1270 {"optString": "three"}
1271 ]
1272}`,
1273 wantMessage: func() proto.Message {
1274 m := &pb2.Extensions{}
1275 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1276 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1277 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1278 &pb2.Nested{OptString: scalar.String("one")},
1279 &pb2.Nested{OptString: scalar.String("two")},
1280 &pb2.Nested{OptString: scalar.String("three")},
1281 })
1282 return m
1283 }(),
1284 }, {
1285 desc: "extensions of non-repeated fields in another message",
1286 inputMessage: &pb2.Extensions{},
1287 inputText: `{
1288 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1289 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1290 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1291 "optString": "nested in an extension",
1292 "optNested": {
1293 "optString": "another nested in an extension"
1294 }
1295 },
1296 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1297}`,
1298 wantMessage: func() proto.Message {
1299 m := &pb2.Extensions{}
1300 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1301 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1302 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1303 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1304 OptString: scalar.String("nested in an extension"),
1305 OptNested: &pb2.Nested{
1306 OptString: scalar.String("another nested in an extension"),
1307 },
1308 })
1309 return m
1310 }(),
1311 }, {
1312 desc: "extensions of repeated fields in another message",
1313 inputMessage: &pb2.Extensions{},
1314 inputText: `{
1315 "optString": "non-extension field",
1316 "optBool": true,
1317 "optInt32": 42,
1318 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1319 {"optString": "one"},
1320 {"optString": "two"},
1321 {"optString": "three"}
1322 ],
1323 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1324 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1325}`,
1326 wantMessage: func() proto.Message {
1327 m := &pb2.Extensions{
1328 OptString: scalar.String("non-extension field"),
1329 OptBool: scalar.Bool(true),
1330 OptInt32: scalar.Int32(42),
1331 }
1332 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1333 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1334 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1335 &pb2.Nested{OptString: scalar.String("one")},
1336 &pb2.Nested{OptString: scalar.String("two")},
1337 &pb2.Nested{OptString: scalar.String("three")},
1338 })
1339 return m
1340 }(),
1341 }, {
1342 desc: "invalid extension field name",
1343 inputMessage: &pb2.Extensions{},
1344 inputText: `{ "[pb2.invalid_message_field]": true }`,
1345 wantErr: true,
1346 }, {
1347 desc: "MessageSet",
1348 inputMessage: &pb2.MessageSet{},
1349 inputText: `{
1350 "[pb2.MessageSetExtension]": {
1351 "optString": "a messageset extension"
1352 },
1353 "[pb2.MessageSetExtension.ext_nested]": {
1354 "optString": "just a regular extension"
1355 },
1356 "[pb2.MessageSetExtension.not_message_set_extension]": {
1357 "optString": "not a messageset extension"
1358 }
1359}`,
1360 wantMessage: func() proto.Message {
1361 m := &pb2.MessageSet{}
1362 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1363 OptString: scalar.String("a messageset extension"),
1364 })
1365 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1366 OptString: scalar.String("not a messageset extension"),
1367 })
1368 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1369 OptString: scalar.String("just a regular extension"),
1370 })
1371 return m
1372 }(),
1373 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001374 desc: "extensions of repeated field contains null",
1375 inputMessage: &pb2.Extensions{},
1376 inputText: `{
1377 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1378 {"optString": "one"},
1379 null,
1380 {"optString": "three"}
1381 ],
1382}`,
1383 wantErr: true,
1384 }, {
1385 desc: "not real MessageSet 1",
1386 inputMessage: &pb2.FakeMessageSet{},
1387 inputText: `{
1388 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1389 "optString": "not a messageset extension"
1390 }
1391}`,
1392 wantMessage: func() proto.Message {
1393 m := &pb2.FakeMessageSet{}
1394 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1395 OptString: scalar.String("not a messageset extension"),
1396 })
1397 return m
1398 }(),
1399 }, {
1400 desc: "not real MessageSet 2",
1401 inputMessage: &pb2.FakeMessageSet{},
1402 inputText: `{
1403 "[pb2.FakeMessageSetExtension]": {
1404 "optString": "not a messageset extension"
1405 }
1406}`,
1407 wantErr: true,
1408 }, {
1409 desc: "not real MessageSet 3",
1410 inputMessage: &pb2.MessageSet{},
1411 inputText: `{
1412 "[pb2.message_set_extension]": {
1413 "optString": "another not a messageset extension"
1414 }
1415}`,
1416 wantMessage: func() proto.Message {
1417 m := &pb2.MessageSet{}
1418 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1419 OptString: scalar.String("another not a messageset extension"),
1420 })
1421 return m
1422 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001423 }, {
1424 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001425 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001426 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001427 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001428 }, {
1429 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001430 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001431 inputText: `{"unknown": null}`,
1432 wantErr: true,
1433 }, {
1434 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001435 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001436 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001437 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001438 }, {
1439 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001440 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001441 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001442 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001443 }, {
1444 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001445 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001446 inputText: `{}`,
1447 wantErr: true,
1448 }, {
1449 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001450 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001451 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001452 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001453 }, {
1454 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001455 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001456 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001457 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001458 }, {
1459 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001460 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001461 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001463 }, {
1464 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001465 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001466 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001467 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001468 }, {
1469 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001470 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001471 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001472 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001473 }, {
1474 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001475 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001476 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001477 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001478 }, {
1479 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001480 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001481 inputText: `1.23+40`,
1482 wantErr: true,
1483 }, {
1484 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001485 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001486 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001487 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001488 }, {
1489 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001490 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001491 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001492 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001493 }, {
1494 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001495 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001496 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001497 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001498 }, {
1499 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001500 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001501 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001502 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001503 }, {
1504 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001505 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001506 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001507 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001508 }, {
1509 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001510 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001511 inputText: "\"abc\xff\"",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001512 wantMessage: &wrapperspb.StringValue{Value: "abc\xff"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001513 wantErr: true,
1514 }, {
1515 desc: "StringValue field with invalid UTF8 error",
1516 inputMessage: &pb2.KnownTypes{},
1517 inputText: "{\n \"optString\": \"abc\xff\"\n}",
1518 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001519 OptString: &wrapperspb.StringValue{Value: "abc\xff"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001520 },
1521 wantErr: true,
1522 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001523 desc: "NullValue field with JSON null",
1524 inputMessage: &pb2.KnownTypes{},
1525 inputText: `{
1526 "optNull": null
1527}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001528 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001529 }, {
1530 desc: "NullValue field with string",
1531 inputMessage: &pb2.KnownTypes{},
1532 inputText: `{
1533 "optNull": "NULL_VALUE"
1534}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001535 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001536 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001537 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001538 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001539 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001540 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001541 }, {
1542 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001543 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001544 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001545 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001546 }, {
1547 desc: "Value field null",
1548 inputMessage: &pb2.KnownTypes{},
1549 inputText: `{
1550 "optValue": null
1551}`,
1552 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001553 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001554 },
1555 }, {
1556 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001557 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001558 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001559 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001560 }, {
1561 desc: "Value field bool",
1562 inputMessage: &pb2.KnownTypes{},
1563 inputText: `{
1564 "optValue": true
1565}`,
1566 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001567 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001568 },
1569 }, {
1570 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001571 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001572 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001573 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001574 }, {
1575 desc: "Value field number",
1576 inputMessage: &pb2.KnownTypes{},
1577 inputText: `{
1578 "optValue": 1.02
1579}`,
1580 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001581 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001582 },
1583 }, {
1584 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001585 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001586 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001587 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001588 }, {
1589 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001590 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001591 inputText: "\"\xff\"",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001592 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001593 wantErr: true,
1594 }, {
1595 desc: "Value field string",
1596 inputMessage: &pb2.KnownTypes{},
1597 inputText: `{
1598 "optValue": "NaN"
1599}`,
1600 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001601 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001602 },
1603 }, {
1604 desc: "Value field string with invalid UTF8",
1605 inputMessage: &pb2.KnownTypes{},
1606 inputText: `{
1607 "optValue": "` + "\xff" + `"
1608}`,
1609 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001610 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001611 },
1612 wantErr: true,
1613 }, {
1614 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001615 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001616 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001617 wantMessage: &structpb.Value{
1618 Kind: &structpb.Value_StructValue{
1619 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001620 },
1621 },
1622 }, {
1623 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001624 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001625 inputText: `{
1626 "string": "hello",
1627 "number": 123,
1628 "null": null,
1629 "bool": false,
1630 "struct": {
1631 "string": "world"
1632 },
1633 "list": []
1634}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001635 wantMessage: &structpb.Value{
1636 Kind: &structpb.Value_StructValue{
1637 &structpb.Struct{
1638 Fields: map[string]*structpb.Value{
1639 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1640 "number": {Kind: &structpb.Value_NumberValue{123}},
1641 "null": {Kind: &structpb.Value_NullValue{}},
1642 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001643 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001644 Kind: &structpb.Value_StructValue{
1645 &structpb.Struct{
1646 Fields: map[string]*structpb.Value{
1647 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001648 },
1649 },
1650 },
1651 },
1652 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001653 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001654 },
1655 },
1656 },
1657 },
1658 },
1659 }, {
1660 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001661 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001662 inputText: "{\"string\": \"abc\xff\"}",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001663 wantMessage: &structpb.Value{
1664 Kind: &structpb.Value_StructValue{
1665 &structpb.Struct{
1666 Fields: map[string]*structpb.Value{
1667 "string": {Kind: &structpb.Value_StringValue{"abc\xff"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001668 },
1669 },
1670 },
1671 },
1672 wantErr: true,
1673 }, {
1674 desc: "Value field struct",
1675 inputMessage: &pb2.KnownTypes{},
1676 inputText: `{
1677 "optValue": {
1678 "string": "hello"
1679 }
1680}`,
1681 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001682 OptValue: &structpb.Value{
1683 Kind: &structpb.Value_StructValue{
1684 &structpb.Struct{
1685 Fields: map[string]*structpb.Value{
1686 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001687 },
1688 },
1689 },
1690 },
1691 },
1692 }, {
1693 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001694 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001695 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001696 wantMessage: &structpb.Value{
1697 Kind: &structpb.Value_ListValue{
1698 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001699 },
1700 },
1701 }, {
1702 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001703 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001704 inputText: `[
1705 "string",
1706 123,
1707 null,
1708 true,
1709 {},
1710 [
1711 "string",
1712 1.23,
1713 null,
1714 false
1715 ]
1716]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001717 wantMessage: &structpb.Value{
1718 Kind: &structpb.Value_ListValue{
1719 &structpb.ListValue{
1720 Values: []*structpb.Value{
1721 {Kind: &structpb.Value_StringValue{"string"}},
1722 {Kind: &structpb.Value_NumberValue{123}},
1723 {Kind: &structpb.Value_NullValue{}},
1724 {Kind: &structpb.Value_BoolValue{true}},
1725 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001726 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001727 Kind: &structpb.Value_ListValue{
1728 &structpb.ListValue{
1729 Values: []*structpb.Value{
1730 {Kind: &structpb.Value_StringValue{"string"}},
1731 {Kind: &structpb.Value_NumberValue{1.23}},
1732 {Kind: &structpb.Value_NullValue{}},
1733 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001734 },
1735 },
1736 },
1737 },
1738 },
1739 },
1740 },
1741 },
1742 }, {
1743 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001744 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001745 inputText: "[\"abc\xff\"]",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001746 wantMessage: &structpb.Value{
1747 Kind: &structpb.Value_ListValue{
1748 &structpb.ListValue{
1749 Values: []*structpb.Value{
1750 {Kind: &structpb.Value_StringValue{"abc\xff"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001751 },
1752 },
1753 },
1754 },
1755 wantErr: true,
1756 }, {
1757 desc: "Value field list with invalid UTF8 string",
1758 inputMessage: &pb2.KnownTypes{},
1759 inputText: `{
1760 "optValue": [ "` + "abc\xff" + `"]
1761}`,
1762 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 OptValue: &structpb.Value{
1764 Kind: &structpb.Value_ListValue{
1765 &structpb.ListValue{
1766 Values: []*structpb.Value{
1767 {Kind: &structpb.Value_StringValue{"abc\xff"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001768 },
1769 },
1770 },
1771 },
1772 },
1773 wantErr: true,
1774 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001775 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001776 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001777 inputText: `""`,
1778 wantErr: true,
1779 }, {
1780 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001781 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001782 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001783 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001784 }, {
1785 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001786 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001787 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001788 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001789 }, {
1790 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001791 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001792 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001793 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001794 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001795 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001796 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001797 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001798 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001799 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001800 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001801 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001802 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001803 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001804 }, {
1805 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001806 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001807 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001808 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001809 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001810 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001811 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001812 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001813 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001814 }, {
1815 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001816 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001817 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001818 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001819 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001820 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001821 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001822 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001824 }, {
1825 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001826 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001827 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 }, {
1830 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001831 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001832 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 }, {
1835 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001836 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001837 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001838 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001839 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001840 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001841 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001842 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001844 }, {
1845 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001846 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001847 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001848 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001849 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001850 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001851 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001852 inputText: `"315576000001s"`,
1853 wantErr: true,
1854 }, {
1855 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001856 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001857 inputText: `"-315576000001s"`,
1858 wantErr: true,
1859 }, {
1860 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001861 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001862 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001863 wantErr: true,
1864 }, {
1865 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001866 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001867 inputText: `"123"`,
1868 wantErr: true,
1869 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001870 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001871 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001872 inputText: `"123.+123s"`,
1873 wantErr: true,
1874 }, {
1875 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001876 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001877 inputText: `"123.123.s"`,
1878 wantErr: true,
1879 }, {
1880 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001881 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001882 inputText: `"01s"`,
1883 wantErr: true,
1884 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001885 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001886 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001887 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001888 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001889 }, {
1890 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001891 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001892 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001893 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001894 }, {
1895 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001896 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001897 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001898 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001899 }, {
1900 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001901 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001902 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001903 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001904 }, {
1905 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001906 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001907 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001908 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001909 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001910 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001911 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001912 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001913 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001914 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001915 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001916 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001917 inputText: `"9999-12-31T23:59:59-01:00"`,
1918 wantErr: true,
1919 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001920 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001921 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001922 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001923 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001924 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001925 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001926 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001927 inputText: `"0001-01-01T00:00:00+01:00"`,
1928 wantErr: true,
1929 }, {
1930 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001931 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001932 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1933 wantErr: true,
1934 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001935 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001936 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001937 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001938 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001939 }, {
1940 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001941 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001942 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001943 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001944 Paths: []string{
1945 "foo",
1946 "foo_bar",
1947 "foo.bar_qux",
1948 "_foo",
1949 },
1950 },
1951 }, {
1952 desc: "FieldMask field",
1953 inputMessage: &pb2.KnownTypes{},
1954 inputText: `{
1955 "optFieldmask": "foo, qux.fooBar"
1956}`,
1957 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001958 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001959 Paths: []string{
1960 "foo",
1961 "qux.foo_bar",
1962 },
1963 },
1964 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001965 }, {
1966 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001967 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001968 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001969 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001970 }, {
1971 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001972 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001973 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001974 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001975 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001976 inputText: `{
1977 "@type": "foo/pb2.Nested",
1978 "optString": "embedded inside Any",
1979 "optNested": {
1980 "optString": "inception"
1981 }
1982}`,
1983 wantMessage: func() proto.Message {
1984 m := &pb2.Nested{
1985 OptString: scalar.String("embedded inside Any"),
1986 OptNested: &pb2.Nested{
1987 OptString: scalar.String("inception"),
1988 },
1989 }
1990 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1991 if err != nil {
1992 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1993 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001994 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001995 TypeUrl: "foo/pb2.Nested",
1996 Value: b,
1997 }
1998 }(),
1999 }, {
2000 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07002001 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002002 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002003 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002004 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002005 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002006 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002007 }, {
2008 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002009 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002010 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002011 inputText: `{"@type": "foo/pb2.Nested"}`,
2012 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002013 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07002014 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07002015 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002016 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002017 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002018 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002019 inputText: `{
2020 "@type": "pb2.PartialRequired",
2021 "optString": "embedded inside Any"
2022}`,
2023 wantMessage: func() proto.Message {
2024 m := &pb2.PartialRequired{
2025 OptString: scalar.String("embedded inside Any"),
2026 }
Damien Neil96c229a2019-04-03 12:17:24 -07002027 b, err := proto.MarshalOptions{
2028 Deterministic: true,
2029 AllowPartial: true,
2030 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002031 if err != nil {
2032 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2033 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002034 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002035 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002036 Value: b,
2037 }
2038 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002039 }, {
2040 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07002041 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002042 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002043 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002044 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002045 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002046 inputText: `{
2047 "@type": "pb2.PartialRequired",
2048 "optString": "embedded inside Any"
2049}`,
2050 wantMessage: func() proto.Message {
2051 m := &pb2.PartialRequired{
2052 OptString: scalar.String("embedded inside Any"),
2053 }
Damien Neil96c229a2019-04-03 12:17:24 -07002054 b, err := proto.MarshalOptions{
2055 Deterministic: true,
2056 AllowPartial: true,
2057 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002058 if err != nil {
2059 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2060 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002061 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002062 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002063 Value: b,
2064 }
2065 }(),
2066 }, {
2067 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002068 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002069 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002070 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002071 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002072 inputText: `{
2073 "optString": "` + "abc\xff" + `",
2074 "@type": "foo/pb2.Nested"
2075}`,
2076 wantMessage: func() proto.Message {
2077 m := &pb2.Nested{
2078 OptString: scalar.String("abc\xff"),
2079 }
2080 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: "foo/pb2.Nested",
2086 Value: b,
2087 }
2088 }(),
2089 wantErr: true,
2090 }, {
2091 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002092 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002093 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002094 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002095 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002096 inputText: `{
2097 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2098 "value": true
2099}`,
2100 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002101 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002102 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2103 if err != nil {
2104 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2105 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002106 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002107 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2108 Value: b,
2109 }
2110 }(),
2111 }, {
2112 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002113 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002114 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002115 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002116 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002117 inputText: `{
2118 "value": {},
2119 "@type": "type.googleapis.com/google.protobuf.Empty"
2120}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002121 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002122 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2123 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002124 }, {
2125 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002126 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002127 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002128 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002129 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002130 inputText: `{
2131 "@type": "type.googleapis.com/google.protobuf.Empty"
2132}`,
2133 wantErr: true,
2134 }, {
2135 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002136 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002137 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002138 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002139 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002140 inputText: `{
2141 "@type": "google.protobuf.StringValue",
2142 "value": "` + "abc\xff" + `"
2143}`,
2144 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002145 m := &wrapperspb.StringValue{Value: "abcd"}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002146 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.StringValue",
Damien Neilbc310b52019-04-11 11:46:55 -07002152 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002153 }
2154 }(),
2155 wantErr: true,
2156 }, {
2157 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002158 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002159 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002160 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002161 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002162 inputText: `{
2163 "@type": "google.protobuf.Int64Value",
2164 "value": "42"
2165}`,
2166 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002167 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002168 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2169 if err != nil {
2170 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2171 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002172 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002173 TypeUrl: "google.protobuf.Int64Value",
2174 Value: b,
2175 }
2176 }(),
2177 }, {
2178 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002179 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002180 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002181 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002182 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002183 inputText: `{
2184 "@type": "google.protobuf.Int64Value",
2185 "value": "forty-two"
2186}`,
2187 wantErr: true,
2188 }, {
2189 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002190 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002191 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002192 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002193 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002194 inputText: `{
2195 "@type": "google.protobuf.UInt64Value",
2196 "value": -42
2197}`,
2198 wantErr: true,
2199 }, {
2200 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002201 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002202 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002203 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002204 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002205 inputText: `{
2206 "@type": "type.googleapis.com/google.protobuf.Duration",
2207 "value": "0s"
2208}`,
2209 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002210 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002211 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2212 if err != nil {
2213 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2214 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002215 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002216 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2217 Value: b,
2218 }
2219 }(),
2220 }, {
2221 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002222 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002223 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002224 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002225 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002226 inputText: `{
2227 "@type": "google.protobuf.Value",
2228 "value": "` + "abc\xff" + `"
2229}`,
2230 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002231 m := &structpb.Value{Kind: &structpb.Value_StringValue{"abcd"}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002232 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2233 if err != nil {
2234 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2235 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002236 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002237 TypeUrl: "google.protobuf.Value",
Damien Neilbc310b52019-04-11 11:46:55 -07002238 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002239 }
2240 }(),
2241 wantErr: true,
2242 }, {
2243 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002244 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002245 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002246 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002247 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002248 inputText: `{
2249 "@type": "google.protobuf.Value",
2250 "value": null
2251}`,
2252 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002253 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002254 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2255 if err != nil {
2256 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2257 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002258 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002259 TypeUrl: "google.protobuf.Value",
2260 Value: b,
2261 }
2262 }(),
2263 }, {
2264 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002265 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002266 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002267 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2268 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2269 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2270 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2271 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002272 ),
2273 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002274 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002275 inputText: `{
2276 "@type": "google.protobuf.Struct",
2277 "value": {
2278 "bool": true,
2279 "null": null,
2280 "string": "hello",
2281 "struct": {
2282 "string": "world"
2283 }
2284 }
2285}`,
2286 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002287 m := &structpb.Struct{
2288 Fields: map[string]*structpb.Value{
2289 "bool": {Kind: &structpb.Value_BoolValue{true}},
2290 "null": {Kind: &structpb.Value_NullValue{}},
2291 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002292 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002293 Kind: &structpb.Value_StructValue{
2294 &structpb.Struct{
2295 Fields: map[string]*structpb.Value{
2296 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002297 },
2298 },
2299 },
2300 },
2301 },
2302 }
2303 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2304 if err != nil {
2305 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2306 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002307 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002308 TypeUrl: "google.protobuf.Struct",
2309 Value: b,
2310 }
2311 }(),
2312 }, {
2313 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002314 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002315 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002316 inputText: `{
2317 "value": {}
2318}`,
2319 wantErr: true,
2320 }, {
2321 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002322 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002323 inputText: `{
2324 "@type": ""
2325}`,
2326 wantErr: true,
2327 }, {
2328 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002329 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002330 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002331 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002332 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002333 ),
2334 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002335 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002336 inputText: `{
2337 "@type": "google.protobuf.StringValue",
2338 "value": "hello",
2339 "@type": "pb2.Nested"
2340}`,
2341 wantErr: true,
2342 }, {
2343 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002344 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002345 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002346 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002347 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002348 inputText: `{
2349 "@type": "google.protobuf.StringValue",
2350 "value": "hello",
2351 "value": "world"
2352}`,
2353 wantErr: true,
2354 }, {
2355 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002356 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002357 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002358 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002359 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002360 inputText: `{
2361 "@type": "pb2.Nested",
2362 "optString": "hello",
2363 "unknown": "world"
2364}`,
2365 wantErr: true,
2366 }, {
2367 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002368 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002369 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002370 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002371 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2372 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002373 ),
2374 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002375 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002376 inputText: `{
2377 "@type": "pb2.KnownTypes",
2378 "optAny": {
2379 "@type": "google.protobuf.StringValue",
2380 "value": "` + "abc\xff" + `"
2381 }
2382}`,
2383 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002384 m1 := &wrapperspb.StringValue{Value: "abcd"}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002385 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
2386 if err != nil {
2387 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2388 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002389 m2 := &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002390 TypeUrl: "google.protobuf.StringValue",
2391 Value: b,
2392 }
2393 m3 := &pb2.KnownTypes{OptAny: m2}
2394 b, err = proto.MarshalOptions{Deterministic: true}.Marshal(m3)
2395 if err != nil {
2396 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2397 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002398 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002399 TypeUrl: "pb2.KnownTypes",
Damien Neilbc310b52019-04-11 11:46:55 -07002400 Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002401 }
2402 }(),
2403 wantErr: true,
2404 }, {
2405 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002406 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002407 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002408 },
2409 inputMessage: &pb2.KnownTypes{},
2410 inputText: `{
2411 "optBool": false,
2412 "optInt32": 42,
2413 "optInt64": "42",
2414 "optUint32": 42,
2415 "optUint64": "42",
2416 "optFloat": 1.23,
2417 "optDouble": 3.1415,
2418 "optString": "hello",
2419 "optBytes": "aGVsbG8=",
2420 "optDuration": "123s",
2421 "optTimestamp": "2019-03-19T23:03:21Z",
2422 "optStruct": {
2423 "string": "hello"
2424 },
2425 "optList": [
2426 null,
2427 "",
2428 {},
2429 []
2430 ],
2431 "optValue": "world",
2432 "optEmpty": {},
2433 "optAny": {
2434 "@type": "google.protobuf.Empty",
2435 "value": {}
2436 },
2437 "optFieldmask": "fooBar,barFoo"
2438}`,
2439 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002440 OptBool: &wrapperspb.BoolValue{Value: false},
2441 OptInt32: &wrapperspb.Int32Value{Value: 42},
2442 OptInt64: &wrapperspb.Int64Value{Value: 42},
2443 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2444 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2445 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2446 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2447 OptString: &wrapperspb.StringValue{Value: "hello"},
2448 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2449 OptDuration: &durationpb.Duration{Seconds: 123},
2450 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2451 OptStruct: &structpb.Struct{
2452 Fields: map[string]*structpb.Value{
2453 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002454 },
2455 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002456 OptList: &structpb.ListValue{
2457 Values: []*structpb.Value{
2458 {Kind: &structpb.Value_NullValue{}},
2459 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002460 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002461 Kind: &structpb.Value_StructValue{
2462 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002463 },
2464 },
2465 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002466 Kind: &structpb.Value_ListValue{
2467 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002468 },
2469 },
2470 },
2471 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002472 OptValue: &structpb.Value{
2473 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002474 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002475 OptEmpty: &emptypb.Empty{},
2476 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002477 TypeUrl: "google.protobuf.Empty",
2478 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002479 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002480 Paths: []string{"foo_bar", "bar_foo"},
2481 },
2482 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002483 }, {
2484 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002485 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002486 inputMessage: &pb3.Nests{},
2487 inputText: `{
2488 "sNested": {
2489 "unknown": {
2490 "foo": 1,
2491 "bar": [1, 2, 3]
2492 }
2493 },
2494 "unknown": "not known"
2495}`,
2496 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2497 }, {
2498 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002499 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002500 inputMessage: &pb2.Nests{},
2501 inputText: `{
2502 "rptNested": [
2503 {"unknown": "blah"},
2504 {"optString": "hello"}
2505 ]
2506}`,
2507 wantMessage: &pb2.Nests{
2508 RptNested: []*pb2.Nested{
2509 {},
2510 {OptString: scalar.String("hello")},
2511 },
2512 },
2513 }, {
2514 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002515 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002516 inputMessage: &pb3.Maps{},
2517 inputText: `{
2518 "strToNested": {
2519 "nested_one": {
2520 "unknown": "what you see is not"
2521 }
2522 }
2523}`,
2524 wantMessage: &pb3.Maps{
2525 StrToNested: map[string]*pb3.Nested{
2526 "nested_one": {},
2527 },
2528 },
2529 }, {
2530 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002531 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002532 inputMessage: &pb2.Extensions{},
2533 inputText: `{
2534 "[pb2.opt_ext_nested]": {
2535 "unknown": []
2536 }
2537}`,
2538 wantMessage: func() proto.Message {
2539 m := &pb2.Extensions{}
2540 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2541 return m
2542 }(),
2543 }, {
2544 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002545 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002546 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002547 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002548 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002549 }, {
2550 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002551 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002552 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002553 inputText: `{
2554 "value": {"foo": "bar"},
2555 "unknown": true
2556}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002557 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002558 }, {
2559 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002560 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002561 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002562 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002563 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002564 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002565 inputText: `{
2566 "@type": "foo/pb2.Nested",
2567 "unknown": "none"
2568}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002569 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002570 TypeUrl: "foo/pb2.Nested",
2571 },
2572 }, {
2573 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002574 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002575 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002576 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002577 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002578 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002579 inputText: `{
2580 "@type": "type.googleapis.com/google.protobuf.Empty",
2581 "value": {"unknown": 47}
2582}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002583 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002584 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2585 },
Herbie Ongc96a79d2019-03-08 10:49:17 -08002586 }}
2587
2588 for _, tt := range tests {
2589 tt := tt
2590 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002591 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002592 if err != nil && !tt.wantErr {
2593 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2594 }
2595 if err == nil && tt.wantErr {
2596 t.Error("Unmarshal() got nil error, want error\n\n")
2597 }
2598 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
2599 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2600 }
2601 })
2602 }
2603}