blob: 00b1a546525a6c7eb35ddcb0ae5386668fe7cefc [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package protojson_test
Herbie Ongc96a79d2019-03-08 10:49:17 -08006
7import (
8 "math"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
Damien Neile89e6242019-05-13 23:55:40 -070012 "google.golang.org/protobuf/encoding/testprotos/pb2"
13 "google.golang.org/protobuf/encoding/testprotos/pb3"
14 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070015 "google.golang.org/protobuf/proto"
16 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Onge63c4c42019-03-22 22:20:22 -070017
Joe Tsaia95b29f2019-05-16 12:47:20 -070018 "google.golang.org/protobuf/types/known/anypb"
19 "google.golang.org/protobuf/types/known/durationpb"
20 "google.golang.org/protobuf/types/known/emptypb"
21 "google.golang.org/protobuf/types/known/fieldmaskpb"
22 "google.golang.org/protobuf/types/known/structpb"
23 "google.golang.org/protobuf/types/known/timestamppb"
24 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080025)
26
27func TestUnmarshal(t *testing.T) {
28 tests := []struct {
29 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070030 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080031 inputMessage proto.Message
32 inputText string
33 wantMessage proto.Message
34 // TODO: verify expected error message substring.
35 wantErr bool
36 }{{
37 desc: "proto2 empty message",
38 inputMessage: &pb2.Scalars{},
39 inputText: "{}",
40 wantMessage: &pb2.Scalars{},
41 }, {
42 desc: "unexpected value instead of EOF",
43 inputMessage: &pb2.Scalars{},
44 inputText: "{} {}",
45 wantErr: true,
46 }, {
47 desc: "proto2 optional scalars set to zero values",
48 inputMessage: &pb2.Scalars{},
49 inputText: `{
50 "optBool": false,
51 "optInt32": 0,
52 "optInt64": 0,
53 "optUint32": 0,
54 "optUint64": 0,
55 "optSint32": 0,
56 "optSint64": 0,
57 "optFixed32": 0,
58 "optFixed64": 0,
59 "optSfixed32": 0,
60 "optSfixed64": 0,
61 "optFloat": 0,
62 "optDouble": 0,
63 "optBytes": "",
64 "optString": ""
65}`,
66 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070067 OptBool: proto.Bool(false),
68 OptInt32: proto.Int32(0),
69 OptInt64: proto.Int64(0),
70 OptUint32: proto.Uint32(0),
71 OptUint64: proto.Uint64(0),
72 OptSint32: proto.Int32(0),
73 OptSint64: proto.Int64(0),
74 OptFixed32: proto.Uint32(0),
75 OptFixed64: proto.Uint64(0),
76 OptSfixed32: proto.Int32(0),
77 OptSfixed64: proto.Int64(0),
78 OptFloat: proto.Float32(0),
79 OptDouble: proto.Float64(0),
Herbie Ongc96a79d2019-03-08 10:49:17 -080080 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070081 OptString: proto.String(""),
Herbie Ongc96a79d2019-03-08 10:49:17 -080082 },
83 }, {
84 desc: "proto3 scalars set to zero values",
85 inputMessage: &pb3.Scalars{},
86 inputText: `{
87 "sBool": false,
88 "sInt32": 0,
89 "sInt64": 0,
90 "sUint32": 0,
91 "sUint64": 0,
92 "sSint32": 0,
93 "sSint64": 0,
94 "sFixed32": 0,
95 "sFixed64": 0,
96 "sSfixed32": 0,
97 "sSfixed64": 0,
98 "sFloat": 0,
99 "sDouble": 0,
100 "sBytes": "",
101 "sString": ""
102}`,
103 wantMessage: &pb3.Scalars{},
104 }, {
105 desc: "proto2 optional scalars set to null",
106 inputMessage: &pb2.Scalars{},
107 inputText: `{
108 "optBool": null,
109 "optInt32": null,
110 "optInt64": null,
111 "optUint32": null,
112 "optUint64": null,
113 "optSint32": null,
114 "optSint64": null,
115 "optFixed32": null,
116 "optFixed64": null,
117 "optSfixed32": null,
118 "optSfixed64": null,
119 "optFloat": null,
120 "optDouble": null,
121 "optBytes": null,
122 "optString": null
123}`,
124 wantMessage: &pb2.Scalars{},
125 }, {
126 desc: "proto3 scalars set to null",
127 inputMessage: &pb3.Scalars{},
128 inputText: `{
129 "sBool": null,
130 "sInt32": null,
131 "sInt64": null,
132 "sUint32": null,
133 "sUint64": null,
134 "sSint32": null,
135 "sSint64": null,
136 "sFixed32": null,
137 "sFixed64": null,
138 "sSfixed32": null,
139 "sSfixed64": null,
140 "sFloat": null,
141 "sDouble": null,
142 "sBytes": null,
143 "sString": null
144}`,
145 wantMessage: &pb3.Scalars{},
146 }, {
147 desc: "boolean",
148 inputMessage: &pb3.Scalars{},
149 inputText: `{"sBool": true}`,
150 wantMessage: &pb3.Scalars{
151 SBool: true,
152 },
153 }, {
154 desc: "not boolean",
155 inputMessage: &pb3.Scalars{},
156 inputText: `{"sBool": "true"}`,
157 wantErr: true,
158 }, {
159 desc: "float and double",
160 inputMessage: &pb3.Scalars{},
161 inputText: `{
162 "sFloat": 1.234,
163 "sDouble": 5.678
164}`,
165 wantMessage: &pb3.Scalars{
166 SFloat: 1.234,
167 SDouble: 5.678,
168 },
169 }, {
170 desc: "float and double in string",
171 inputMessage: &pb3.Scalars{},
172 inputText: `{
173 "sFloat": "1.234",
174 "sDouble": "5.678"
175}`,
176 wantMessage: &pb3.Scalars{
177 SFloat: 1.234,
178 SDouble: 5.678,
179 },
180 }, {
181 desc: "float and double in E notation",
182 inputMessage: &pb3.Scalars{},
183 inputText: `{
184 "sFloat": 12.34E-1,
185 "sDouble": 5.678e4
186}`,
187 wantMessage: &pb3.Scalars{
188 SFloat: 1.234,
189 SDouble: 56780,
190 },
191 }, {
192 desc: "float and double in string E notation",
193 inputMessage: &pb3.Scalars{},
194 inputText: `{
195 "sFloat": "12.34E-1",
196 "sDouble": "5.678e4"
197}`,
198 wantMessage: &pb3.Scalars{
199 SFloat: 1.234,
200 SDouble: 56780,
201 },
202 }, {
203 desc: "float exceeds limit",
204 inputMessage: &pb3.Scalars{},
205 inputText: `{"sFloat": 3.4e39}`,
206 wantErr: true,
207 }, {
208 desc: "float in string exceeds limit",
209 inputMessage: &pb3.Scalars{},
210 inputText: `{"sFloat": "-3.4e39"}`,
211 wantErr: true,
212 }, {
213 desc: "double exceeds limit",
214 inputMessage: &pb3.Scalars{},
215 inputText: `{"sFloat": -1.79e+309}`,
216 wantErr: true,
217 }, {
218 desc: "double in string exceeds limit",
219 inputMessage: &pb3.Scalars{},
220 inputText: `{"sFloat": "1.79e+309"}`,
221 wantErr: true,
222 }, {
223 desc: "infinites",
224 inputMessage: &pb3.Scalars{},
225 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
226 wantMessage: &pb3.Scalars{
227 SFloat: float32(math.Inf(+1)),
228 SDouble: math.Inf(-1),
229 },
230 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700231 desc: "float string with leading space",
232 inputMessage: &pb3.Scalars{},
233 inputText: `{"sFloat": " 1.234"}`,
234 wantErr: true,
235 }, {
236 desc: "double string with trailing space",
237 inputMessage: &pb3.Scalars{},
238 inputText: `{"sDouble": "5.678 "}`,
239 wantErr: true,
240 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800241 desc: "not float",
242 inputMessage: &pb3.Scalars{},
243 inputText: `{"sFloat": true}`,
244 wantErr: true,
245 }, {
246 desc: "not double",
247 inputMessage: &pb3.Scalars{},
248 inputText: `{"sDouble": "not a number"}`,
249 wantErr: true,
250 }, {
251 desc: "integers",
252 inputMessage: &pb3.Scalars{},
253 inputText: `{
254 "sInt32": 1234,
255 "sInt64": -1234,
256 "sUint32": 1e2,
257 "sUint64": 100E-2,
258 "sSint32": 1.0,
259 "sSint64": -1.0,
260 "sFixed32": 1.234e+5,
261 "sFixed64": 1200E-2,
262 "sSfixed32": -1.234e05,
263 "sSfixed64": -1200e-02
264}`,
265 wantMessage: &pb3.Scalars{
266 SInt32: 1234,
267 SInt64: -1234,
268 SUint32: 100,
269 SUint64: 1,
270 SSint32: 1,
271 SSint64: -1,
272 SFixed32: 123400,
273 SFixed64: 12,
274 SSfixed32: -123400,
275 SSfixed64: -12,
276 },
277 }, {
278 desc: "integers in string",
279 inputMessage: &pb3.Scalars{},
280 inputText: `{
281 "sInt32": "1234",
282 "sInt64": "-1234",
283 "sUint32": "1e2",
284 "sUint64": "100E-2",
285 "sSint32": "1.0",
286 "sSint64": "-1.0",
287 "sFixed32": "1.234e+5",
288 "sFixed64": "1200E-2",
289 "sSfixed32": "-1.234e05",
290 "sSfixed64": "-1200e-02"
291}`,
292 wantMessage: &pb3.Scalars{
293 SInt32: 1234,
294 SInt64: -1234,
295 SUint32: 100,
296 SUint64: 1,
297 SSint32: 1,
298 SSint64: -1,
299 SFixed32: 123400,
300 SFixed64: 12,
301 SSfixed32: -123400,
302 SSfixed64: -12,
303 },
304 }, {
305 desc: "integers in escaped string",
306 inputMessage: &pb3.Scalars{},
307 inputText: `{"sInt32": "\u0031\u0032"}`,
308 wantMessage: &pb3.Scalars{
309 SInt32: 12,
310 },
311 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700312 desc: "integer string with leading space",
313 inputMessage: &pb3.Scalars{},
314 inputText: `{"sInt32": " 1234"}`,
315 wantErr: true,
316 }, {
317 desc: "integer string with trailing space",
318 inputMessage: &pb3.Scalars{},
319 inputText: `{"sUint32": "1e2 "}`,
320 wantErr: true,
321 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800322 desc: "number is not an integer",
323 inputMessage: &pb3.Scalars{},
324 inputText: `{"sInt32": 1.001}`,
325 wantErr: true,
326 }, {
327 desc: "32-bit int exceeds limit",
328 inputMessage: &pb3.Scalars{},
329 inputText: `{"sInt32": 2e10}`,
330 wantErr: true,
331 }, {
332 desc: "64-bit int exceeds limit",
333 inputMessage: &pb3.Scalars{},
334 inputText: `{"sSfixed64": -9e19}`,
335 wantErr: true,
336 }, {
337 desc: "not integer",
338 inputMessage: &pb3.Scalars{},
339 inputText: `{"sInt32": "not a number"}`,
340 wantErr: true,
341 }, {
342 desc: "not unsigned integer",
343 inputMessage: &pb3.Scalars{},
344 inputText: `{"sUint32": "not a number"}`,
345 wantErr: true,
346 }, {
347 desc: "number is not an unsigned integer",
348 inputMessage: &pb3.Scalars{},
349 inputText: `{"sUint32": -1}`,
350 wantErr: true,
351 }, {
352 desc: "string",
353 inputMessage: &pb2.Scalars{},
354 inputText: `{"optString": "谷歌"}`,
355 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700356 OptString: proto.String("谷歌"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800357 },
358 }, {
359 desc: "string with invalid UTF-8",
360 inputMessage: &pb3.Scalars{},
361 inputText: "{\"sString\": \"\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700362 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800363 }, {
364 desc: "not string",
365 inputMessage: &pb2.Scalars{},
366 inputText: `{"optString": 42}`,
367 wantErr: true,
368 }, {
369 desc: "bytes",
370 inputMessage: &pb3.Scalars{},
371 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
372 wantMessage: &pb3.Scalars{
373 SBytes: []byte("hello world"),
374 },
375 }, {
376 desc: "bytes padded",
377 inputMessage: &pb3.Scalars{},
378 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
379 wantMessage: &pb3.Scalars{
380 SBytes: []byte("hello world"),
381 },
382 }, {
383 desc: "not bytes",
384 inputMessage: &pb3.Scalars{},
385 inputText: `{"sBytes": true}`,
386 wantErr: true,
387 }, {
388 desc: "proto2 enum",
389 inputMessage: &pb2.Enums{},
390 inputText: `{
391 "optEnum": "ONE",
392 "optNestedEnum": "UNO"
393}`,
394 wantMessage: &pb2.Enums{
395 OptEnum: pb2.Enum_ONE.Enum(),
396 OptNestedEnum: pb2.Enums_UNO.Enum(),
397 },
398 }, {
399 desc: "proto3 enum",
400 inputMessage: &pb3.Enums{},
401 inputText: `{
402 "sEnum": "ONE",
403 "sNestedEnum": "DIEZ"
404}`,
405 wantMessage: &pb3.Enums{
406 SEnum: pb3.Enum_ONE,
407 SNestedEnum: pb3.Enums_DIEZ,
408 },
409 }, {
410 desc: "enum numeric value",
411 inputMessage: &pb3.Enums{},
412 inputText: `{
413 "sEnum": 2,
414 "sNestedEnum": 2
415}`,
416 wantMessage: &pb3.Enums{
417 SEnum: pb3.Enum_TWO,
418 SNestedEnum: pb3.Enums_DOS,
419 },
420 }, {
421 desc: "enum unnamed numeric value",
422 inputMessage: &pb3.Enums{},
423 inputText: `{
424 "sEnum": 101,
425 "sNestedEnum": -101
426}`,
427 wantMessage: &pb3.Enums{
428 SEnum: 101,
429 SNestedEnum: -101,
430 },
431 }, {
432 desc: "enum set to number string",
433 inputMessage: &pb3.Enums{},
434 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700435 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800436}`,
437 wantErr: true,
438 }, {
439 desc: "enum set to invalid named",
440 inputMessage: &pb3.Enums{},
441 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700442 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800443}`,
444 wantErr: true,
445 }, {
446 desc: "enum set to not enum",
447 inputMessage: &pb3.Enums{},
448 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700449 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800450}`,
451 wantErr: true,
452 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700453 desc: "enum set to JSON null",
454 inputMessage: &pb3.Enums{},
455 inputText: `{
456 "sEnum": null
457}`,
458 wantMessage: &pb3.Enums{},
459 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800460 desc: "proto name",
461 inputMessage: &pb3.JSONNames{},
462 inputText: `{
463 "s_string": "proto name used"
464}`,
465 wantMessage: &pb3.JSONNames{
466 SString: "proto name used",
467 },
468 }, {
469 desc: "json_name",
470 inputMessage: &pb3.JSONNames{},
471 inputText: `{
472 "foo_bar": "json_name used"
473}`,
474 wantMessage: &pb3.JSONNames{
475 SString: "json_name used",
476 },
477 }, {
478 desc: "camelCase name",
479 inputMessage: &pb3.JSONNames{},
480 inputText: `{
481 "sString": "camelcase used"
482}`,
483 wantErr: true,
484 }, {
485 desc: "proto name and json_name",
486 inputMessage: &pb3.JSONNames{},
487 inputText: `{
488 "foo_bar": "json_name used",
489 "s_string": "proto name used"
490}`,
491 wantErr: true,
492 }, {
493 desc: "duplicate field names",
494 inputMessage: &pb3.JSONNames{},
495 inputText: `{
496 "foo_bar": "one",
497 "foo_bar": "two",
498}`,
499 wantErr: true,
500 }, {
501 desc: "null message",
502 inputMessage: &pb2.Nests{},
503 inputText: "null",
504 wantErr: true,
505 }, {
506 desc: "proto2 nested message not set",
507 inputMessage: &pb2.Nests{},
508 inputText: "{}",
509 wantMessage: &pb2.Nests{},
510 }, {
511 desc: "proto2 nested message set to null",
512 inputMessage: &pb2.Nests{},
513 inputText: `{
514 "optNested": null,
515 "optgroup": null
516}`,
517 wantMessage: &pb2.Nests{},
518 }, {
519 desc: "proto2 nested message set to empty",
520 inputMessage: &pb2.Nests{},
521 inputText: `{
522 "optNested": {},
523 "optgroup": {}
524}`,
525 wantMessage: &pb2.Nests{
526 OptNested: &pb2.Nested{},
527 Optgroup: &pb2.Nests_OptGroup{},
528 },
529 }, {
530 desc: "proto2 nested messages",
531 inputMessage: &pb2.Nests{},
532 inputText: `{
533 "optNested": {
534 "optString": "nested message",
535 "optNested": {
536 "optString": "another nested message"
537 }
538 }
539}`,
540 wantMessage: &pb2.Nests{
541 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700542 OptString: proto.String("nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800543 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700544 OptString: proto.String("another nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800545 },
546 },
547 },
548 }, {
549 desc: "proto2 groups",
550 inputMessage: &pb2.Nests{},
551 inputText: `{
552 "optgroup": {
553 "optString": "inside a group",
554 "optNested": {
555 "optString": "nested message inside a group"
556 },
557 "optnestedgroup": {
558 "optFixed32": 47
559 }
560 }
561}`,
562 wantMessage: &pb2.Nests{
563 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700564 OptString: proto.String("inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800565 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700566 OptString: proto.String("nested message inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800567 },
568 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700569 OptFixed32: proto.Uint32(47),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800570 },
571 },
572 },
573 }, {
574 desc: "proto3 nested message not set",
575 inputMessage: &pb3.Nests{},
576 inputText: "{}",
577 wantMessage: &pb3.Nests{},
578 }, {
579 desc: "proto3 nested message set to null",
580 inputMessage: &pb3.Nests{},
581 inputText: `{"sNested": null}`,
582 wantMessage: &pb3.Nests{},
583 }, {
584 desc: "proto3 nested message set to empty",
585 inputMessage: &pb3.Nests{},
586 inputText: `{"sNested": {}}`,
587 wantMessage: &pb3.Nests{
588 SNested: &pb3.Nested{},
589 },
590 }, {
591 desc: "proto3 nested message",
592 inputMessage: &pb3.Nests{},
593 inputText: `{
594 "sNested": {
595 "sString": "nested message",
596 "sNested": {
597 "sString": "another nested message"
598 }
599 }
600}`,
601 wantMessage: &pb3.Nests{
602 SNested: &pb3.Nested{
603 SString: "nested message",
604 SNested: &pb3.Nested{
605 SString: "another nested message",
606 },
607 },
608 },
609 }, {
610 desc: "message set to non-message",
611 inputMessage: &pb3.Nests{},
612 inputText: `"not valid"`,
613 wantErr: true,
614 }, {
615 desc: "nested message set to non-message",
616 inputMessage: &pb3.Nests{},
617 inputText: `{"sNested": true}`,
618 wantErr: true,
619 }, {
620 desc: "oneof not set",
621 inputMessage: &pb3.Oneofs{},
622 inputText: "{}",
623 wantMessage: &pb3.Oneofs{},
624 }, {
625 desc: "oneof set to empty string",
626 inputMessage: &pb3.Oneofs{},
627 inputText: `{"oneofString": ""}`,
628 wantMessage: &pb3.Oneofs{
629 Union: &pb3.Oneofs_OneofString{},
630 },
631 }, {
632 desc: "oneof set to string",
633 inputMessage: &pb3.Oneofs{},
634 inputText: `{"oneofString": "hello"}`,
635 wantMessage: &pb3.Oneofs{
636 Union: &pb3.Oneofs_OneofString{
637 OneofString: "hello",
638 },
639 },
640 }, {
641 desc: "oneof set to enum",
642 inputMessage: &pb3.Oneofs{},
643 inputText: `{"oneofEnum": "ZERO"}`,
644 wantMessage: &pb3.Oneofs{
645 Union: &pb3.Oneofs_OneofEnum{
646 OneofEnum: pb3.Enum_ZERO,
647 },
648 },
649 }, {
650 desc: "oneof set to empty message",
651 inputMessage: &pb3.Oneofs{},
652 inputText: `{"oneofNested": {}}`,
653 wantMessage: &pb3.Oneofs{
654 Union: &pb3.Oneofs_OneofNested{
655 OneofNested: &pb3.Nested{},
656 },
657 },
658 }, {
659 desc: "oneof set to message",
660 inputMessage: &pb3.Oneofs{},
661 inputText: `{
662 "oneofNested": {
663 "sString": "nested message"
664 }
665}`,
666 wantMessage: &pb3.Oneofs{
667 Union: &pb3.Oneofs_OneofNested{
668 OneofNested: &pb3.Nested{
669 SString: "nested message",
670 },
671 },
672 },
673 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700674 desc: "oneof set to more than one field",
675 inputMessage: &pb3.Oneofs{},
676 inputText: `{
677 "oneofEnum": "ZERO",
678 "oneofString": "hello"
679}`,
680 wantErr: true,
681 }, {
682 desc: "oneof set to null and value",
683 inputMessage: &pb3.Oneofs{},
684 inputText: `{
685 "oneofEnum": "ZERO",
686 "oneofString": null
687}`,
688 wantMessage: &pb3.Oneofs{
689 Union: &pb3.Oneofs_OneofEnum{
690 OneofEnum: pb3.Enum_ZERO,
691 },
692 },
693 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800694 desc: "repeated null fields",
695 inputMessage: &pb2.Repeats{},
696 inputText: `{
697 "rptString": null,
698 "rptInt32" : null,
699 "rptFloat" : null,
700 "rptBytes" : null
701}`,
702 wantMessage: &pb2.Repeats{},
703 }, {
704 desc: "repeated scalars",
705 inputMessage: &pb2.Repeats{},
706 inputText: `{
707 "rptString": ["hello", "world"],
708 "rptInt32" : [-1, 0, 1],
709 "rptBool" : [false, true]
710}`,
711 wantMessage: &pb2.Repeats{
712 RptString: []string{"hello", "world"},
713 RptInt32: []int32{-1, 0, 1},
714 RptBool: []bool{false, true},
715 },
716 }, {
717 desc: "repeated enums",
718 inputMessage: &pb2.Enums{},
719 inputText: `{
720 "rptEnum" : ["TEN", 1, 42],
721 "rptNestedEnum": ["DOS", 2, -47]
722}`,
723 wantMessage: &pb2.Enums{
724 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
725 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
726 },
727 }, {
728 desc: "repeated messages",
729 inputMessage: &pb2.Nests{},
730 inputText: `{
731 "rptNested": [
732 {
733 "optString": "repeat nested one"
734 },
735 {
736 "optString": "repeat nested two",
737 "optNested": {
738 "optString": "inside repeat nested two"
739 }
740 },
741 {}
742 ]
743}`,
744 wantMessage: &pb2.Nests{
745 RptNested: []*pb2.Nested{
746 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700747 OptString: proto.String("repeat nested one"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800748 },
749 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700750 OptString: proto.String("repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800751 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700752 OptString: proto.String("inside repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800753 },
754 },
755 {},
756 },
757 },
758 }, {
759 desc: "repeated groups",
760 inputMessage: &pb2.Nests{},
761 inputText: `{
762 "rptgroup": [
763 {
764 "rptString": ["hello", "world"]
765 },
766 {}
767 ]
768}
769`,
770 wantMessage: &pb2.Nests{
771 Rptgroup: []*pb2.Nests_RptGroup{
772 {
773 RptString: []string{"hello", "world"},
774 },
775 {},
776 },
777 },
778 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700779 desc: "repeated string contains invalid UTF8",
780 inputMessage: &pb2.Repeats{},
781 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700782 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700783 }, {
784 desc: "repeated messages contain invalid UTF8",
785 inputMessage: &pb2.Nests{},
786 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700787 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700788 }, {
789 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800790 inputMessage: &pb2.Repeats{},
791 inputText: `{"rptString": ["hello", null, "world"]}`,
792 wantErr: true,
793 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700794 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800795 inputMessage: &pb2.Nests{},
796 inputText: `{"rptNested": [{}, null]}`,
797 wantErr: true,
798 }, {
799 desc: "map fields 1",
800 inputMessage: &pb3.Maps{},
801 inputText: `{
802 "int32ToStr": {
803 "-101": "-101",
804 "0" : "zero",
805 "255" : "0xff"
806 },
807 "boolToUint32": {
808 "false": 101,
809 "true" : "42"
810 }
811}`,
812 wantMessage: &pb3.Maps{
813 Int32ToStr: map[int32]string{
814 -101: "-101",
815 0xff: "0xff",
816 0: "zero",
817 },
818 BoolToUint32: map[bool]uint32{
819 true: 42,
820 false: 101,
821 },
822 },
823 }, {
824 desc: "map fields 2",
825 inputMessage: &pb3.Maps{},
826 inputText: `{
827 "uint64ToEnum": {
828 "1" : "ONE",
829 "2" : 2,
830 "10": 101
831 }
832}`,
833 wantMessage: &pb3.Maps{
834 Uint64ToEnum: map[uint64]pb3.Enum{
835 1: pb3.Enum_ONE,
836 2: pb3.Enum_TWO,
837 10: 101,
838 },
839 },
840 }, {
841 desc: "map fields 3",
842 inputMessage: &pb3.Maps{},
843 inputText: `{
844 "strToNested": {
845 "nested_one": {
846 "sString": "nested in a map"
847 },
848 "nested_two": {}
849 }
850}`,
851 wantMessage: &pb3.Maps{
852 StrToNested: map[string]*pb3.Nested{
853 "nested_one": {
854 SString: "nested in a map",
855 },
856 "nested_two": {},
857 },
858 },
859 }, {
860 desc: "map fields 4",
861 inputMessage: &pb3.Maps{},
862 inputText: `{
863 "strToOneofs": {
864 "nested": {
865 "oneofNested": {
866 "sString": "nested oneof in map field value"
867 }
868 },
869 "string": {
870 "oneofString": "hello"
871 }
872 }
873}`,
874 wantMessage: &pb3.Maps{
875 StrToOneofs: map[string]*pb3.Oneofs{
876 "string": {
877 Union: &pb3.Oneofs_OneofString{
878 OneofString: "hello",
879 },
880 },
881 "nested": {
882 Union: &pb3.Oneofs_OneofNested{
883 OneofNested: &pb3.Nested{
884 SString: "nested oneof in map field value",
885 },
886 },
887 },
888 },
889 },
890 }, {
891 desc: "map contains duplicate keys",
892 inputMessage: &pb3.Maps{},
893 inputText: `{
894 "int32ToStr": {
895 "0": "cero",
896 "0": "zero"
897 }
898}
899`,
900 wantErr: true,
901 }, {
902 desc: "map key empty string",
903 inputMessage: &pb3.Maps{},
904 inputText: `{
905 "strToNested": {
906 "": {}
907 }
908}`,
909 wantMessage: &pb3.Maps{
910 StrToNested: map[string]*pb3.Nested{
911 "": {},
912 },
913 },
914 }, {
915 desc: "map contains invalid key 1",
916 inputMessage: &pb3.Maps{},
917 inputText: `{
918 "int32ToStr": {
919 "invalid": "cero"
920}`,
921 wantErr: true,
922 }, {
923 desc: "map contains invalid key 2",
924 inputMessage: &pb3.Maps{},
925 inputText: `{
926 "int32ToStr": {
927 "1.02": "float"
928}`,
929 wantErr: true,
930 }, {
931 desc: "map contains invalid key 3",
932 inputMessage: &pb3.Maps{},
933 inputText: `{
934 "int32ToStr": {
935 "2147483648": "exceeds 32-bit integer max limit"
936}`,
937 wantErr: true,
938 }, {
939 desc: "map contains invalid key 4",
940 inputMessage: &pb3.Maps{},
941 inputText: `{
942 "uint64ToEnum": {
943 "-1": 0
944 }
945}`,
946 wantErr: true,
947 }, {
948 desc: "map contains invalid value",
949 inputMessage: &pb3.Maps{},
950 inputText: `{
951 "int32ToStr": {
952 "101": true
953}`,
954 wantErr: true,
955 }, {
956 desc: "map contains null for scalar value",
957 inputMessage: &pb3.Maps{},
958 inputText: `{
959 "int32ToStr": {
960 "101": null
961}`,
962 wantErr: true,
963 }, {
964 desc: "map contains null for message value",
965 inputMessage: &pb3.Maps{},
966 inputText: `{
967 "strToNested": {
968 "hello": null
969 }
970}`,
971 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -0700972 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700973 desc: "map contains contains message value with invalid UTF8",
974 inputMessage: &pb3.Maps{},
975 inputText: `{
976 "strToNested": {
977 "hello": {
978 "sString": "` + "abc\xff" + `"
979 }
980 }
981}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700982 wantErr: true,
983 }, {
984 desc: "map key contains invalid UTF8",
985 inputMessage: &pb3.Maps{},
986 inputText: `{
987 "strToNested": {
988 "` + "abc\xff" + `": {}
989 }
990}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700991 wantErr: true,
992 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -0700993 desc: "required fields not set",
994 inputMessage: &pb2.Requireds{},
995 wantErr: true,
996 }, {
997 desc: "required field set",
998 inputMessage: &pb2.PartialRequired{},
999 inputText: `{
1000 "reqString": "this is required"
1001}`,
1002 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001003 ReqString: proto.String("this is required"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001004 },
1005 }, {
1006 desc: "required fields partially set",
1007 inputMessage: &pb2.Requireds{},
1008 inputText: `{
1009 "reqBool": false,
1010 "reqSfixed64": 42,
1011 "reqString": "hello",
1012 "reqEnum": "ONE"
1013}`,
1014 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001015 ReqBool: proto.Bool(false),
1016 ReqSfixed64: proto.Int64(42),
1017 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001018 ReqEnum: pb2.Enum_ONE.Enum(),
1019 },
1020 wantErr: true,
1021 }, {
1022 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001023 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001024 inputMessage: &pb2.Requireds{},
1025 inputText: `{
1026 "reqBool": false,
1027 "reqSfixed64": 42,
1028 "reqString": "hello",
1029 "reqEnum": "ONE"
1030}`,
1031 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001032 ReqBool: proto.Bool(false),
1033 ReqSfixed64: proto.Int64(42),
1034 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001035 ReqEnum: pb2.Enum_ONE.Enum(),
1036 },
1037 }, {
1038 desc: "required fields all set",
1039 inputMessage: &pb2.Requireds{},
1040 inputText: `{
1041 "reqBool": false,
1042 "reqSfixed64": 42,
1043 "reqDouble": 1.23,
1044 "reqString": "hello",
1045 "reqEnum": "ONE",
1046 "reqNested": {}
1047}`,
1048 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001049 ReqBool: proto.Bool(false),
1050 ReqSfixed64: proto.Int64(42),
1051 ReqDouble: proto.Float64(1.23),
1052 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001053 ReqEnum: pb2.Enum_ONE.Enum(),
1054 ReqNested: &pb2.Nested{},
1055 },
1056 }, {
1057 desc: "indirect required field",
1058 inputMessage: &pb2.IndirectRequired{},
1059 inputText: `{
1060 "optNested": {}
1061}`,
1062 wantMessage: &pb2.IndirectRequired{
1063 OptNested: &pb2.NestedWithRequired{},
1064 },
1065 wantErr: true,
1066 }, {
1067 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001068 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001069 inputMessage: &pb2.IndirectRequired{},
1070 inputText: `{
1071 "optNested": {}
1072}`,
1073 wantMessage: &pb2.IndirectRequired{
1074 OptNested: &pb2.NestedWithRequired{},
1075 },
1076 }, {
1077 desc: "indirect required field in repeated",
1078 inputMessage: &pb2.IndirectRequired{},
1079 inputText: `{
1080 "rptNested": [
1081 {"reqString": "one"},
1082 {}
1083 ]
1084}`,
1085 wantMessage: &pb2.IndirectRequired{
1086 RptNested: []*pb2.NestedWithRequired{
1087 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001088 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001089 },
1090 {},
1091 },
1092 },
1093 wantErr: true,
1094 }, {
1095 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001096 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001097 inputMessage: &pb2.IndirectRequired{},
1098 inputText: `{
1099 "rptNested": [
1100 {"reqString": "one"},
1101 {}
1102 ]
1103}`,
1104 wantMessage: &pb2.IndirectRequired{
1105 RptNested: []*pb2.NestedWithRequired{
1106 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001107 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001108 },
1109 {},
1110 },
1111 },
1112 }, {
1113 desc: "indirect required field in map",
1114 inputMessage: &pb2.IndirectRequired{},
1115 inputText: `{
1116 "strToNested": {
1117 "missing": {},
1118 "contains": {
1119 "reqString": "here"
1120 }
1121 }
1122}`,
1123 wantMessage: &pb2.IndirectRequired{
1124 StrToNested: map[string]*pb2.NestedWithRequired{
1125 "missing": &pb2.NestedWithRequired{},
1126 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001127 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001128 },
1129 },
1130 },
1131 wantErr: true,
1132 }, {
1133 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001134 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001135 inputMessage: &pb2.IndirectRequired{},
1136 inputText: `{
1137 "strToNested": {
1138 "missing": {},
1139 "contains": {
1140 "reqString": "here"
1141 }
1142 }
1143}`,
1144 wantMessage: &pb2.IndirectRequired{
1145 StrToNested: map[string]*pb2.NestedWithRequired{
1146 "missing": &pb2.NestedWithRequired{},
1147 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001148 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001149 },
1150 },
1151 },
1152 }, {
1153 desc: "indirect required field in oneof",
1154 inputMessage: &pb2.IndirectRequired{},
1155 inputText: `{
1156 "oneofNested": {}
1157}`,
1158 wantMessage: &pb2.IndirectRequired{
1159 Union: &pb2.IndirectRequired_OneofNested{
1160 OneofNested: &pb2.NestedWithRequired{},
1161 },
1162 },
1163 wantErr: true,
1164 }, {
1165 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001166 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001167 inputMessage: &pb2.IndirectRequired{},
1168 inputText: `{
1169 "oneofNested": {}
1170}`,
1171 wantMessage: &pb2.IndirectRequired{
1172 Union: &pb2.IndirectRequired_OneofNested{
1173 OneofNested: &pb2.NestedWithRequired{},
1174 },
1175 },
1176 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001177 desc: "extensions of non-repeated fields",
1178 inputMessage: &pb2.Extensions{},
1179 inputText: `{
1180 "optString": "non-extension field",
1181 "optBool": true,
1182 "optInt32": 42,
1183 "[pb2.opt_ext_bool]": true,
1184 "[pb2.opt_ext_nested]": {
1185 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001186 "optNested": {
1187 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001188 }
1189 },
1190 "[pb2.opt_ext_string]": "extension field",
1191 "[pb2.opt_ext_enum]": "TEN"
1192}`,
1193 wantMessage: func() proto.Message {
1194 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001195 OptString: proto.String("non-extension field"),
1196 OptBool: proto.Bool(true),
1197 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001198 }
1199 setExtension(m, pb2.E_OptExtBool, true)
1200 setExtension(m, pb2.E_OptExtString, "extension field")
1201 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1202 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001203 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001204 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001205 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001206 },
1207 })
1208 return m
1209 }(),
1210 }, {
1211 desc: "extensions of repeated fields",
1212 inputMessage: &pb2.Extensions{},
1213 inputText: `{
1214 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1215 "[pb2.rpt_ext_fixed32]": [42, 47],
1216 "[pb2.rpt_ext_nested]": [
1217 {"optString": "one"},
1218 {"optString": "two"},
1219 {"optString": "three"}
1220 ]
1221}`,
1222 wantMessage: func() proto.Message {
1223 m := &pb2.Extensions{}
1224 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1225 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1226 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001227 &pb2.Nested{OptString: proto.String("one")},
1228 &pb2.Nested{OptString: proto.String("two")},
1229 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001230 })
1231 return m
1232 }(),
1233 }, {
1234 desc: "extensions of non-repeated fields in another message",
1235 inputMessage: &pb2.Extensions{},
1236 inputText: `{
1237 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1238 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1239 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1240 "optString": "nested in an extension",
1241 "optNested": {
1242 "optString": "another nested in an extension"
1243 }
1244 },
1245 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1246}`,
1247 wantMessage: func() proto.Message {
1248 m := &pb2.Extensions{}
1249 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1250 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1251 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1252 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001253 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001254 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001255 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001256 },
1257 })
1258 return m
1259 }(),
1260 }, {
1261 desc: "extensions of repeated fields in another message",
1262 inputMessage: &pb2.Extensions{},
1263 inputText: `{
1264 "optString": "non-extension field",
1265 "optBool": true,
1266 "optInt32": 42,
1267 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1268 {"optString": "one"},
1269 {"optString": "two"},
1270 {"optString": "three"}
1271 ],
1272 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1273 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1274}`,
1275 wantMessage: func() proto.Message {
1276 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001277 OptString: proto.String("non-extension field"),
1278 OptBool: proto.Bool(true),
1279 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001280 }
1281 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1282 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1283 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001284 &pb2.Nested{OptString: proto.String("one")},
1285 &pb2.Nested{OptString: proto.String("two")},
1286 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001287 })
1288 return m
1289 }(),
1290 }, {
1291 desc: "invalid extension field name",
1292 inputMessage: &pb2.Extensions{},
1293 inputText: `{ "[pb2.invalid_message_field]": true }`,
1294 wantErr: true,
1295 }, {
1296 desc: "MessageSet",
1297 inputMessage: &pb2.MessageSet{},
1298 inputText: `{
1299 "[pb2.MessageSetExtension]": {
1300 "optString": "a messageset extension"
1301 },
1302 "[pb2.MessageSetExtension.ext_nested]": {
1303 "optString": "just a regular extension"
1304 },
1305 "[pb2.MessageSetExtension.not_message_set_extension]": {
1306 "optString": "not a messageset extension"
1307 }
1308}`,
1309 wantMessage: func() proto.Message {
1310 m := &pb2.MessageSet{}
1311 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001312 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001313 })
1314 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001315 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001316 })
1317 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001318 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001319 })
1320 return m
1321 }(),
1322 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001323 desc: "extensions of repeated field contains null",
1324 inputMessage: &pb2.Extensions{},
1325 inputText: `{
1326 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1327 {"optString": "one"},
1328 null,
1329 {"optString": "three"}
1330 ],
1331}`,
1332 wantErr: true,
1333 }, {
1334 desc: "not real MessageSet 1",
1335 inputMessage: &pb2.FakeMessageSet{},
1336 inputText: `{
1337 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1338 "optString": "not a messageset extension"
1339 }
1340}`,
1341 wantMessage: func() proto.Message {
1342 m := &pb2.FakeMessageSet{}
1343 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001344 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001345 })
1346 return m
1347 }(),
1348 }, {
1349 desc: "not real MessageSet 2",
1350 inputMessage: &pb2.FakeMessageSet{},
1351 inputText: `{
1352 "[pb2.FakeMessageSetExtension]": {
1353 "optString": "not a messageset extension"
1354 }
1355}`,
1356 wantErr: true,
1357 }, {
1358 desc: "not real MessageSet 3",
1359 inputMessage: &pb2.MessageSet{},
1360 inputText: `{
1361 "[pb2.message_set_extension]": {
1362 "optString": "another not a messageset extension"
1363 }
1364}`,
1365 wantMessage: func() proto.Message {
1366 m := &pb2.MessageSet{}
1367 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001368 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001369 })
1370 return m
1371 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001372 }, {
1373 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001374 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001375 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001376 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001377 }, {
1378 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001379 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001380 inputText: `{"unknown": null}`,
1381 wantErr: true,
1382 }, {
1383 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001384 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001385 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001386 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001387 }, {
1388 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001389 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001390 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001391 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001392 }, {
1393 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001394 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001395 inputText: `{}`,
1396 wantErr: true,
1397 }, {
1398 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001399 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001400 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001401 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001402 }, {
1403 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001404 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001405 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001406 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001407 }, {
1408 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001410 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001411 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001412 }, {
1413 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001414 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001415 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001416 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001417 }, {
1418 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001419 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001420 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001421 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001422 }, {
1423 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001424 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001425 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001426 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001427 }, {
1428 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001429 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001430 inputText: `1.23+40`,
1431 wantErr: true,
1432 }, {
1433 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001435 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001436 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001437 }, {
1438 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001439 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001440 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001441 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001442 }, {
1443 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001445 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001446 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001447 }, {
1448 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001449 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001450 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001451 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001452 }, {
1453 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001455 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001456 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001457 }, {
1458 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001459 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001460 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001461 wantErr: true,
1462 }, {
1463 desc: "StringValue field with invalid UTF8 error",
1464 inputMessage: &pb2.KnownTypes{},
1465 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001466 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001467 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001468 desc: "NullValue field with JSON null",
1469 inputMessage: &pb2.KnownTypes{},
1470 inputText: `{
1471 "optNull": null
1472}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001473 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001474 }, {
1475 desc: "NullValue field with string",
1476 inputMessage: &pb2.KnownTypes{},
1477 inputText: `{
1478 "optNull": "NULL_VALUE"
1479}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001480 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001481 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001482 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001483 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001484 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001485 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001486 }, {
1487 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001488 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001489 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001490 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001491 }, {
1492 desc: "Value field null",
1493 inputMessage: &pb2.KnownTypes{},
1494 inputText: `{
1495 "optValue": null
1496}`,
1497 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001498 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001499 },
1500 }, {
1501 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001502 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001503 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001504 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001505 }, {
1506 desc: "Value field bool",
1507 inputMessage: &pb2.KnownTypes{},
1508 inputText: `{
1509 "optValue": true
1510}`,
1511 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001512 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001513 },
1514 }, {
1515 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001516 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001517 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001518 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001519 }, {
1520 desc: "Value field number",
1521 inputMessage: &pb2.KnownTypes{},
1522 inputText: `{
1523 "optValue": 1.02
1524}`,
1525 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001526 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001527 },
1528 }, {
1529 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001530 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001531 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001532 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001533 }, {
1534 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001535 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001536 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001537 wantErr: true,
1538 }, {
1539 desc: "Value field string",
1540 inputMessage: &pb2.KnownTypes{},
1541 inputText: `{
1542 "optValue": "NaN"
1543}`,
1544 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001545 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001546 },
1547 }, {
1548 desc: "Value field string with invalid UTF8",
1549 inputMessage: &pb2.KnownTypes{},
1550 inputText: `{
1551 "optValue": "` + "\xff" + `"
1552}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001553 wantErr: true,
1554 }, {
1555 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001556 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001557 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001558 wantMessage: &structpb.Value{
1559 Kind: &structpb.Value_StructValue{
1560 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001561 },
1562 },
1563 }, {
1564 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001565 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001566 inputText: `{
1567 "string": "hello",
1568 "number": 123,
1569 "null": null,
1570 "bool": false,
1571 "struct": {
1572 "string": "world"
1573 },
1574 "list": []
1575}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001576 wantMessage: &structpb.Value{
1577 Kind: &structpb.Value_StructValue{
1578 &structpb.Struct{
1579 Fields: map[string]*structpb.Value{
1580 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1581 "number": {Kind: &structpb.Value_NumberValue{123}},
1582 "null": {Kind: &structpb.Value_NullValue{}},
1583 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001584 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001585 Kind: &structpb.Value_StructValue{
1586 &structpb.Struct{
1587 Fields: map[string]*structpb.Value{
1588 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001589 },
1590 },
1591 },
1592 },
1593 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001594 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001595 },
1596 },
1597 },
1598 },
1599 },
1600 }, {
1601 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001602 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001603 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001604 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001605 }, {
1606 desc: "Value field struct",
1607 inputMessage: &pb2.KnownTypes{},
1608 inputText: `{
1609 "optValue": {
1610 "string": "hello"
1611 }
1612}`,
1613 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001614 OptValue: &structpb.Value{
1615 Kind: &structpb.Value_StructValue{
1616 &structpb.Struct{
1617 Fields: map[string]*structpb.Value{
1618 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001619 },
1620 },
1621 },
1622 },
1623 },
1624 }, {
1625 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001626 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001627 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001628 wantMessage: &structpb.Value{
1629 Kind: &structpb.Value_ListValue{
1630 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001631 },
1632 },
1633 }, {
1634 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001635 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001636 inputText: `[
1637 "string",
1638 123,
1639 null,
1640 true,
1641 {},
1642 [
1643 "string",
1644 1.23,
1645 null,
1646 false
1647 ]
1648]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001649 wantMessage: &structpb.Value{
1650 Kind: &structpb.Value_ListValue{
1651 &structpb.ListValue{
1652 Values: []*structpb.Value{
1653 {Kind: &structpb.Value_StringValue{"string"}},
1654 {Kind: &structpb.Value_NumberValue{123}},
1655 {Kind: &structpb.Value_NullValue{}},
1656 {Kind: &structpb.Value_BoolValue{true}},
1657 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001658 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001659 Kind: &structpb.Value_ListValue{
1660 &structpb.ListValue{
1661 Values: []*structpb.Value{
1662 {Kind: &structpb.Value_StringValue{"string"}},
1663 {Kind: &structpb.Value_NumberValue{1.23}},
1664 {Kind: &structpb.Value_NullValue{}},
1665 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001666 },
1667 },
1668 },
1669 },
1670 },
1671 },
1672 },
1673 },
1674 }, {
1675 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001676 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001677 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001678 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001679 }, {
1680 desc: "Value field list with invalid UTF8 string",
1681 inputMessage: &pb2.KnownTypes{},
1682 inputText: `{
1683 "optValue": [ "` + "abc\xff" + `"]
1684}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001685 wantErr: true,
1686 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001687 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001688 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001689 inputText: `""`,
1690 wantErr: true,
1691 }, {
1692 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001693 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001694 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001695 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001696 }, {
1697 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001698 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001699 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001700 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001701 }, {
1702 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001703 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001704 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001705 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001706 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001707 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001708 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001709 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001710 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001711 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001712 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001713 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001714 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001715 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001716 }, {
1717 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001718 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001719 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001720 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001721 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001722 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001723 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001724 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001725 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001726 }, {
1727 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001728 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001729 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001730 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001731 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001732 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001733 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001734 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001735 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001736 }, {
1737 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001738 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001739 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001740 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001741 }, {
1742 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001743 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001744 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001745 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001746 }, {
1747 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001748 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001749 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001750 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001751 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001752 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001753 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001754 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001755 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001756 }, {
1757 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001758 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001759 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001760 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001761 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001762 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001764 inputText: `"315576000001s"`,
1765 wantErr: true,
1766 }, {
1767 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001768 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001769 inputText: `"-315576000001s"`,
1770 wantErr: true,
1771 }, {
1772 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001773 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001774 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001775 wantErr: true,
1776 }, {
1777 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001778 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001779 inputText: `"123"`,
1780 wantErr: true,
1781 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001782 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001783 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001784 inputText: `"123.+123s"`,
1785 wantErr: true,
1786 }, {
1787 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001788 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001789 inputText: `"123.123.s"`,
1790 wantErr: true,
1791 }, {
1792 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001793 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001794 inputText: `"01s"`,
1795 wantErr: true,
1796 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001797 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001798 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001799 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001800 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001801 }, {
1802 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001803 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001804 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001805 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001806 }, {
1807 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001808 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001809 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001810 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001811 }, {
1812 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001813 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001814 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001815 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001816 }, {
1817 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001818 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001819 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001820 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001821 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001822 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001824 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001825 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001826 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001827 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 inputText: `"9999-12-31T23:59:59-01:00"`,
1830 wantErr: true,
1831 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001832 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001835 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001836 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001837 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001838 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001839 inputText: `"0001-01-01T00:00:00+01:00"`,
1840 wantErr: true,
1841 }, {
1842 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001844 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1845 wantErr: true,
1846 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001847 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001848 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001849 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001850 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001851 }, {
1852 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001853 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001854 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001855 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001856 Paths: []string{
1857 "foo",
1858 "foo_bar",
1859 "foo.bar_qux",
1860 "_foo",
1861 },
1862 },
1863 }, {
1864 desc: "FieldMask field",
1865 inputMessage: &pb2.KnownTypes{},
1866 inputText: `{
1867 "optFieldmask": "foo, qux.fooBar"
1868}`,
1869 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001870 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001871 Paths: []string{
1872 "foo",
1873 "qux.foo_bar",
1874 },
1875 },
1876 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001877 }, {
1878 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001879 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001880 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001881 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001882 }, {
1883 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001884 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001885 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001886 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001887 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001888 inputText: `{
1889 "@type": "foo/pb2.Nested",
1890 "optString": "embedded inside Any",
1891 "optNested": {
1892 "optString": "inception"
1893 }
1894}`,
1895 wantMessage: func() proto.Message {
1896 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001897 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001898 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001899 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001900 },
1901 }
1902 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1903 if err != nil {
1904 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1905 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001906 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001907 TypeUrl: "foo/pb2.Nested",
1908 Value: b,
1909 }
1910 }(),
1911 }, {
1912 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001913 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001914 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001915 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001916 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001917 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001918 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001919 }, {
1920 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001921 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001922 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001923 inputText: `{"@type": "foo/pb2.Nested"}`,
1924 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001925 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001926 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001927 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001928 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001929 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001930 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001931 inputText: `{
1932 "@type": "pb2.PartialRequired",
1933 "optString": "embedded inside Any"
1934}`,
1935 wantMessage: func() proto.Message {
1936 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001937 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001938 }
Damien Neil96c229a2019-04-03 12:17:24 -07001939 b, err := proto.MarshalOptions{
1940 Deterministic: true,
1941 AllowPartial: true,
1942 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001943 if err != nil {
1944 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1945 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001946 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001947 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001948 Value: b,
1949 }
1950 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001951 }, {
1952 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001953 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001954 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001955 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001956 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001957 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001958 inputText: `{
1959 "@type": "pb2.PartialRequired",
1960 "optString": "embedded inside Any"
1961}`,
1962 wantMessage: func() proto.Message {
1963 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001964 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001965 }
Damien Neil96c229a2019-04-03 12:17:24 -07001966 b, err := proto.MarshalOptions{
1967 Deterministic: true,
1968 AllowPartial: true,
1969 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001970 if err != nil {
1971 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1972 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001973 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001974 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001975 Value: b,
1976 }
1977 }(),
1978 }, {
1979 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001980 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001981 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001982 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001983 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001984 inputText: `{
1985 "optString": "` + "abc\xff" + `",
1986 "@type": "foo/pb2.Nested"
1987}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001988 wantErr: true,
1989 }, {
1990 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07001991 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001992 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001993 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001994 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001995 inputText: `{
1996 "@type": "type.googleapis.com/google.protobuf.BoolValue",
1997 "value": true
1998}`,
1999 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002000 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002001 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2002 if err != nil {
2003 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2004 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002005 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002006 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2007 Value: b,
2008 }
2009 }(),
2010 }, {
2011 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002012 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002013 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002014 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002015 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002016 inputText: `{
2017 "value": {},
2018 "@type": "type.googleapis.com/google.protobuf.Empty"
2019}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002020 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002021 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2022 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002023 }, {
2024 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002025 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002026 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002027 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002028 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002029 inputText: `{
2030 "@type": "type.googleapis.com/google.protobuf.Empty"
2031}`,
2032 wantErr: true,
2033 }, {
2034 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002035 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002036 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002037 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002038 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002039 inputText: `{
2040 "@type": "google.protobuf.StringValue",
2041 "value": "` + "abc\xff" + `"
2042}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002043 wantErr: true,
2044 }, {
2045 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002046 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002047 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002048 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002049 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002050 inputText: `{
2051 "@type": "google.protobuf.Int64Value",
2052 "value": "42"
2053}`,
2054 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002055 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002056 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2057 if err != nil {
2058 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2059 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002060 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002061 TypeUrl: "google.protobuf.Int64Value",
2062 Value: b,
2063 }
2064 }(),
2065 }, {
2066 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002067 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002068 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002069 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002070 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002071 inputText: `{
2072 "@type": "google.protobuf.Int64Value",
2073 "value": "forty-two"
2074}`,
2075 wantErr: true,
2076 }, {
2077 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002078 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002079 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002080 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002081 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002082 inputText: `{
2083 "@type": "google.protobuf.UInt64Value",
2084 "value": -42
2085}`,
2086 wantErr: true,
2087 }, {
2088 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002089 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002090 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002091 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002092 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002093 inputText: `{
2094 "@type": "type.googleapis.com/google.protobuf.Duration",
2095 "value": "0s"
2096}`,
2097 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002098 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002099 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2100 if err != nil {
2101 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2102 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002103 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002104 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2105 Value: b,
2106 }
2107 }(),
2108 }, {
2109 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002110 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002111 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002112 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002113 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002114 inputText: `{
2115 "@type": "google.protobuf.Value",
2116 "value": "` + "abc\xff" + `"
2117}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002118 wantErr: true,
2119 }, {
2120 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002121 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002122 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002123 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002124 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002125 inputText: `{
2126 "@type": "google.protobuf.Value",
2127 "value": null
2128}`,
2129 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002130 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002131 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2132 if err != nil {
2133 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2134 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002135 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002136 TypeUrl: "google.protobuf.Value",
2137 Value: b,
2138 }
2139 }(),
2140 }, {
2141 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002142 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002143 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002144 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2145 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2146 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2147 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2148 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002149 ),
2150 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002151 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002152 inputText: `{
2153 "@type": "google.protobuf.Struct",
2154 "value": {
2155 "bool": true,
2156 "null": null,
2157 "string": "hello",
2158 "struct": {
2159 "string": "world"
2160 }
2161 }
2162}`,
2163 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002164 m := &structpb.Struct{
2165 Fields: map[string]*structpb.Value{
2166 "bool": {Kind: &structpb.Value_BoolValue{true}},
2167 "null": {Kind: &structpb.Value_NullValue{}},
2168 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002169 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002170 Kind: &structpb.Value_StructValue{
2171 &structpb.Struct{
2172 Fields: map[string]*structpb.Value{
2173 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002174 },
2175 },
2176 },
2177 },
2178 },
2179 }
2180 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2181 if err != nil {
2182 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2183 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002184 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002185 TypeUrl: "google.protobuf.Struct",
2186 Value: b,
2187 }
2188 }(),
2189 }, {
2190 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002191 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002192 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002193 inputText: `{
2194 "value": {}
2195}`,
2196 wantErr: true,
2197 }, {
2198 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002199 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002200 inputText: `{
2201 "@type": ""
2202}`,
2203 wantErr: true,
2204 }, {
2205 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002206 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002207 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002208 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002209 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002210 ),
2211 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002212 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002213 inputText: `{
2214 "@type": "google.protobuf.StringValue",
2215 "value": "hello",
2216 "@type": "pb2.Nested"
2217}`,
2218 wantErr: true,
2219 }, {
2220 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002221 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002222 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002223 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002224 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002225 inputText: `{
2226 "@type": "google.protobuf.StringValue",
2227 "value": "hello",
2228 "value": "world"
2229}`,
2230 wantErr: true,
2231 }, {
2232 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002233 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002234 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002235 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002236 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002237 inputText: `{
2238 "@type": "pb2.Nested",
2239 "optString": "hello",
2240 "unknown": "world"
2241}`,
2242 wantErr: true,
2243 }, {
2244 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002245 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002246 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002247 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002248 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2249 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002250 ),
2251 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002252 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002253 inputText: `{
2254 "@type": "pb2.KnownTypes",
2255 "optAny": {
2256 "@type": "google.protobuf.StringValue",
2257 "value": "` + "abc\xff" + `"
2258 }
2259}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002260 wantErr: true,
2261 }, {
2262 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002263 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002264 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002265 },
2266 inputMessage: &pb2.KnownTypes{},
2267 inputText: `{
2268 "optBool": false,
2269 "optInt32": 42,
2270 "optInt64": "42",
2271 "optUint32": 42,
2272 "optUint64": "42",
2273 "optFloat": 1.23,
2274 "optDouble": 3.1415,
2275 "optString": "hello",
2276 "optBytes": "aGVsbG8=",
2277 "optDuration": "123s",
2278 "optTimestamp": "2019-03-19T23:03:21Z",
2279 "optStruct": {
2280 "string": "hello"
2281 },
2282 "optList": [
2283 null,
2284 "",
2285 {},
2286 []
2287 ],
2288 "optValue": "world",
2289 "optEmpty": {},
2290 "optAny": {
2291 "@type": "google.protobuf.Empty",
2292 "value": {}
2293 },
2294 "optFieldmask": "fooBar,barFoo"
2295}`,
2296 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002297 OptBool: &wrapperspb.BoolValue{Value: false},
2298 OptInt32: &wrapperspb.Int32Value{Value: 42},
2299 OptInt64: &wrapperspb.Int64Value{Value: 42},
2300 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2301 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2302 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2303 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2304 OptString: &wrapperspb.StringValue{Value: "hello"},
2305 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2306 OptDuration: &durationpb.Duration{Seconds: 123},
2307 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2308 OptStruct: &structpb.Struct{
2309 Fields: map[string]*structpb.Value{
2310 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002311 },
2312 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002313 OptList: &structpb.ListValue{
2314 Values: []*structpb.Value{
2315 {Kind: &structpb.Value_NullValue{}},
2316 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002317 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002318 Kind: &structpb.Value_StructValue{
2319 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002320 },
2321 },
2322 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002323 Kind: &structpb.Value_ListValue{
2324 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002325 },
2326 },
2327 },
2328 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002329 OptValue: &structpb.Value{
2330 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002331 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002332 OptEmpty: &emptypb.Empty{},
2333 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002334 TypeUrl: "google.protobuf.Empty",
2335 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002336 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002337 Paths: []string{"foo_bar", "bar_foo"},
2338 },
2339 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002340 }, {
2341 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002342 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002343 inputMessage: &pb3.Nests{},
2344 inputText: `{
2345 "sNested": {
2346 "unknown": {
2347 "foo": 1,
2348 "bar": [1, 2, 3]
2349 }
2350 },
2351 "unknown": "not known"
2352}`,
2353 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2354 }, {
2355 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002356 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002357 inputMessage: &pb2.Nests{},
2358 inputText: `{
2359 "rptNested": [
2360 {"unknown": "blah"},
2361 {"optString": "hello"}
2362 ]
2363}`,
2364 wantMessage: &pb2.Nests{
2365 RptNested: []*pb2.Nested{
2366 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002367 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002368 },
2369 },
2370 }, {
2371 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002372 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002373 inputMessage: &pb3.Maps{},
2374 inputText: `{
2375 "strToNested": {
2376 "nested_one": {
2377 "unknown": "what you see is not"
2378 }
2379 }
2380}`,
2381 wantMessage: &pb3.Maps{
2382 StrToNested: map[string]*pb3.Nested{
2383 "nested_one": {},
2384 },
2385 },
2386 }, {
2387 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002388 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002389 inputMessage: &pb2.Extensions{},
2390 inputText: `{
2391 "[pb2.opt_ext_nested]": {
2392 "unknown": []
2393 }
2394}`,
2395 wantMessage: func() proto.Message {
2396 m := &pb2.Extensions{}
2397 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2398 return m
2399 }(),
2400 }, {
2401 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002402 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002403 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002404 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002405 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002406 }, {
2407 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002408 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002409 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002410 inputText: `{
2411 "value": {"foo": "bar"},
2412 "unknown": true
2413}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002414 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002415 }, {
2416 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002417 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002418 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002419 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002420 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002421 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002422 inputText: `{
2423 "@type": "foo/pb2.Nested",
2424 "unknown": "none"
2425}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002426 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002427 TypeUrl: "foo/pb2.Nested",
2428 },
2429 }, {
2430 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002431 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002432 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002433 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002434 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002435 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002436 inputText: `{
2437 "@type": "type.googleapis.com/google.protobuf.Empty",
2438 "value": {"unknown": 47}
2439}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002440 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002441 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2442 },
Herbie Ongc96a79d2019-03-08 10:49:17 -08002443 }}
2444
2445 for _, tt := range tests {
2446 tt := tt
2447 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002448 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002449 if err != nil && !tt.wantErr {
2450 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2451 }
2452 if err == nil && tt.wantErr {
2453 t.Error("Unmarshal() got nil error, want error\n\n")
2454 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002455 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002456 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2457 }
2458 })
2459 }
2460}