blob: 2385dc4c2e51edb1238764051a1caecee4e4ac94 [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package protojson_test
Herbie Ongc96a79d2019-03-08 10:49:17 -08006
7import (
8 "math"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
Joe Tsaid47ea192019-07-09 22:38:15 -070012 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070013 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070014 "google.golang.org/protobuf/proto"
15 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Onge63c4c42019-03-22 22:20:22 -070016
Joe Tsaid47ea192019-07-09 22:38:15 -070017 "google.golang.org/protobuf/encoding/testprotos/pb2"
18 "google.golang.org/protobuf/encoding/testprotos/pb3"
19 testpb "google.golang.org/protobuf/internal/testprotos/test"
20 weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
Joe Tsaia95b29f2019-05-16 12:47:20 -070021 "google.golang.org/protobuf/types/known/anypb"
22 "google.golang.org/protobuf/types/known/durationpb"
23 "google.golang.org/protobuf/types/known/emptypb"
24 "google.golang.org/protobuf/types/known/fieldmaskpb"
25 "google.golang.org/protobuf/types/known/structpb"
26 "google.golang.org/protobuf/types/known/timestamppb"
27 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080028)
29
30func TestUnmarshal(t *testing.T) {
31 tests := []struct {
32 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070033 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080034 inputMessage proto.Message
35 inputText string
36 wantMessage proto.Message
37 // TODO: verify expected error message substring.
38 wantErr bool
Joe Tsaid47ea192019-07-09 22:38:15 -070039 skip bool
Herbie Ongc96a79d2019-03-08 10:49:17 -080040 }{{
41 desc: "proto2 empty message",
42 inputMessage: &pb2.Scalars{},
43 inputText: "{}",
44 wantMessage: &pb2.Scalars{},
45 }, {
46 desc: "unexpected value instead of EOF",
47 inputMessage: &pb2.Scalars{},
48 inputText: "{} {}",
49 wantErr: true,
50 }, {
51 desc: "proto2 optional scalars set to zero values",
52 inputMessage: &pb2.Scalars{},
53 inputText: `{
54 "optBool": false,
55 "optInt32": 0,
56 "optInt64": 0,
57 "optUint32": 0,
58 "optUint64": 0,
59 "optSint32": 0,
60 "optSint64": 0,
61 "optFixed32": 0,
62 "optFixed64": 0,
63 "optSfixed32": 0,
64 "optSfixed64": 0,
65 "optFloat": 0,
66 "optDouble": 0,
67 "optBytes": "",
68 "optString": ""
69}`,
70 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070071 OptBool: proto.Bool(false),
72 OptInt32: proto.Int32(0),
73 OptInt64: proto.Int64(0),
74 OptUint32: proto.Uint32(0),
75 OptUint64: proto.Uint64(0),
76 OptSint32: proto.Int32(0),
77 OptSint64: proto.Int64(0),
78 OptFixed32: proto.Uint32(0),
79 OptFixed64: proto.Uint64(0),
80 OptSfixed32: proto.Int32(0),
81 OptSfixed64: proto.Int64(0),
82 OptFloat: proto.Float32(0),
83 OptDouble: proto.Float64(0),
Herbie Ongc96a79d2019-03-08 10:49:17 -080084 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070085 OptString: proto.String(""),
Herbie Ongc96a79d2019-03-08 10:49:17 -080086 },
87 }, {
88 desc: "proto3 scalars set to zero values",
89 inputMessage: &pb3.Scalars{},
90 inputText: `{
91 "sBool": false,
92 "sInt32": 0,
93 "sInt64": 0,
94 "sUint32": 0,
95 "sUint64": 0,
96 "sSint32": 0,
97 "sSint64": 0,
98 "sFixed32": 0,
99 "sFixed64": 0,
100 "sSfixed32": 0,
101 "sSfixed64": 0,
102 "sFloat": 0,
103 "sDouble": 0,
104 "sBytes": "",
105 "sString": ""
106}`,
107 wantMessage: &pb3.Scalars{},
108 }, {
109 desc: "proto2 optional scalars set to null",
110 inputMessage: &pb2.Scalars{},
111 inputText: `{
112 "optBool": null,
113 "optInt32": null,
114 "optInt64": null,
115 "optUint32": null,
116 "optUint64": null,
117 "optSint32": null,
118 "optSint64": null,
119 "optFixed32": null,
120 "optFixed64": null,
121 "optSfixed32": null,
122 "optSfixed64": null,
123 "optFloat": null,
124 "optDouble": null,
125 "optBytes": null,
126 "optString": null
127}`,
128 wantMessage: &pb2.Scalars{},
129 }, {
130 desc: "proto3 scalars set to null",
131 inputMessage: &pb3.Scalars{},
132 inputText: `{
133 "sBool": null,
134 "sInt32": null,
135 "sInt64": null,
136 "sUint32": null,
137 "sUint64": null,
138 "sSint32": null,
139 "sSint64": null,
140 "sFixed32": null,
141 "sFixed64": null,
142 "sSfixed32": null,
143 "sSfixed64": null,
144 "sFloat": null,
145 "sDouble": null,
146 "sBytes": null,
147 "sString": null
148}`,
149 wantMessage: &pb3.Scalars{},
150 }, {
151 desc: "boolean",
152 inputMessage: &pb3.Scalars{},
153 inputText: `{"sBool": true}`,
154 wantMessage: &pb3.Scalars{
155 SBool: true,
156 },
157 }, {
158 desc: "not boolean",
159 inputMessage: &pb3.Scalars{},
160 inputText: `{"sBool": "true"}`,
161 wantErr: true,
162 }, {
163 desc: "float and double",
164 inputMessage: &pb3.Scalars{},
165 inputText: `{
166 "sFloat": 1.234,
167 "sDouble": 5.678
168}`,
169 wantMessage: &pb3.Scalars{
170 SFloat: 1.234,
171 SDouble: 5.678,
172 },
173 }, {
174 desc: "float and double in string",
175 inputMessage: &pb3.Scalars{},
176 inputText: `{
177 "sFloat": "1.234",
178 "sDouble": "5.678"
179}`,
180 wantMessage: &pb3.Scalars{
181 SFloat: 1.234,
182 SDouble: 5.678,
183 },
184 }, {
185 desc: "float and double in E notation",
186 inputMessage: &pb3.Scalars{},
187 inputText: `{
188 "sFloat": 12.34E-1,
189 "sDouble": 5.678e4
190}`,
191 wantMessage: &pb3.Scalars{
192 SFloat: 1.234,
193 SDouble: 56780,
194 },
195 }, {
196 desc: "float and double in string E notation",
197 inputMessage: &pb3.Scalars{},
198 inputText: `{
199 "sFloat": "12.34E-1",
200 "sDouble": "5.678e4"
201}`,
202 wantMessage: &pb3.Scalars{
203 SFloat: 1.234,
204 SDouble: 56780,
205 },
206 }, {
207 desc: "float exceeds limit",
208 inputMessage: &pb3.Scalars{},
209 inputText: `{"sFloat": 3.4e39}`,
210 wantErr: true,
211 }, {
212 desc: "float in string exceeds limit",
213 inputMessage: &pb3.Scalars{},
214 inputText: `{"sFloat": "-3.4e39"}`,
215 wantErr: true,
216 }, {
217 desc: "double exceeds limit",
218 inputMessage: &pb3.Scalars{},
219 inputText: `{"sFloat": -1.79e+309}`,
220 wantErr: true,
221 }, {
222 desc: "double in string exceeds limit",
223 inputMessage: &pb3.Scalars{},
224 inputText: `{"sFloat": "1.79e+309"}`,
225 wantErr: true,
226 }, {
227 desc: "infinites",
228 inputMessage: &pb3.Scalars{},
229 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
230 wantMessage: &pb3.Scalars{
231 SFloat: float32(math.Inf(+1)),
232 SDouble: math.Inf(-1),
233 },
234 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700235 desc: "float string with leading space",
236 inputMessage: &pb3.Scalars{},
237 inputText: `{"sFloat": " 1.234"}`,
238 wantErr: true,
239 }, {
240 desc: "double string with trailing space",
241 inputMessage: &pb3.Scalars{},
242 inputText: `{"sDouble": "5.678 "}`,
243 wantErr: true,
244 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800245 desc: "not float",
246 inputMessage: &pb3.Scalars{},
247 inputText: `{"sFloat": true}`,
248 wantErr: true,
249 }, {
250 desc: "not double",
251 inputMessage: &pb3.Scalars{},
252 inputText: `{"sDouble": "not a number"}`,
253 wantErr: true,
254 }, {
255 desc: "integers",
256 inputMessage: &pb3.Scalars{},
257 inputText: `{
258 "sInt32": 1234,
259 "sInt64": -1234,
260 "sUint32": 1e2,
261 "sUint64": 100E-2,
262 "sSint32": 1.0,
263 "sSint64": -1.0,
264 "sFixed32": 1.234e+5,
265 "sFixed64": 1200E-2,
266 "sSfixed32": -1.234e05,
267 "sSfixed64": -1200e-02
268}`,
269 wantMessage: &pb3.Scalars{
270 SInt32: 1234,
271 SInt64: -1234,
272 SUint32: 100,
273 SUint64: 1,
274 SSint32: 1,
275 SSint64: -1,
276 SFixed32: 123400,
277 SFixed64: 12,
278 SSfixed32: -123400,
279 SSfixed64: -12,
280 },
281 }, {
282 desc: "integers in string",
283 inputMessage: &pb3.Scalars{},
284 inputText: `{
285 "sInt32": "1234",
286 "sInt64": "-1234",
287 "sUint32": "1e2",
288 "sUint64": "100E-2",
289 "sSint32": "1.0",
290 "sSint64": "-1.0",
291 "sFixed32": "1.234e+5",
292 "sFixed64": "1200E-2",
293 "sSfixed32": "-1.234e05",
294 "sSfixed64": "-1200e-02"
295}`,
296 wantMessage: &pb3.Scalars{
297 SInt32: 1234,
298 SInt64: -1234,
299 SUint32: 100,
300 SUint64: 1,
301 SSint32: 1,
302 SSint64: -1,
303 SFixed32: 123400,
304 SFixed64: 12,
305 SSfixed32: -123400,
306 SSfixed64: -12,
307 },
308 }, {
309 desc: "integers in escaped string",
310 inputMessage: &pb3.Scalars{},
311 inputText: `{"sInt32": "\u0031\u0032"}`,
312 wantMessage: &pb3.Scalars{
313 SInt32: 12,
314 },
315 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700316 desc: "integer string with leading space",
317 inputMessage: &pb3.Scalars{},
318 inputText: `{"sInt32": " 1234"}`,
319 wantErr: true,
320 }, {
321 desc: "integer string with trailing space",
322 inputMessage: &pb3.Scalars{},
323 inputText: `{"sUint32": "1e2 "}`,
324 wantErr: true,
325 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800326 desc: "number is not an integer",
327 inputMessage: &pb3.Scalars{},
328 inputText: `{"sInt32": 1.001}`,
329 wantErr: true,
330 }, {
331 desc: "32-bit int exceeds limit",
332 inputMessage: &pb3.Scalars{},
333 inputText: `{"sInt32": 2e10}`,
334 wantErr: true,
335 }, {
336 desc: "64-bit int exceeds limit",
337 inputMessage: &pb3.Scalars{},
338 inputText: `{"sSfixed64": -9e19}`,
339 wantErr: true,
340 }, {
341 desc: "not integer",
342 inputMessage: &pb3.Scalars{},
343 inputText: `{"sInt32": "not a number"}`,
344 wantErr: true,
345 }, {
346 desc: "not unsigned integer",
347 inputMessage: &pb3.Scalars{},
348 inputText: `{"sUint32": "not a number"}`,
349 wantErr: true,
350 }, {
351 desc: "number is not an unsigned integer",
352 inputMessage: &pb3.Scalars{},
353 inputText: `{"sUint32": -1}`,
354 wantErr: true,
355 }, {
356 desc: "string",
357 inputMessage: &pb2.Scalars{},
358 inputText: `{"optString": "谷歌"}`,
359 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700360 OptString: proto.String("谷歌"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800361 },
362 }, {
363 desc: "string with invalid UTF-8",
364 inputMessage: &pb3.Scalars{},
365 inputText: "{\"sString\": \"\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700366 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800367 }, {
368 desc: "not string",
369 inputMessage: &pb2.Scalars{},
370 inputText: `{"optString": 42}`,
371 wantErr: true,
372 }, {
373 desc: "bytes",
374 inputMessage: &pb3.Scalars{},
375 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
376 wantMessage: &pb3.Scalars{
377 SBytes: []byte("hello world"),
378 },
379 }, {
380 desc: "bytes padded",
381 inputMessage: &pb3.Scalars{},
382 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
383 wantMessage: &pb3.Scalars{
384 SBytes: []byte("hello world"),
385 },
386 }, {
387 desc: "not bytes",
388 inputMessage: &pb3.Scalars{},
389 inputText: `{"sBytes": true}`,
390 wantErr: true,
391 }, {
392 desc: "proto2 enum",
393 inputMessage: &pb2.Enums{},
394 inputText: `{
395 "optEnum": "ONE",
396 "optNestedEnum": "UNO"
397}`,
398 wantMessage: &pb2.Enums{
399 OptEnum: pb2.Enum_ONE.Enum(),
400 OptNestedEnum: pb2.Enums_UNO.Enum(),
401 },
402 }, {
403 desc: "proto3 enum",
404 inputMessage: &pb3.Enums{},
405 inputText: `{
406 "sEnum": "ONE",
407 "sNestedEnum": "DIEZ"
408}`,
409 wantMessage: &pb3.Enums{
410 SEnum: pb3.Enum_ONE,
411 SNestedEnum: pb3.Enums_DIEZ,
412 },
413 }, {
414 desc: "enum numeric value",
415 inputMessage: &pb3.Enums{},
416 inputText: `{
417 "sEnum": 2,
418 "sNestedEnum": 2
419}`,
420 wantMessage: &pb3.Enums{
421 SEnum: pb3.Enum_TWO,
422 SNestedEnum: pb3.Enums_DOS,
423 },
424 }, {
425 desc: "enum unnamed numeric value",
426 inputMessage: &pb3.Enums{},
427 inputText: `{
428 "sEnum": 101,
429 "sNestedEnum": -101
430}`,
431 wantMessage: &pb3.Enums{
432 SEnum: 101,
433 SNestedEnum: -101,
434 },
435 }, {
436 desc: "enum set to number string",
437 inputMessage: &pb3.Enums{},
438 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700439 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800440}`,
441 wantErr: true,
442 }, {
443 desc: "enum set to invalid named",
444 inputMessage: &pb3.Enums{},
445 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700446 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800447}`,
448 wantErr: true,
449 }, {
450 desc: "enum set to not enum",
451 inputMessage: &pb3.Enums{},
452 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700453 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800454}`,
455 wantErr: true,
456 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700457 desc: "enum set to JSON null",
458 inputMessage: &pb3.Enums{},
459 inputText: `{
460 "sEnum": null
461}`,
462 wantMessage: &pb3.Enums{},
463 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800464 desc: "proto name",
465 inputMessage: &pb3.JSONNames{},
466 inputText: `{
467 "s_string": "proto name used"
468}`,
469 wantMessage: &pb3.JSONNames{
470 SString: "proto name used",
471 },
472 }, {
473 desc: "json_name",
474 inputMessage: &pb3.JSONNames{},
475 inputText: `{
476 "foo_bar": "json_name used"
477}`,
478 wantMessage: &pb3.JSONNames{
479 SString: "json_name used",
480 },
481 }, {
482 desc: "camelCase name",
483 inputMessage: &pb3.JSONNames{},
484 inputText: `{
485 "sString": "camelcase used"
486}`,
487 wantErr: true,
488 }, {
489 desc: "proto name and json_name",
490 inputMessage: &pb3.JSONNames{},
491 inputText: `{
492 "foo_bar": "json_name used",
493 "s_string": "proto name used"
494}`,
495 wantErr: true,
496 }, {
497 desc: "duplicate field names",
498 inputMessage: &pb3.JSONNames{},
499 inputText: `{
500 "foo_bar": "one",
501 "foo_bar": "two",
502}`,
503 wantErr: true,
504 }, {
505 desc: "null message",
506 inputMessage: &pb2.Nests{},
507 inputText: "null",
508 wantErr: true,
509 }, {
510 desc: "proto2 nested message not set",
511 inputMessage: &pb2.Nests{},
512 inputText: "{}",
513 wantMessage: &pb2.Nests{},
514 }, {
515 desc: "proto2 nested message set to null",
516 inputMessage: &pb2.Nests{},
517 inputText: `{
518 "optNested": null,
519 "optgroup": null
520}`,
521 wantMessage: &pb2.Nests{},
522 }, {
523 desc: "proto2 nested message set to empty",
524 inputMessage: &pb2.Nests{},
525 inputText: `{
526 "optNested": {},
527 "optgroup": {}
528}`,
529 wantMessage: &pb2.Nests{
530 OptNested: &pb2.Nested{},
531 Optgroup: &pb2.Nests_OptGroup{},
532 },
533 }, {
534 desc: "proto2 nested messages",
535 inputMessage: &pb2.Nests{},
536 inputText: `{
537 "optNested": {
538 "optString": "nested message",
539 "optNested": {
540 "optString": "another nested message"
541 }
542 }
543}`,
544 wantMessage: &pb2.Nests{
545 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700546 OptString: proto.String("nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800547 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700548 OptString: proto.String("another nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800549 },
550 },
551 },
552 }, {
553 desc: "proto2 groups",
554 inputMessage: &pb2.Nests{},
555 inputText: `{
556 "optgroup": {
557 "optString": "inside a group",
558 "optNested": {
559 "optString": "nested message inside a group"
560 },
561 "optnestedgroup": {
562 "optFixed32": 47
563 }
564 }
565}`,
566 wantMessage: &pb2.Nests{
567 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700568 OptString: proto.String("inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800569 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700570 OptString: proto.String("nested message inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800571 },
572 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700573 OptFixed32: proto.Uint32(47),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800574 },
575 },
576 },
577 }, {
578 desc: "proto3 nested message not set",
579 inputMessage: &pb3.Nests{},
580 inputText: "{}",
581 wantMessage: &pb3.Nests{},
582 }, {
583 desc: "proto3 nested message set to null",
584 inputMessage: &pb3.Nests{},
585 inputText: `{"sNested": null}`,
586 wantMessage: &pb3.Nests{},
587 }, {
588 desc: "proto3 nested message set to empty",
589 inputMessage: &pb3.Nests{},
590 inputText: `{"sNested": {}}`,
591 wantMessage: &pb3.Nests{
592 SNested: &pb3.Nested{},
593 },
594 }, {
595 desc: "proto3 nested message",
596 inputMessage: &pb3.Nests{},
597 inputText: `{
598 "sNested": {
599 "sString": "nested message",
600 "sNested": {
601 "sString": "another nested message"
602 }
603 }
604}`,
605 wantMessage: &pb3.Nests{
606 SNested: &pb3.Nested{
607 SString: "nested message",
608 SNested: &pb3.Nested{
609 SString: "another nested message",
610 },
611 },
612 },
613 }, {
614 desc: "message set to non-message",
615 inputMessage: &pb3.Nests{},
616 inputText: `"not valid"`,
617 wantErr: true,
618 }, {
619 desc: "nested message set to non-message",
620 inputMessage: &pb3.Nests{},
621 inputText: `{"sNested": true}`,
622 wantErr: true,
623 }, {
624 desc: "oneof not set",
625 inputMessage: &pb3.Oneofs{},
626 inputText: "{}",
627 wantMessage: &pb3.Oneofs{},
628 }, {
629 desc: "oneof set to empty string",
630 inputMessage: &pb3.Oneofs{},
631 inputText: `{"oneofString": ""}`,
632 wantMessage: &pb3.Oneofs{
633 Union: &pb3.Oneofs_OneofString{},
634 },
635 }, {
636 desc: "oneof set to string",
637 inputMessage: &pb3.Oneofs{},
638 inputText: `{"oneofString": "hello"}`,
639 wantMessage: &pb3.Oneofs{
640 Union: &pb3.Oneofs_OneofString{
641 OneofString: "hello",
642 },
643 },
644 }, {
645 desc: "oneof set to enum",
646 inputMessage: &pb3.Oneofs{},
647 inputText: `{"oneofEnum": "ZERO"}`,
648 wantMessage: &pb3.Oneofs{
649 Union: &pb3.Oneofs_OneofEnum{
650 OneofEnum: pb3.Enum_ZERO,
651 },
652 },
653 }, {
654 desc: "oneof set to empty message",
655 inputMessage: &pb3.Oneofs{},
656 inputText: `{"oneofNested": {}}`,
657 wantMessage: &pb3.Oneofs{
658 Union: &pb3.Oneofs_OneofNested{
659 OneofNested: &pb3.Nested{},
660 },
661 },
662 }, {
663 desc: "oneof set to message",
664 inputMessage: &pb3.Oneofs{},
665 inputText: `{
666 "oneofNested": {
667 "sString": "nested message"
668 }
669}`,
670 wantMessage: &pb3.Oneofs{
671 Union: &pb3.Oneofs_OneofNested{
672 OneofNested: &pb3.Nested{
673 SString: "nested message",
674 },
675 },
676 },
677 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700678 desc: "oneof set to more than one field",
679 inputMessage: &pb3.Oneofs{},
680 inputText: `{
681 "oneofEnum": "ZERO",
682 "oneofString": "hello"
683}`,
684 wantErr: true,
685 }, {
686 desc: "oneof set to null and value",
687 inputMessage: &pb3.Oneofs{},
688 inputText: `{
689 "oneofEnum": "ZERO",
690 "oneofString": null
691}`,
692 wantMessage: &pb3.Oneofs{
693 Union: &pb3.Oneofs_OneofEnum{
694 OneofEnum: pb3.Enum_ZERO,
695 },
696 },
697 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800698 desc: "repeated null fields",
699 inputMessage: &pb2.Repeats{},
700 inputText: `{
701 "rptString": null,
702 "rptInt32" : null,
703 "rptFloat" : null,
704 "rptBytes" : null
705}`,
706 wantMessage: &pb2.Repeats{},
707 }, {
708 desc: "repeated scalars",
709 inputMessage: &pb2.Repeats{},
710 inputText: `{
711 "rptString": ["hello", "world"],
712 "rptInt32" : [-1, 0, 1],
713 "rptBool" : [false, true]
714}`,
715 wantMessage: &pb2.Repeats{
716 RptString: []string{"hello", "world"},
717 RptInt32: []int32{-1, 0, 1},
718 RptBool: []bool{false, true},
719 },
720 }, {
721 desc: "repeated enums",
722 inputMessage: &pb2.Enums{},
723 inputText: `{
724 "rptEnum" : ["TEN", 1, 42],
725 "rptNestedEnum": ["DOS", 2, -47]
726}`,
727 wantMessage: &pb2.Enums{
728 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
729 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
730 },
731 }, {
732 desc: "repeated messages",
733 inputMessage: &pb2.Nests{},
734 inputText: `{
735 "rptNested": [
736 {
737 "optString": "repeat nested one"
738 },
739 {
740 "optString": "repeat nested two",
741 "optNested": {
742 "optString": "inside repeat nested two"
743 }
744 },
745 {}
746 ]
747}`,
748 wantMessage: &pb2.Nests{
749 RptNested: []*pb2.Nested{
750 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700751 OptString: proto.String("repeat nested one"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800752 },
753 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700754 OptString: proto.String("repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800755 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700756 OptString: proto.String("inside repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800757 },
758 },
759 {},
760 },
761 },
762 }, {
763 desc: "repeated groups",
764 inputMessage: &pb2.Nests{},
765 inputText: `{
766 "rptgroup": [
767 {
768 "rptString": ["hello", "world"]
769 },
770 {}
771 ]
772}
773`,
774 wantMessage: &pb2.Nests{
775 Rptgroup: []*pb2.Nests_RptGroup{
776 {
777 RptString: []string{"hello", "world"},
778 },
779 {},
780 },
781 },
782 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700783 desc: "repeated string contains invalid UTF8",
784 inputMessage: &pb2.Repeats{},
785 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700786 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700787 }, {
788 desc: "repeated messages contain invalid UTF8",
789 inputMessage: &pb2.Nests{},
790 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700791 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -0700792 }, {
793 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800794 inputMessage: &pb2.Repeats{},
795 inputText: `{"rptString": ["hello", null, "world"]}`,
796 wantErr: true,
797 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700798 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800799 inputMessage: &pb2.Nests{},
800 inputText: `{"rptNested": [{}, null]}`,
801 wantErr: true,
802 }, {
803 desc: "map fields 1",
804 inputMessage: &pb3.Maps{},
805 inputText: `{
806 "int32ToStr": {
807 "-101": "-101",
808 "0" : "zero",
809 "255" : "0xff"
810 },
811 "boolToUint32": {
812 "false": 101,
813 "true" : "42"
814 }
815}`,
816 wantMessage: &pb3.Maps{
817 Int32ToStr: map[int32]string{
818 -101: "-101",
819 0xff: "0xff",
820 0: "zero",
821 },
822 BoolToUint32: map[bool]uint32{
823 true: 42,
824 false: 101,
825 },
826 },
827 }, {
828 desc: "map fields 2",
829 inputMessage: &pb3.Maps{},
830 inputText: `{
831 "uint64ToEnum": {
832 "1" : "ONE",
833 "2" : 2,
834 "10": 101
835 }
836}`,
837 wantMessage: &pb3.Maps{
838 Uint64ToEnum: map[uint64]pb3.Enum{
839 1: pb3.Enum_ONE,
840 2: pb3.Enum_TWO,
841 10: 101,
842 },
843 },
844 }, {
845 desc: "map fields 3",
846 inputMessage: &pb3.Maps{},
847 inputText: `{
848 "strToNested": {
849 "nested_one": {
850 "sString": "nested in a map"
851 },
852 "nested_two": {}
853 }
854}`,
855 wantMessage: &pb3.Maps{
856 StrToNested: map[string]*pb3.Nested{
857 "nested_one": {
858 SString: "nested in a map",
859 },
860 "nested_two": {},
861 },
862 },
863 }, {
864 desc: "map fields 4",
865 inputMessage: &pb3.Maps{},
866 inputText: `{
867 "strToOneofs": {
868 "nested": {
869 "oneofNested": {
870 "sString": "nested oneof in map field value"
871 }
872 },
873 "string": {
874 "oneofString": "hello"
875 }
876 }
877}`,
878 wantMessage: &pb3.Maps{
879 StrToOneofs: map[string]*pb3.Oneofs{
880 "string": {
881 Union: &pb3.Oneofs_OneofString{
882 OneofString: "hello",
883 },
884 },
885 "nested": {
886 Union: &pb3.Oneofs_OneofNested{
887 OneofNested: &pb3.Nested{
888 SString: "nested oneof in map field value",
889 },
890 },
891 },
892 },
893 },
894 }, {
895 desc: "map contains duplicate keys",
896 inputMessage: &pb3.Maps{},
897 inputText: `{
898 "int32ToStr": {
899 "0": "cero",
900 "0": "zero"
901 }
902}
903`,
904 wantErr: true,
905 }, {
906 desc: "map key empty string",
907 inputMessage: &pb3.Maps{},
908 inputText: `{
909 "strToNested": {
910 "": {}
911 }
912}`,
913 wantMessage: &pb3.Maps{
914 StrToNested: map[string]*pb3.Nested{
915 "": {},
916 },
917 },
918 }, {
919 desc: "map contains invalid key 1",
920 inputMessage: &pb3.Maps{},
921 inputText: `{
922 "int32ToStr": {
923 "invalid": "cero"
924}`,
925 wantErr: true,
926 }, {
927 desc: "map contains invalid key 2",
928 inputMessage: &pb3.Maps{},
929 inputText: `{
930 "int32ToStr": {
931 "1.02": "float"
932}`,
933 wantErr: true,
934 }, {
935 desc: "map contains invalid key 3",
936 inputMessage: &pb3.Maps{},
937 inputText: `{
938 "int32ToStr": {
939 "2147483648": "exceeds 32-bit integer max limit"
940}`,
941 wantErr: true,
942 }, {
943 desc: "map contains invalid key 4",
944 inputMessage: &pb3.Maps{},
945 inputText: `{
946 "uint64ToEnum": {
947 "-1": 0
948 }
949}`,
950 wantErr: true,
951 }, {
952 desc: "map contains invalid value",
953 inputMessage: &pb3.Maps{},
954 inputText: `{
955 "int32ToStr": {
956 "101": true
957}`,
958 wantErr: true,
959 }, {
960 desc: "map contains null for scalar value",
961 inputMessage: &pb3.Maps{},
962 inputText: `{
963 "int32ToStr": {
964 "101": null
965}`,
966 wantErr: true,
967 }, {
968 desc: "map contains null for message value",
969 inputMessage: &pb3.Maps{},
970 inputText: `{
971 "strToNested": {
972 "hello": null
973 }
974}`,
975 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -0700976 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700977 desc: "map contains contains message value with invalid UTF8",
978 inputMessage: &pb3.Maps{},
979 inputText: `{
980 "strToNested": {
981 "hello": {
982 "sString": "` + "abc\xff" + `"
983 }
984 }
985}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700986 wantErr: true,
987 }, {
988 desc: "map key contains invalid UTF8",
989 inputMessage: &pb3.Maps{},
990 inputText: `{
991 "strToNested": {
992 "` + "abc\xff" + `": {}
993 }
994}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700995 wantErr: true,
996 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -0700997 desc: "required fields not set",
998 inputMessage: &pb2.Requireds{},
999 wantErr: true,
1000 }, {
1001 desc: "required field set",
1002 inputMessage: &pb2.PartialRequired{},
1003 inputText: `{
1004 "reqString": "this is required"
1005}`,
1006 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001007 ReqString: proto.String("this is required"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001008 },
1009 }, {
1010 desc: "required fields partially set",
1011 inputMessage: &pb2.Requireds{},
1012 inputText: `{
1013 "reqBool": false,
1014 "reqSfixed64": 42,
1015 "reqString": "hello",
1016 "reqEnum": "ONE"
1017}`,
1018 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001019 ReqBool: proto.Bool(false),
1020 ReqSfixed64: proto.Int64(42),
1021 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001022 ReqEnum: pb2.Enum_ONE.Enum(),
1023 },
1024 wantErr: true,
1025 }, {
1026 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001027 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001028 inputMessage: &pb2.Requireds{},
1029 inputText: `{
1030 "reqBool": false,
1031 "reqSfixed64": 42,
1032 "reqString": "hello",
1033 "reqEnum": "ONE"
1034}`,
1035 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001036 ReqBool: proto.Bool(false),
1037 ReqSfixed64: proto.Int64(42),
1038 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001039 ReqEnum: pb2.Enum_ONE.Enum(),
1040 },
1041 }, {
1042 desc: "required fields all set",
1043 inputMessage: &pb2.Requireds{},
1044 inputText: `{
1045 "reqBool": false,
1046 "reqSfixed64": 42,
1047 "reqDouble": 1.23,
1048 "reqString": "hello",
1049 "reqEnum": "ONE",
1050 "reqNested": {}
1051}`,
1052 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001053 ReqBool: proto.Bool(false),
1054 ReqSfixed64: proto.Int64(42),
1055 ReqDouble: proto.Float64(1.23),
1056 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001057 ReqEnum: pb2.Enum_ONE.Enum(),
1058 ReqNested: &pb2.Nested{},
1059 },
1060 }, {
1061 desc: "indirect required field",
1062 inputMessage: &pb2.IndirectRequired{},
1063 inputText: `{
1064 "optNested": {}
1065}`,
1066 wantMessage: &pb2.IndirectRequired{
1067 OptNested: &pb2.NestedWithRequired{},
1068 },
1069 wantErr: true,
1070 }, {
1071 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001072 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001073 inputMessage: &pb2.IndirectRequired{},
1074 inputText: `{
1075 "optNested": {}
1076}`,
1077 wantMessage: &pb2.IndirectRequired{
1078 OptNested: &pb2.NestedWithRequired{},
1079 },
1080 }, {
1081 desc: "indirect required field in repeated",
1082 inputMessage: &pb2.IndirectRequired{},
1083 inputText: `{
1084 "rptNested": [
1085 {"reqString": "one"},
1086 {}
1087 ]
1088}`,
1089 wantMessage: &pb2.IndirectRequired{
1090 RptNested: []*pb2.NestedWithRequired{
1091 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001092 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001093 },
1094 {},
1095 },
1096 },
1097 wantErr: true,
1098 }, {
1099 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001100 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001101 inputMessage: &pb2.IndirectRequired{},
1102 inputText: `{
1103 "rptNested": [
1104 {"reqString": "one"},
1105 {}
1106 ]
1107}`,
1108 wantMessage: &pb2.IndirectRequired{
1109 RptNested: []*pb2.NestedWithRequired{
1110 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001111 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001112 },
1113 {},
1114 },
1115 },
1116 }, {
1117 desc: "indirect required field in map",
1118 inputMessage: &pb2.IndirectRequired{},
1119 inputText: `{
1120 "strToNested": {
1121 "missing": {},
1122 "contains": {
1123 "reqString": "here"
1124 }
1125 }
1126}`,
1127 wantMessage: &pb2.IndirectRequired{
1128 StrToNested: map[string]*pb2.NestedWithRequired{
1129 "missing": &pb2.NestedWithRequired{},
1130 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001131 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001132 },
1133 },
1134 },
1135 wantErr: true,
1136 }, {
1137 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001138 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001139 inputMessage: &pb2.IndirectRequired{},
1140 inputText: `{
1141 "strToNested": {
1142 "missing": {},
1143 "contains": {
1144 "reqString": "here"
1145 }
1146 }
1147}`,
1148 wantMessage: &pb2.IndirectRequired{
1149 StrToNested: map[string]*pb2.NestedWithRequired{
1150 "missing": &pb2.NestedWithRequired{},
1151 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001152 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001153 },
1154 },
1155 },
1156 }, {
1157 desc: "indirect required field in oneof",
1158 inputMessage: &pb2.IndirectRequired{},
1159 inputText: `{
1160 "oneofNested": {}
1161}`,
1162 wantMessage: &pb2.IndirectRequired{
1163 Union: &pb2.IndirectRequired_OneofNested{
1164 OneofNested: &pb2.NestedWithRequired{},
1165 },
1166 },
1167 wantErr: true,
1168 }, {
1169 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001170 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001171 inputMessage: &pb2.IndirectRequired{},
1172 inputText: `{
1173 "oneofNested": {}
1174}`,
1175 wantMessage: &pb2.IndirectRequired{
1176 Union: &pb2.IndirectRequired_OneofNested{
1177 OneofNested: &pb2.NestedWithRequired{},
1178 },
1179 },
1180 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001181 desc: "extensions of non-repeated fields",
1182 inputMessage: &pb2.Extensions{},
1183 inputText: `{
1184 "optString": "non-extension field",
1185 "optBool": true,
1186 "optInt32": 42,
1187 "[pb2.opt_ext_bool]": true,
1188 "[pb2.opt_ext_nested]": {
1189 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001190 "optNested": {
1191 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001192 }
1193 },
1194 "[pb2.opt_ext_string]": "extension field",
1195 "[pb2.opt_ext_enum]": "TEN"
1196}`,
1197 wantMessage: func() proto.Message {
1198 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001199 OptString: proto.String("non-extension field"),
1200 OptBool: proto.Bool(true),
1201 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001202 }
1203 setExtension(m, pb2.E_OptExtBool, true)
1204 setExtension(m, pb2.E_OptExtString, "extension field")
1205 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1206 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001207 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001208 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001209 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001210 },
1211 })
1212 return m
1213 }(),
1214 }, {
1215 desc: "extensions of repeated fields",
1216 inputMessage: &pb2.Extensions{},
1217 inputText: `{
1218 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1219 "[pb2.rpt_ext_fixed32]": [42, 47],
1220 "[pb2.rpt_ext_nested]": [
1221 {"optString": "one"},
1222 {"optString": "two"},
1223 {"optString": "three"}
1224 ]
1225}`,
1226 wantMessage: func() proto.Message {
1227 m := &pb2.Extensions{}
1228 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1229 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1230 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001231 &pb2.Nested{OptString: proto.String("one")},
1232 &pb2.Nested{OptString: proto.String("two")},
1233 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001234 })
1235 return m
1236 }(),
1237 }, {
1238 desc: "extensions of non-repeated fields in another message",
1239 inputMessage: &pb2.Extensions{},
1240 inputText: `{
1241 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1242 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1243 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1244 "optString": "nested in an extension",
1245 "optNested": {
1246 "optString": "another nested in an extension"
1247 }
1248 },
1249 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1250}`,
1251 wantMessage: func() proto.Message {
1252 m := &pb2.Extensions{}
1253 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1254 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1255 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1256 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001257 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001258 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001259 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001260 },
1261 })
1262 return m
1263 }(),
1264 }, {
1265 desc: "extensions of repeated fields in another message",
1266 inputMessage: &pb2.Extensions{},
1267 inputText: `{
1268 "optString": "non-extension field",
1269 "optBool": true,
1270 "optInt32": 42,
1271 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1272 {"optString": "one"},
1273 {"optString": "two"},
1274 {"optString": "three"}
1275 ],
1276 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1277 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1278}`,
1279 wantMessage: func() proto.Message {
1280 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001281 OptString: proto.String("non-extension field"),
1282 OptBool: proto.Bool(true),
1283 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001284 }
1285 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1286 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1287 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001288 &pb2.Nested{OptString: proto.String("one")},
1289 &pb2.Nested{OptString: proto.String("two")},
1290 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001291 })
1292 return m
1293 }(),
1294 }, {
1295 desc: "invalid extension field name",
1296 inputMessage: &pb2.Extensions{},
1297 inputText: `{ "[pb2.invalid_message_field]": true }`,
1298 wantErr: true,
1299 }, {
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001300 desc: "extensions of repeated field contains null",
1301 inputMessage: &pb2.Extensions{},
1302 inputText: `{
1303 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1304 {"optString": "one"},
1305 null,
1306 {"optString": "three"}
1307 ],
1308}`,
1309 wantErr: true,
1310 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001311 desc: "MessageSet",
1312 inputMessage: &pb2.MessageSet{},
1313 inputText: `{
1314 "[pb2.MessageSetExtension]": {
1315 "optString": "a messageset extension"
1316 },
1317 "[pb2.MessageSetExtension.ext_nested]": {
1318 "optString": "just a regular extension"
1319 },
1320 "[pb2.MessageSetExtension.not_message_set_extension]": {
1321 "optString": "not a messageset extension"
1322 }
1323}`,
1324 wantMessage: func() proto.Message {
1325 m := &pb2.MessageSet{}
1326 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001327 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001328 })
1329 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001330 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001331 })
1332 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001333 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001334 })
1335 return m
1336 }(),
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001337 skip: !flags.Proto1Legacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001338 }, {
1339 desc: "not real MessageSet 1",
1340 inputMessage: &pb2.FakeMessageSet{},
1341 inputText: `{
1342 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1343 "optString": "not a messageset extension"
1344 }
1345}`,
1346 wantMessage: func() proto.Message {
1347 m := &pb2.FakeMessageSet{}
1348 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001349 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001350 })
1351 return m
1352 }(),
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001353 skip: !flags.Proto1Legacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001354 }, {
1355 desc: "not real MessageSet 2",
1356 inputMessage: &pb2.FakeMessageSet{},
1357 inputText: `{
1358 "[pb2.FakeMessageSetExtension]": {
1359 "optString": "not a messageset extension"
1360 }
1361}`,
1362 wantErr: true,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001363 skip: !flags.Proto1Legacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001364 }, {
1365 desc: "not real MessageSet 3",
1366 inputMessage: &pb2.MessageSet{},
1367 inputText: `{
1368 "[pb2.message_set_extension]": {
1369 "optString": "another not a messageset extension"
1370 }
1371}`,
1372 wantMessage: func() proto.Message {
1373 m := &pb2.MessageSet{}
1374 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001375 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001376 })
1377 return m
1378 }(),
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001379 skip: !flags.Proto1Legacy,
Herbie Onge63c4c42019-03-22 22:20:22 -07001380 }, {
1381 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001382 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001383 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001384 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001385 }, {
1386 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001387 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001388 inputText: `{"unknown": null}`,
1389 wantErr: true,
1390 }, {
1391 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001392 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001393 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001394 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001395 }, {
1396 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001397 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001398 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001399 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001400 }, {
1401 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001402 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001403 inputText: `{}`,
1404 wantErr: true,
1405 }, {
1406 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001407 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001408 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001410 }, {
1411 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001412 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001413 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001414 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001415 }, {
1416 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001417 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001418 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001419 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001420 }, {
1421 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001422 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001423 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001424 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001425 }, {
1426 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001427 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001428 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001429 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001430 }, {
1431 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001432 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001433 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001435 }, {
1436 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001437 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001438 inputText: `1.23+40`,
1439 wantErr: true,
1440 }, {
1441 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001442 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001443 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001445 }, {
1446 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001447 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001448 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001449 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001450 }, {
1451 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001452 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001453 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001455 }, {
1456 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001457 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001458 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001459 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001460 }, {
1461 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001463 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001464 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001465 }, {
1466 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001467 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001468 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001469 wantErr: true,
1470 }, {
1471 desc: "StringValue field with invalid UTF8 error",
1472 inputMessage: &pb2.KnownTypes{},
1473 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001474 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001475 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001476 desc: "NullValue field with JSON null",
1477 inputMessage: &pb2.KnownTypes{},
1478 inputText: `{
1479 "optNull": null
1480}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001481 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001482 }, {
1483 desc: "NullValue field with string",
1484 inputMessage: &pb2.KnownTypes{},
1485 inputText: `{
1486 "optNull": "NULL_VALUE"
1487}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001488 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001489 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001490 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001491 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001492 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001493 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001494 }, {
1495 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001496 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001497 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001498 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001499 }, {
1500 desc: "Value field null",
1501 inputMessage: &pb2.KnownTypes{},
1502 inputText: `{
1503 "optValue": null
1504}`,
1505 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001506 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001507 },
1508 }, {
1509 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001510 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001511 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001512 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001513 }, {
1514 desc: "Value field bool",
1515 inputMessage: &pb2.KnownTypes{},
1516 inputText: `{
1517 "optValue": true
1518}`,
1519 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001520 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001521 },
1522 }, {
1523 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001524 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001525 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001526 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001527 }, {
1528 desc: "Value field number",
1529 inputMessage: &pb2.KnownTypes{},
1530 inputText: `{
1531 "optValue": 1.02
1532}`,
1533 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001534 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001535 },
1536 }, {
1537 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001538 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001539 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001540 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001541 }, {
1542 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001543 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001544 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001545 wantErr: true,
1546 }, {
1547 desc: "Value field string",
1548 inputMessage: &pb2.KnownTypes{},
1549 inputText: `{
1550 "optValue": "NaN"
1551}`,
1552 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001553 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001554 },
1555 }, {
1556 desc: "Value field string with invalid UTF8",
1557 inputMessage: &pb2.KnownTypes{},
1558 inputText: `{
1559 "optValue": "` + "\xff" + `"
1560}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001561 wantErr: true,
1562 }, {
1563 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001564 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001565 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001566 wantMessage: &structpb.Value{
1567 Kind: &structpb.Value_StructValue{
1568 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001569 },
1570 },
1571 }, {
1572 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001573 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001574 inputText: `{
1575 "string": "hello",
1576 "number": 123,
1577 "null": null,
1578 "bool": false,
1579 "struct": {
1580 "string": "world"
1581 },
1582 "list": []
1583}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001584 wantMessage: &structpb.Value{
1585 Kind: &structpb.Value_StructValue{
1586 &structpb.Struct{
1587 Fields: map[string]*structpb.Value{
1588 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1589 "number": {Kind: &structpb.Value_NumberValue{123}},
1590 "null": {Kind: &structpb.Value_NullValue{}},
1591 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001592 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001593 Kind: &structpb.Value_StructValue{
1594 &structpb.Struct{
1595 Fields: map[string]*structpb.Value{
1596 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001597 },
1598 },
1599 },
1600 },
1601 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001602 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001603 },
1604 },
1605 },
1606 },
1607 },
1608 }, {
1609 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001610 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001611 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001612 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001613 }, {
1614 desc: "Value field struct",
1615 inputMessage: &pb2.KnownTypes{},
1616 inputText: `{
1617 "optValue": {
1618 "string": "hello"
1619 }
1620}`,
1621 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001622 OptValue: &structpb.Value{
1623 Kind: &structpb.Value_StructValue{
1624 &structpb.Struct{
1625 Fields: map[string]*structpb.Value{
1626 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001627 },
1628 },
1629 },
1630 },
1631 },
1632 }, {
1633 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001634 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001635 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001636 wantMessage: &structpb.Value{
1637 Kind: &structpb.Value_ListValue{
1638 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001639 },
1640 },
1641 }, {
1642 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001643 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001644 inputText: `[
1645 "string",
1646 123,
1647 null,
1648 true,
1649 {},
1650 [
1651 "string",
1652 1.23,
1653 null,
1654 false
1655 ]
1656]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001657 wantMessage: &structpb.Value{
1658 Kind: &structpb.Value_ListValue{
1659 &structpb.ListValue{
1660 Values: []*structpb.Value{
1661 {Kind: &structpb.Value_StringValue{"string"}},
1662 {Kind: &structpb.Value_NumberValue{123}},
1663 {Kind: &structpb.Value_NullValue{}},
1664 {Kind: &structpb.Value_BoolValue{true}},
1665 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001666 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001667 Kind: &structpb.Value_ListValue{
1668 &structpb.ListValue{
1669 Values: []*structpb.Value{
1670 {Kind: &structpb.Value_StringValue{"string"}},
1671 {Kind: &structpb.Value_NumberValue{1.23}},
1672 {Kind: &structpb.Value_NullValue{}},
1673 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001674 },
1675 },
1676 },
1677 },
1678 },
1679 },
1680 },
1681 },
1682 }, {
1683 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001684 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001685 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001686 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001687 }, {
1688 desc: "Value field list with invalid UTF8 string",
1689 inputMessage: &pb2.KnownTypes{},
1690 inputText: `{
1691 "optValue": [ "` + "abc\xff" + `"]
1692}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001693 wantErr: true,
1694 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001695 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001696 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001697 inputText: `""`,
1698 wantErr: true,
1699 }, {
1700 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001701 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001702 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001703 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001704 }, {
1705 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001706 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001707 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001708 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001709 }, {
1710 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001711 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001712 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001713 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001714 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001715 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001716 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001717 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001718 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001719 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001720 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001721 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001722 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001723 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001724 }, {
1725 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001726 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001727 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001728 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001729 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001730 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001731 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001732 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001733 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001734 }, {
1735 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001736 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001737 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001738 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001739 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001740 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001741 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001742 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001743 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001744 }, {
1745 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001746 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001747 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001748 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001749 }, {
1750 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001751 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001752 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001753 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001754 }, {
1755 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001756 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001757 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001758 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001759 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001760 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001761 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001762 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001764 }, {
1765 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001766 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001767 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001768 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001769 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001770 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001771 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001772 inputText: `"315576000001s"`,
1773 wantErr: true,
1774 }, {
1775 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001776 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001777 inputText: `"-315576000001s"`,
1778 wantErr: true,
1779 }, {
1780 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001781 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001782 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001783 wantErr: true,
1784 }, {
1785 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001786 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001787 inputText: `"123"`,
1788 wantErr: true,
1789 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001790 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001791 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001792 inputText: `"123.+123s"`,
1793 wantErr: true,
1794 }, {
1795 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001796 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001797 inputText: `"123.123.s"`,
1798 wantErr: true,
1799 }, {
1800 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001801 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001802 inputText: `"01s"`,
1803 wantErr: true,
1804 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001805 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001806 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001807 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001808 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001809 }, {
1810 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001811 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001812 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001813 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001814 }, {
1815 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001816 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001817 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001818 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001819 }, {
1820 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001821 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001822 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001824 }, {
1825 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001826 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001827 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001830 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001831 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001832 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001835 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001836 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001837 inputText: `"9999-12-31T23:59:59-01:00"`,
1838 wantErr: true,
1839 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001840 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001841 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001842 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001844 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001845 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001846 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001847 inputText: `"0001-01-01T00:00:00+01:00"`,
1848 wantErr: true,
1849 }, {
1850 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001851 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001852 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1853 wantErr: true,
1854 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001855 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001856 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001857 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001858 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001859 }, {
1860 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001861 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001862 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001863 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001864 Paths: []string{
1865 "foo",
1866 "foo_bar",
1867 "foo.bar_qux",
1868 "_foo",
1869 },
1870 },
1871 }, {
1872 desc: "FieldMask field",
1873 inputMessage: &pb2.KnownTypes{},
1874 inputText: `{
1875 "optFieldmask": "foo, qux.fooBar"
1876}`,
1877 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001878 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001879 Paths: []string{
1880 "foo",
1881 "qux.foo_bar",
1882 },
1883 },
1884 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001885 }, {
1886 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001887 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001888 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001889 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001890 }, {
1891 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001892 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001893 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001894 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001895 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001896 inputText: `{
1897 "@type": "foo/pb2.Nested",
1898 "optString": "embedded inside Any",
1899 "optNested": {
1900 "optString": "inception"
1901 }
1902}`,
1903 wantMessage: func() proto.Message {
1904 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001905 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001906 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001907 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001908 },
1909 }
1910 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1911 if err != nil {
1912 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1913 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001914 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001915 TypeUrl: "foo/pb2.Nested",
1916 Value: b,
1917 }
1918 }(),
1919 }, {
1920 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001921 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001922 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001923 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001924 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001925 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001926 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001927 }, {
1928 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001929 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001930 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001931 inputText: `{"@type": "foo/pb2.Nested"}`,
1932 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001933 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001934 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001935 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001936 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001937 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001938 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001939 inputText: `{
1940 "@type": "pb2.PartialRequired",
1941 "optString": "embedded inside Any"
1942}`,
1943 wantMessage: func() proto.Message {
1944 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001945 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001946 }
Damien Neil96c229a2019-04-03 12:17:24 -07001947 b, err := proto.MarshalOptions{
1948 Deterministic: true,
1949 AllowPartial: true,
1950 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001951 if err != nil {
1952 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1953 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001954 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001955 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001956 Value: b,
1957 }
1958 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001959 }, {
1960 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001961 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001962 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001963 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001964 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001965 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001966 inputText: `{
1967 "@type": "pb2.PartialRequired",
1968 "optString": "embedded inside Any"
1969}`,
1970 wantMessage: func() proto.Message {
1971 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001972 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001973 }
Damien Neil96c229a2019-04-03 12:17:24 -07001974 b, err := proto.MarshalOptions{
1975 Deterministic: true,
1976 AllowPartial: true,
1977 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001978 if err != nil {
1979 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1980 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001981 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001982 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001983 Value: b,
1984 }
1985 }(),
1986 }, {
1987 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001988 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001989 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001990 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001991 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001992 inputText: `{
1993 "optString": "` + "abc\xff" + `",
1994 "@type": "foo/pb2.Nested"
1995}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001996 wantErr: true,
1997 }, {
1998 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07001999 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002000 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002001 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002002 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002003 inputText: `{
2004 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2005 "value": true
2006}`,
2007 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002008 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002009 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2010 if err != nil {
2011 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2012 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002013 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002014 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2015 Value: b,
2016 }
2017 }(),
2018 }, {
2019 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002020 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002021 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002022 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002023 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002024 inputText: `{
2025 "value": {},
2026 "@type": "type.googleapis.com/google.protobuf.Empty"
2027}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002028 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002029 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2030 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002031 }, {
2032 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002033 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002034 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002035 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002036 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002037 inputText: `{
2038 "@type": "type.googleapis.com/google.protobuf.Empty"
2039}`,
2040 wantErr: true,
2041 }, {
2042 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002043 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002044 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002045 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002046 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002047 inputText: `{
2048 "@type": "google.protobuf.StringValue",
2049 "value": "` + "abc\xff" + `"
2050}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002051 wantErr: true,
2052 }, {
2053 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002054 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002055 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002056 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002057 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002058 inputText: `{
2059 "@type": "google.protobuf.Int64Value",
2060 "value": "42"
2061}`,
2062 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002063 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002064 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2065 if err != nil {
2066 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2067 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002068 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002069 TypeUrl: "google.protobuf.Int64Value",
2070 Value: b,
2071 }
2072 }(),
2073 }, {
2074 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002075 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002076 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002077 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002078 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002079 inputText: `{
2080 "@type": "google.protobuf.Int64Value",
2081 "value": "forty-two"
2082}`,
2083 wantErr: true,
2084 }, {
2085 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002086 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002087 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002088 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002089 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002090 inputText: `{
2091 "@type": "google.protobuf.UInt64Value",
2092 "value": -42
2093}`,
2094 wantErr: true,
2095 }, {
2096 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002097 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002098 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002099 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002100 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002101 inputText: `{
2102 "@type": "type.googleapis.com/google.protobuf.Duration",
2103 "value": "0s"
2104}`,
2105 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002106 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002107 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2108 if err != nil {
2109 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2110 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002111 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002112 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2113 Value: b,
2114 }
2115 }(),
2116 }, {
2117 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002118 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002119 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002120 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002121 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002122 inputText: `{
2123 "@type": "google.protobuf.Value",
2124 "value": "` + "abc\xff" + `"
2125}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002126 wantErr: true,
2127 }, {
2128 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002129 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002130 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002131 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002132 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002133 inputText: `{
2134 "@type": "google.protobuf.Value",
2135 "value": null
2136}`,
2137 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002138 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002139 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2140 if err != nil {
2141 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2142 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002143 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002144 TypeUrl: "google.protobuf.Value",
2145 Value: b,
2146 }
2147 }(),
2148 }, {
2149 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002150 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002151 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002152 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2153 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2154 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2155 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2156 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002157 ),
2158 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002159 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002160 inputText: `{
2161 "@type": "google.protobuf.Struct",
2162 "value": {
2163 "bool": true,
2164 "null": null,
2165 "string": "hello",
2166 "struct": {
2167 "string": "world"
2168 }
2169 }
2170}`,
2171 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002172 m := &structpb.Struct{
2173 Fields: map[string]*structpb.Value{
2174 "bool": {Kind: &structpb.Value_BoolValue{true}},
2175 "null": {Kind: &structpb.Value_NullValue{}},
2176 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002177 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002178 Kind: &structpb.Value_StructValue{
2179 &structpb.Struct{
2180 Fields: map[string]*structpb.Value{
2181 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002182 },
2183 },
2184 },
2185 },
2186 },
2187 }
2188 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2189 if err != nil {
2190 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2191 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002192 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002193 TypeUrl: "google.protobuf.Struct",
2194 Value: b,
2195 }
2196 }(),
2197 }, {
2198 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002199 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002200 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002201 inputText: `{
2202 "value": {}
2203}`,
2204 wantErr: true,
2205 }, {
2206 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002207 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002208 inputText: `{
2209 "@type": ""
2210}`,
2211 wantErr: true,
2212 }, {
2213 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002214 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002215 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002216 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002217 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002218 ),
2219 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002220 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002221 inputText: `{
2222 "@type": "google.protobuf.StringValue",
2223 "value": "hello",
2224 "@type": "pb2.Nested"
2225}`,
2226 wantErr: true,
2227 }, {
2228 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002229 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002230 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002231 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002232 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002233 inputText: `{
2234 "@type": "google.protobuf.StringValue",
2235 "value": "hello",
2236 "value": "world"
2237}`,
2238 wantErr: true,
2239 }, {
2240 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002241 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002242 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002243 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002244 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002245 inputText: `{
2246 "@type": "pb2.Nested",
2247 "optString": "hello",
2248 "unknown": "world"
2249}`,
2250 wantErr: true,
2251 }, {
2252 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002253 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002254 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002255 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002256 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2257 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002258 ),
2259 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002260 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002261 inputText: `{
2262 "@type": "pb2.KnownTypes",
2263 "optAny": {
2264 "@type": "google.protobuf.StringValue",
2265 "value": "` + "abc\xff" + `"
2266 }
2267}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002268 wantErr: true,
2269 }, {
2270 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002271 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002272 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002273 },
2274 inputMessage: &pb2.KnownTypes{},
2275 inputText: `{
2276 "optBool": false,
2277 "optInt32": 42,
2278 "optInt64": "42",
2279 "optUint32": 42,
2280 "optUint64": "42",
2281 "optFloat": 1.23,
2282 "optDouble": 3.1415,
2283 "optString": "hello",
2284 "optBytes": "aGVsbG8=",
2285 "optDuration": "123s",
2286 "optTimestamp": "2019-03-19T23:03:21Z",
2287 "optStruct": {
2288 "string": "hello"
2289 },
2290 "optList": [
2291 null,
2292 "",
2293 {},
2294 []
2295 ],
2296 "optValue": "world",
2297 "optEmpty": {},
2298 "optAny": {
2299 "@type": "google.protobuf.Empty",
2300 "value": {}
2301 },
2302 "optFieldmask": "fooBar,barFoo"
2303}`,
2304 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002305 OptBool: &wrapperspb.BoolValue{Value: false},
2306 OptInt32: &wrapperspb.Int32Value{Value: 42},
2307 OptInt64: &wrapperspb.Int64Value{Value: 42},
2308 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2309 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2310 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2311 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2312 OptString: &wrapperspb.StringValue{Value: "hello"},
2313 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2314 OptDuration: &durationpb.Duration{Seconds: 123},
2315 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2316 OptStruct: &structpb.Struct{
2317 Fields: map[string]*structpb.Value{
2318 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002319 },
2320 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002321 OptList: &structpb.ListValue{
2322 Values: []*structpb.Value{
2323 {Kind: &structpb.Value_NullValue{}},
2324 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002325 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002326 Kind: &structpb.Value_StructValue{
2327 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002328 },
2329 },
2330 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002331 Kind: &structpb.Value_ListValue{
2332 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002333 },
2334 },
2335 },
2336 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002337 OptValue: &structpb.Value{
2338 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002339 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002340 OptEmpty: &emptypb.Empty{},
2341 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002342 TypeUrl: "google.protobuf.Empty",
2343 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002344 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002345 Paths: []string{"foo_bar", "bar_foo"},
2346 },
2347 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002348 }, {
2349 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002350 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002351 inputMessage: &pb3.Nests{},
2352 inputText: `{
2353 "sNested": {
2354 "unknown": {
2355 "foo": 1,
2356 "bar": [1, 2, 3]
2357 }
2358 },
2359 "unknown": "not known"
2360}`,
2361 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2362 }, {
2363 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002364 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002365 inputMessage: &pb2.Nests{},
2366 inputText: `{
2367 "rptNested": [
2368 {"unknown": "blah"},
2369 {"optString": "hello"}
2370 ]
2371}`,
2372 wantMessage: &pb2.Nests{
2373 RptNested: []*pb2.Nested{
2374 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002375 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002376 },
2377 },
2378 }, {
2379 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002380 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002381 inputMessage: &pb3.Maps{},
2382 inputText: `{
2383 "strToNested": {
2384 "nested_one": {
2385 "unknown": "what you see is not"
2386 }
2387 }
2388}`,
2389 wantMessage: &pb3.Maps{
2390 StrToNested: map[string]*pb3.Nested{
2391 "nested_one": {},
2392 },
2393 },
2394 }, {
2395 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002396 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002397 inputMessage: &pb2.Extensions{},
2398 inputText: `{
2399 "[pb2.opt_ext_nested]": {
2400 "unknown": []
2401 }
2402}`,
2403 wantMessage: func() proto.Message {
2404 m := &pb2.Extensions{}
2405 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2406 return m
2407 }(),
2408 }, {
2409 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002410 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002411 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002412 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002413 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002414 }, {
2415 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002416 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002417 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002418 inputText: `{
2419 "value": {"foo": "bar"},
2420 "unknown": true
2421}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002422 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002423 }, {
2424 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002425 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002426 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002427 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002428 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002429 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002430 inputText: `{
2431 "@type": "foo/pb2.Nested",
2432 "unknown": "none"
2433}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002434 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002435 TypeUrl: "foo/pb2.Nested",
2436 },
2437 }, {
2438 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002439 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002440 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002441 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002442 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002443 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002444 inputText: `{
2445 "@type": "type.googleapis.com/google.protobuf.Empty",
2446 "value": {"unknown": 47}
2447}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002448 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002449 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2450 },
Joe Tsaid47ea192019-07-09 22:38:15 -07002451 }, {
2452 desc: "weak fields",
2453 inputMessage: &testpb.TestWeak{},
2454 inputText: `{"weak_message1":{"a":1}}`,
2455 wantMessage: func() *testpb.TestWeak {
2456 m := new(testpb.TestWeak)
2457 m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
2458 return m
2459 }(),
2460 skip: !flags.Proto1Legacy,
2461 }, {
2462 desc: "weak fields; unknown field",
2463 inputMessage: &testpb.TestWeak{},
2464 inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
2465 wantErr: true, // weak_message2 is unknown since the package containing it is not imported
2466 skip: !flags.Proto1Legacy,
Herbie Ongc96a79d2019-03-08 10:49:17 -08002467 }}
2468
2469 for _, tt := range tests {
2470 tt := tt
Joe Tsaid47ea192019-07-09 22:38:15 -07002471 if tt.skip {
2472 continue
2473 }
Herbie Ongc96a79d2019-03-08 10:49:17 -08002474 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002475 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002476 if err != nil && !tt.wantErr {
2477 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2478 }
2479 if err == nil && tt.wantErr {
2480 t.Error("Unmarshal() got nil error, want error\n\n")
2481 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002482 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002483 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2484 }
2485 })
2486 }
2487}