blob: 03bd10a74893099143df01e87c596adf587b7afd [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 }, {
1300 desc: "MessageSet",
1301 inputMessage: &pb2.MessageSet{},
1302 inputText: `{
1303 "[pb2.MessageSetExtension]": {
1304 "optString": "a messageset extension"
1305 },
1306 "[pb2.MessageSetExtension.ext_nested]": {
1307 "optString": "just a regular extension"
1308 },
1309 "[pb2.MessageSetExtension.not_message_set_extension]": {
1310 "optString": "not a messageset extension"
1311 }
1312}`,
1313 wantMessage: func() proto.Message {
1314 m := &pb2.MessageSet{}
1315 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001316 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001317 })
1318 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001319 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001320 })
1321 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001322 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001323 })
1324 return m
1325 }(),
1326 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001327 desc: "extensions of repeated field contains null",
1328 inputMessage: &pb2.Extensions{},
1329 inputText: `{
1330 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1331 {"optString": "one"},
1332 null,
1333 {"optString": "three"}
1334 ],
1335}`,
1336 wantErr: true,
1337 }, {
1338 desc: "not real MessageSet 1",
1339 inputMessage: &pb2.FakeMessageSet{},
1340 inputText: `{
1341 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1342 "optString": "not a messageset extension"
1343 }
1344}`,
1345 wantMessage: func() proto.Message {
1346 m := &pb2.FakeMessageSet{}
1347 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001348 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001349 })
1350 return m
1351 }(),
1352 }, {
1353 desc: "not real MessageSet 2",
1354 inputMessage: &pb2.FakeMessageSet{},
1355 inputText: `{
1356 "[pb2.FakeMessageSetExtension]": {
1357 "optString": "not a messageset extension"
1358 }
1359}`,
1360 wantErr: true,
1361 }, {
1362 desc: "not real MessageSet 3",
1363 inputMessage: &pb2.MessageSet{},
1364 inputText: `{
1365 "[pb2.message_set_extension]": {
1366 "optString": "another not a messageset extension"
1367 }
1368}`,
1369 wantMessage: func() proto.Message {
1370 m := &pb2.MessageSet{}
1371 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001372 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001373 })
1374 return m
1375 }(),
Herbie Onge63c4c42019-03-22 22:20:22 -07001376 }, {
1377 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001378 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001379 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001380 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001381 }, {
1382 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001383 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001384 inputText: `{"unknown": null}`,
1385 wantErr: true,
1386 }, {
1387 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001388 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001389 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001390 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001391 }, {
1392 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001393 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001394 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001395 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001396 }, {
1397 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001398 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001399 inputText: `{}`,
1400 wantErr: true,
1401 }, {
1402 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001403 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001404 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001405 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001406 }, {
1407 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001408 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001409 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001410 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001411 }, {
1412 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001413 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001414 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001415 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001416 }, {
1417 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001418 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001419 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001420 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001421 }, {
1422 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001423 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001424 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001425 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001426 }, {
1427 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001428 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001429 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001430 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001431 }, {
1432 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001433 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001434 inputText: `1.23+40`,
1435 wantErr: true,
1436 }, {
1437 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001438 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001439 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001440 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001441 }, {
1442 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001443 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001444 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001445 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001446 }, {
1447 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001448 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001449 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001450 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001451 }, {
1452 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001453 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001454 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001455 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001456 }, {
1457 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001458 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001459 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001460 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001461 }, {
1462 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001463 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001464 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001465 wantErr: true,
1466 }, {
1467 desc: "StringValue field with invalid UTF8 error",
1468 inputMessage: &pb2.KnownTypes{},
1469 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001470 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001471 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001472 desc: "NullValue field with JSON null",
1473 inputMessage: &pb2.KnownTypes{},
1474 inputText: `{
1475 "optNull": null
1476}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001477 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001478 }, {
1479 desc: "NullValue field with string",
1480 inputMessage: &pb2.KnownTypes{},
1481 inputText: `{
1482 "optNull": "NULL_VALUE"
1483}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001484 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001485 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001486 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001487 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001488 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001489 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001490 }, {
1491 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001492 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001493 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001494 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001495 }, {
1496 desc: "Value field null",
1497 inputMessage: &pb2.KnownTypes{},
1498 inputText: `{
1499 "optValue": null
1500}`,
1501 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001502 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001503 },
1504 }, {
1505 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001506 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001507 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001508 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001509 }, {
1510 desc: "Value field bool",
1511 inputMessage: &pb2.KnownTypes{},
1512 inputText: `{
1513 "optValue": true
1514}`,
1515 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001516 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001517 },
1518 }, {
1519 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001520 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001521 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001522 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001523 }, {
1524 desc: "Value field number",
1525 inputMessage: &pb2.KnownTypes{},
1526 inputText: `{
1527 "optValue": 1.02
1528}`,
1529 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001530 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001531 },
1532 }, {
1533 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001534 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001535 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001536 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001537 }, {
1538 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001539 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001540 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001541 wantErr: true,
1542 }, {
1543 desc: "Value field string",
1544 inputMessage: &pb2.KnownTypes{},
1545 inputText: `{
1546 "optValue": "NaN"
1547}`,
1548 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001549 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001550 },
1551 }, {
1552 desc: "Value field string with invalid UTF8",
1553 inputMessage: &pb2.KnownTypes{},
1554 inputText: `{
1555 "optValue": "` + "\xff" + `"
1556}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001557 wantErr: true,
1558 }, {
1559 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001560 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001561 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001562 wantMessage: &structpb.Value{
1563 Kind: &structpb.Value_StructValue{
1564 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001565 },
1566 },
1567 }, {
1568 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001569 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001570 inputText: `{
1571 "string": "hello",
1572 "number": 123,
1573 "null": null,
1574 "bool": false,
1575 "struct": {
1576 "string": "world"
1577 },
1578 "list": []
1579}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001580 wantMessage: &structpb.Value{
1581 Kind: &structpb.Value_StructValue{
1582 &structpb.Struct{
1583 Fields: map[string]*structpb.Value{
1584 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1585 "number": {Kind: &structpb.Value_NumberValue{123}},
1586 "null": {Kind: &structpb.Value_NullValue{}},
1587 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001588 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001589 Kind: &structpb.Value_StructValue{
1590 &structpb.Struct{
1591 Fields: map[string]*structpb.Value{
1592 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001593 },
1594 },
1595 },
1596 },
1597 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001598 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001599 },
1600 },
1601 },
1602 },
1603 },
1604 }, {
1605 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001606 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001607 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001608 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001609 }, {
1610 desc: "Value field struct",
1611 inputMessage: &pb2.KnownTypes{},
1612 inputText: `{
1613 "optValue": {
1614 "string": "hello"
1615 }
1616}`,
1617 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001618 OptValue: &structpb.Value{
1619 Kind: &structpb.Value_StructValue{
1620 &structpb.Struct{
1621 Fields: map[string]*structpb.Value{
1622 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001623 },
1624 },
1625 },
1626 },
1627 },
1628 }, {
1629 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001630 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001631 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001632 wantMessage: &structpb.Value{
1633 Kind: &structpb.Value_ListValue{
1634 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001635 },
1636 },
1637 }, {
1638 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001639 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001640 inputText: `[
1641 "string",
1642 123,
1643 null,
1644 true,
1645 {},
1646 [
1647 "string",
1648 1.23,
1649 null,
1650 false
1651 ]
1652]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001653 wantMessage: &structpb.Value{
1654 Kind: &structpb.Value_ListValue{
1655 &structpb.ListValue{
1656 Values: []*structpb.Value{
1657 {Kind: &structpb.Value_StringValue{"string"}},
1658 {Kind: &structpb.Value_NumberValue{123}},
1659 {Kind: &structpb.Value_NullValue{}},
1660 {Kind: &structpb.Value_BoolValue{true}},
1661 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001662 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001663 Kind: &structpb.Value_ListValue{
1664 &structpb.ListValue{
1665 Values: []*structpb.Value{
1666 {Kind: &structpb.Value_StringValue{"string"}},
1667 {Kind: &structpb.Value_NumberValue{1.23}},
1668 {Kind: &structpb.Value_NullValue{}},
1669 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001670 },
1671 },
1672 },
1673 },
1674 },
1675 },
1676 },
1677 },
1678 }, {
1679 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001680 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001681 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001682 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001683 }, {
1684 desc: "Value field list with invalid UTF8 string",
1685 inputMessage: &pb2.KnownTypes{},
1686 inputText: `{
1687 "optValue": [ "` + "abc\xff" + `"]
1688}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001689 wantErr: true,
1690 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001691 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001692 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001693 inputText: `""`,
1694 wantErr: true,
1695 }, {
1696 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001697 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001698 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001699 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001700 }, {
1701 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001702 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001703 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001704 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001705 }, {
1706 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001707 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001708 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001709 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001710 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001711 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001712 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001713 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001714 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001715 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001716 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001717 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001718 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001719 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001720 }, {
1721 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001722 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001723 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001724 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001725 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001726 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001727 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001728 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001729 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001730 }, {
1731 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001732 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001733 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001734 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001735 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001736 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001737 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001738 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001739 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001740 }, {
1741 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001742 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001743 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001744 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001745 }, {
1746 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001747 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001748 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001749 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001750 }, {
1751 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001752 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001753 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001754 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001755 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001756 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001757 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001758 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001759 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001760 }, {
1761 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001762 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001763 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001764 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001765 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001766 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001767 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001768 inputText: `"315576000001s"`,
1769 wantErr: true,
1770 }, {
1771 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001772 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001773 inputText: `"-315576000001s"`,
1774 wantErr: true,
1775 }, {
1776 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001777 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001778 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001779 wantErr: true,
1780 }, {
1781 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001782 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001783 inputText: `"123"`,
1784 wantErr: true,
1785 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001786 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001787 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001788 inputText: `"123.+123s"`,
1789 wantErr: true,
1790 }, {
1791 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001792 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001793 inputText: `"123.123.s"`,
1794 wantErr: true,
1795 }, {
1796 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001797 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001798 inputText: `"01s"`,
1799 wantErr: true,
1800 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001801 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001802 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001803 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001804 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001805 }, {
1806 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001807 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001808 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001809 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001810 }, {
1811 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001812 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001813 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001814 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001815 }, {
1816 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001817 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001818 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001819 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001820 }, {
1821 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001822 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001823 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001824 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001825 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001826 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001827 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001828 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001829 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001830 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001831 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001832 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001833 inputText: `"9999-12-31T23:59:59-01:00"`,
1834 wantErr: true,
1835 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001836 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001837 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001838 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001839 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001840 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001841 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001842 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001843 inputText: `"0001-01-01T00:00:00+01:00"`,
1844 wantErr: true,
1845 }, {
1846 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001847 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001848 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1849 wantErr: true,
1850 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001851 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001852 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001853 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001854 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001855 }, {
1856 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001857 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001858 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001859 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001860 Paths: []string{
1861 "foo",
1862 "foo_bar",
1863 "foo.bar_qux",
1864 "_foo",
1865 },
1866 },
1867 }, {
1868 desc: "FieldMask field",
1869 inputMessage: &pb2.KnownTypes{},
1870 inputText: `{
1871 "optFieldmask": "foo, qux.fooBar"
1872}`,
1873 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001874 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001875 Paths: []string{
1876 "foo",
1877 "qux.foo_bar",
1878 },
1879 },
1880 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001881 }, {
1882 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001883 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001884 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001885 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001886 }, {
1887 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001888 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001889 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001890 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001891 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001892 inputText: `{
1893 "@type": "foo/pb2.Nested",
1894 "optString": "embedded inside Any",
1895 "optNested": {
1896 "optString": "inception"
1897 }
1898}`,
1899 wantMessage: func() proto.Message {
1900 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001901 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001902 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001903 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001904 },
1905 }
1906 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1907 if err != nil {
1908 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1909 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001910 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001911 TypeUrl: "foo/pb2.Nested",
1912 Value: b,
1913 }
1914 }(),
1915 }, {
1916 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001917 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001918 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001919 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001920 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001921 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001922 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001923 }, {
1924 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001925 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001926 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001927 inputText: `{"@type": "foo/pb2.Nested"}`,
1928 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001929 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001930 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001931 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001932 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001933 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001934 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001935 inputText: `{
1936 "@type": "pb2.PartialRequired",
1937 "optString": "embedded inside Any"
1938}`,
1939 wantMessage: func() proto.Message {
1940 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001941 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001942 }
Damien Neil96c229a2019-04-03 12:17:24 -07001943 b, err := proto.MarshalOptions{
1944 Deterministic: true,
1945 AllowPartial: true,
1946 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001947 if err != nil {
1948 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1949 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001950 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001951 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001952 Value: b,
1953 }
1954 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001955 }, {
1956 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001957 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001958 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001959 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001960 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001961 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001962 inputText: `{
1963 "@type": "pb2.PartialRequired",
1964 "optString": "embedded inside Any"
1965}`,
1966 wantMessage: func() proto.Message {
1967 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001968 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001969 }
Damien Neil96c229a2019-04-03 12:17:24 -07001970 b, err := proto.MarshalOptions{
1971 Deterministic: true,
1972 AllowPartial: true,
1973 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001974 if err != nil {
1975 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1976 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001977 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001978 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001979 Value: b,
1980 }
1981 }(),
1982 }, {
1983 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001984 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001985 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001986 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001987 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001988 inputText: `{
1989 "optString": "` + "abc\xff" + `",
1990 "@type": "foo/pb2.Nested"
1991}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001992 wantErr: true,
1993 }, {
1994 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07001995 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001996 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001997 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001998 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001999 inputText: `{
2000 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2001 "value": true
2002}`,
2003 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002004 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002005 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2006 if err != nil {
2007 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2008 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002009 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002010 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2011 Value: b,
2012 }
2013 }(),
2014 }, {
2015 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002016 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002017 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002018 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002019 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002020 inputText: `{
2021 "value": {},
2022 "@type": "type.googleapis.com/google.protobuf.Empty"
2023}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002024 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002025 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2026 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002027 }, {
2028 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002029 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002030 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002031 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002032 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002033 inputText: `{
2034 "@type": "type.googleapis.com/google.protobuf.Empty"
2035}`,
2036 wantErr: true,
2037 }, {
2038 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002039 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002040 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002041 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002042 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002043 inputText: `{
2044 "@type": "google.protobuf.StringValue",
2045 "value": "` + "abc\xff" + `"
2046}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002047 wantErr: true,
2048 }, {
2049 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002050 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002051 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002052 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002053 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002054 inputText: `{
2055 "@type": "google.protobuf.Int64Value",
2056 "value": "42"
2057}`,
2058 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002059 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002060 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2061 if err != nil {
2062 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2063 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002064 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002065 TypeUrl: "google.protobuf.Int64Value",
2066 Value: b,
2067 }
2068 }(),
2069 }, {
2070 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002071 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002072 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002073 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002074 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002075 inputText: `{
2076 "@type": "google.protobuf.Int64Value",
2077 "value": "forty-two"
2078}`,
2079 wantErr: true,
2080 }, {
2081 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002082 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002083 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002084 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002085 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002086 inputText: `{
2087 "@type": "google.protobuf.UInt64Value",
2088 "value": -42
2089}`,
2090 wantErr: true,
2091 }, {
2092 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002093 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002094 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002095 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002096 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002097 inputText: `{
2098 "@type": "type.googleapis.com/google.protobuf.Duration",
2099 "value": "0s"
2100}`,
2101 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002102 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002103 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2104 if err != nil {
2105 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2106 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002107 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002108 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2109 Value: b,
2110 }
2111 }(),
2112 }, {
2113 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002114 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002115 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002116 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002117 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002118 inputText: `{
2119 "@type": "google.protobuf.Value",
2120 "value": "` + "abc\xff" + `"
2121}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002122 wantErr: true,
2123 }, {
2124 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002125 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002126 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002127 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002128 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002129 inputText: `{
2130 "@type": "google.protobuf.Value",
2131 "value": null
2132}`,
2133 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002134 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002135 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2136 if err != nil {
2137 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2138 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002139 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002140 TypeUrl: "google.protobuf.Value",
2141 Value: b,
2142 }
2143 }(),
2144 }, {
2145 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002146 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002147 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002148 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2149 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2150 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2151 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2152 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002153 ),
2154 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002155 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002156 inputText: `{
2157 "@type": "google.protobuf.Struct",
2158 "value": {
2159 "bool": true,
2160 "null": null,
2161 "string": "hello",
2162 "struct": {
2163 "string": "world"
2164 }
2165 }
2166}`,
2167 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002168 m := &structpb.Struct{
2169 Fields: map[string]*structpb.Value{
2170 "bool": {Kind: &structpb.Value_BoolValue{true}},
2171 "null": {Kind: &structpb.Value_NullValue{}},
2172 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002173 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002174 Kind: &structpb.Value_StructValue{
2175 &structpb.Struct{
2176 Fields: map[string]*structpb.Value{
2177 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002178 },
2179 },
2180 },
2181 },
2182 },
2183 }
2184 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2185 if err != nil {
2186 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2187 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002188 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002189 TypeUrl: "google.protobuf.Struct",
2190 Value: b,
2191 }
2192 }(),
2193 }, {
2194 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002195 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002196 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002197 inputText: `{
2198 "value": {}
2199}`,
2200 wantErr: true,
2201 }, {
2202 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002203 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002204 inputText: `{
2205 "@type": ""
2206}`,
2207 wantErr: true,
2208 }, {
2209 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002210 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002211 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002212 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002213 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002214 ),
2215 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002216 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002217 inputText: `{
2218 "@type": "google.protobuf.StringValue",
2219 "value": "hello",
2220 "@type": "pb2.Nested"
2221}`,
2222 wantErr: true,
2223 }, {
2224 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002225 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002226 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002227 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002228 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002229 inputText: `{
2230 "@type": "google.protobuf.StringValue",
2231 "value": "hello",
2232 "value": "world"
2233}`,
2234 wantErr: true,
2235 }, {
2236 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002237 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002238 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002239 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002240 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002241 inputText: `{
2242 "@type": "pb2.Nested",
2243 "optString": "hello",
2244 "unknown": "world"
2245}`,
2246 wantErr: true,
2247 }, {
2248 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002249 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002250 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002251 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002252 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2253 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002254 ),
2255 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002256 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002257 inputText: `{
2258 "@type": "pb2.KnownTypes",
2259 "optAny": {
2260 "@type": "google.protobuf.StringValue",
2261 "value": "` + "abc\xff" + `"
2262 }
2263}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002264 wantErr: true,
2265 }, {
2266 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002267 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002268 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002269 },
2270 inputMessage: &pb2.KnownTypes{},
2271 inputText: `{
2272 "optBool": false,
2273 "optInt32": 42,
2274 "optInt64": "42",
2275 "optUint32": 42,
2276 "optUint64": "42",
2277 "optFloat": 1.23,
2278 "optDouble": 3.1415,
2279 "optString": "hello",
2280 "optBytes": "aGVsbG8=",
2281 "optDuration": "123s",
2282 "optTimestamp": "2019-03-19T23:03:21Z",
2283 "optStruct": {
2284 "string": "hello"
2285 },
2286 "optList": [
2287 null,
2288 "",
2289 {},
2290 []
2291 ],
2292 "optValue": "world",
2293 "optEmpty": {},
2294 "optAny": {
2295 "@type": "google.protobuf.Empty",
2296 "value": {}
2297 },
2298 "optFieldmask": "fooBar,barFoo"
2299}`,
2300 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002301 OptBool: &wrapperspb.BoolValue{Value: false},
2302 OptInt32: &wrapperspb.Int32Value{Value: 42},
2303 OptInt64: &wrapperspb.Int64Value{Value: 42},
2304 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2305 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2306 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2307 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2308 OptString: &wrapperspb.StringValue{Value: "hello"},
2309 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2310 OptDuration: &durationpb.Duration{Seconds: 123},
2311 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2312 OptStruct: &structpb.Struct{
2313 Fields: map[string]*structpb.Value{
2314 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002315 },
2316 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002317 OptList: &structpb.ListValue{
2318 Values: []*structpb.Value{
2319 {Kind: &structpb.Value_NullValue{}},
2320 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002321 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002322 Kind: &structpb.Value_StructValue{
2323 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002324 },
2325 },
2326 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002327 Kind: &structpb.Value_ListValue{
2328 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002329 },
2330 },
2331 },
2332 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002333 OptValue: &structpb.Value{
2334 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002335 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002336 OptEmpty: &emptypb.Empty{},
2337 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002338 TypeUrl: "google.protobuf.Empty",
2339 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002340 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002341 Paths: []string{"foo_bar", "bar_foo"},
2342 },
2343 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002344 }, {
2345 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002346 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002347 inputMessage: &pb3.Nests{},
2348 inputText: `{
2349 "sNested": {
2350 "unknown": {
2351 "foo": 1,
2352 "bar": [1, 2, 3]
2353 }
2354 },
2355 "unknown": "not known"
2356}`,
2357 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2358 }, {
2359 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002360 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002361 inputMessage: &pb2.Nests{},
2362 inputText: `{
2363 "rptNested": [
2364 {"unknown": "blah"},
2365 {"optString": "hello"}
2366 ]
2367}`,
2368 wantMessage: &pb2.Nests{
2369 RptNested: []*pb2.Nested{
2370 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002371 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002372 },
2373 },
2374 }, {
2375 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002376 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002377 inputMessage: &pb3.Maps{},
2378 inputText: `{
2379 "strToNested": {
2380 "nested_one": {
2381 "unknown": "what you see is not"
2382 }
2383 }
2384}`,
2385 wantMessage: &pb3.Maps{
2386 StrToNested: map[string]*pb3.Nested{
2387 "nested_one": {},
2388 },
2389 },
2390 }, {
2391 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002392 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002393 inputMessage: &pb2.Extensions{},
2394 inputText: `{
2395 "[pb2.opt_ext_nested]": {
2396 "unknown": []
2397 }
2398}`,
2399 wantMessage: func() proto.Message {
2400 m := &pb2.Extensions{}
2401 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
2402 return m
2403 }(),
2404 }, {
2405 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002406 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002407 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002408 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002409 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002410 }, {
2411 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002412 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002413 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002414 inputText: `{
2415 "value": {"foo": "bar"},
2416 "unknown": true
2417}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002418 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002419 }, {
2420 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002421 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002422 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002423 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002424 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002425 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002426 inputText: `{
2427 "@type": "foo/pb2.Nested",
2428 "unknown": "none"
2429}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002430 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002431 TypeUrl: "foo/pb2.Nested",
2432 },
2433 }, {
2434 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002435 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002436 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002437 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002438 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002439 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002440 inputText: `{
2441 "@type": "type.googleapis.com/google.protobuf.Empty",
2442 "value": {"unknown": 47}
2443}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002444 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002445 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2446 },
Joe Tsaid47ea192019-07-09 22:38:15 -07002447 }, {
2448 desc: "weak fields",
2449 inputMessage: &testpb.TestWeak{},
2450 inputText: `{"weak_message1":{"a":1}}`,
2451 wantMessage: func() *testpb.TestWeak {
2452 m := new(testpb.TestWeak)
2453 m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
2454 return m
2455 }(),
2456 skip: !flags.Proto1Legacy,
2457 }, {
2458 desc: "weak fields; unknown field",
2459 inputMessage: &testpb.TestWeak{},
2460 inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
2461 wantErr: true, // weak_message2 is unknown since the package containing it is not imported
2462 skip: !flags.Proto1Legacy,
Herbie Ongc96a79d2019-03-08 10:49:17 -08002463 }}
2464
2465 for _, tt := range tests {
2466 tt := tt
Joe Tsaid47ea192019-07-09 22:38:15 -07002467 if tt.skip {
2468 continue
2469 }
Herbie Ongc96a79d2019-03-08 10:49:17 -08002470 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002471 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002472 if err != nil && !tt.wantErr {
2473 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2474 }
2475 if err == nil && tt.wantErr {
2476 t.Error("Unmarshal() got nil error, want error\n\n")
2477 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002478 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002479 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2480 }
2481 })
2482 }
2483}