blob: 7f0a4e860737abff14fa31e12ef2795836258e0b [file] [log] [blame]
Herbie Ong800c9902018-12-06 15:28:53 -08001// Copyright 2018 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 prototext_test
Herbie Ong800c9902018-12-06 15:28:53 -08006
7import (
8 "math"
9 "testing"
10
11 protoV1 "github.com/golang/protobuf/proto"
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070013 pimpl "google.golang.org/protobuf/internal/impl"
14 "google.golang.org/protobuf/internal/scalar"
15 "google.golang.org/protobuf/proto"
16 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080017
Damien Neile89e6242019-05-13 23:55:40 -070018 "google.golang.org/protobuf/encoding/testprotos/pb2"
19 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070020 "google.golang.org/protobuf/types/known/anypb"
Herbie Ong800c9902018-12-06 15:28:53 -080021)
22
23func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080024 tests := []struct {
25 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070026 umo prototext.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080027 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080028 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080029 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070030 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080031 }{{
32 desc: "proto2 empty message",
33 inputMessage: &pb2.Scalars{},
34 wantMessage: &pb2.Scalars{},
35 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080036 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080037 inputMessage: &pb2.Scalars{},
38 inputText: `opt_bool: false
39opt_int32: 0
40opt_int64: 0
41opt_uint32: 0
42opt_uint64: 0
43opt_sint32: 0
44opt_sint64: 0
45opt_fixed32: 0
46opt_fixed64: 0
47opt_sfixed32: 0
48opt_sfixed64: 0
49opt_float: 0
50opt_double: 0
51opt_bytes: ""
52opt_string: ""
53`,
54 wantMessage: &pb2.Scalars{
55 OptBool: scalar.Bool(false),
56 OptInt32: scalar.Int32(0),
57 OptInt64: scalar.Int64(0),
58 OptUint32: scalar.Uint32(0),
59 OptUint64: scalar.Uint64(0),
60 OptSint32: scalar.Int32(0),
61 OptSint64: scalar.Int64(0),
62 OptFixed32: scalar.Uint32(0),
63 OptFixed64: scalar.Uint64(0),
64 OptSfixed32: scalar.Int32(0),
65 OptSfixed64: scalar.Int64(0),
66 OptFloat: scalar.Float32(0),
67 OptDouble: scalar.Float64(0),
68 OptBytes: []byte{},
69 OptString: scalar.String(""),
70 },
71 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080072 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080073 inputMessage: &pb3.Scalars{},
74 inputText: `s_bool: false
75s_int32: 0
76s_int64: 0
77s_uint32: 0
78s_uint64: 0
79s_sint32: 0
80s_sint64: 0
81s_fixed32: 0
82s_fixed64: 0
83s_sfixed32: 0
84s_sfixed64: 0
85s_float: 0
86s_double: 0
87s_bytes: ""
88s_string: ""
89`,
90 wantMessage: &pb3.Scalars{},
91 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080092 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -080093 inputMessage: &pb2.Scalars{},
94 inputText: `opt_bool: true
95opt_int32: 255
96opt_int64: 3735928559
97opt_uint32: 0xff
98opt_uint64: 0xdeadbeef
99opt_sint32: -1001
100opt_sint64: -0xffff
101opt_fixed64: 64
102opt_sfixed32: -32
103opt_float: 1.234
104opt_double: 1.23e+100
105opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
106opt_string: "谷歌"
107`,
108 wantMessage: &pb2.Scalars{
109 OptBool: scalar.Bool(true),
110 OptInt32: scalar.Int32(0xff),
111 OptInt64: scalar.Int64(0xdeadbeef),
112 OptUint32: scalar.Uint32(0xff),
113 OptUint64: scalar.Uint64(0xdeadbeef),
114 OptSint32: scalar.Int32(-1001),
115 OptSint64: scalar.Int64(-0xffff),
116 OptFixed64: scalar.Uint64(64),
117 OptSfixed32: scalar.Int32(-32),
118 OptFloat: scalar.Float32(1.234),
119 OptDouble: scalar.Float64(1.23e100),
120 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
121 OptString: scalar.String("谷歌"),
122 },
123 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700124 desc: "case sensitive",
125 inputMessage: &pb3.Scalars{},
126 inputText: `S_BOOL: true`,
127 wantErr: true,
128 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800129 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800130 inputMessage: &pb3.Scalars{},
131 inputText: `s_bool: true
132s_int32: 255
133s_int64: 3735928559
134s_uint32: 0xff
135s_uint64: 0xdeadbeef
136s_sint32: -1001
137s_sint64: -0xffff
138s_fixed64: 64
139s_sfixed32: -32
140s_float: 1.234
141s_double: 1.23e+100
142s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
143s_string: "谷歌"
144`,
145 wantMessage: &pb3.Scalars{
146 SBool: true,
147 SInt32: 0xff,
148 SInt64: 0xdeadbeef,
149 SUint32: 0xff,
150 SUint64: 0xdeadbeef,
151 SSint32: -1001,
152 SSint64: -0xffff,
153 SFixed64: 64,
154 SSfixed32: -32,
155 SFloat: 1.234,
156 SDouble: 1.23e100,
157 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
158 SString: "谷歌",
159 },
160 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700161 desc: "string with invalid UTF-8",
162 inputMessage: &pb3.Scalars{},
163 inputText: `s_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700164 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700165 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800166 desc: "proto2 message contains unknown field",
167 inputMessage: &pb2.Scalars{},
168 inputText: "unknown_field: 123",
169 wantErr: true,
170 }, {
171 desc: "proto3 message contains unknown field",
172 inputMessage: &pb3.Scalars{},
173 inputText: "unknown_field: 456",
174 wantErr: true,
175 }, {
176 desc: "proto2 numeric key field",
177 inputMessage: &pb2.Scalars{},
178 inputText: "1: true",
179 wantErr: true,
180 }, {
181 desc: "proto3 numeric key field",
182 inputMessage: &pb3.Scalars{},
183 inputText: "1: true",
184 wantErr: true,
185 }, {
186 desc: "invalid bool value",
187 inputMessage: &pb3.Scalars{},
188 inputText: "s_bool: 123",
189 wantErr: true,
190 }, {
191 desc: "invalid int32 value",
192 inputMessage: &pb3.Scalars{},
193 inputText: "s_int32: not_a_num",
194 wantErr: true,
195 }, {
196 desc: "invalid int64 value",
197 inputMessage: &pb3.Scalars{},
198 inputText: "s_int64: 'not a num either'",
199 wantErr: true,
200 }, {
201 desc: "invalid uint32 value",
202 inputMessage: &pb3.Scalars{},
203 inputText: "s_fixed32: -42",
204 wantErr: true,
205 }, {
206 desc: "invalid uint64 value",
207 inputMessage: &pb3.Scalars{},
208 inputText: "s_uint64: -47",
209 wantErr: true,
210 }, {
211 desc: "invalid sint32 value",
212 inputMessage: &pb3.Scalars{},
213 inputText: "s_sint32: '42'",
214 wantErr: true,
215 }, {
216 desc: "invalid sint64 value",
217 inputMessage: &pb3.Scalars{},
218 inputText: "s_sint64: '-47'",
219 wantErr: true,
220 }, {
221 desc: "invalid fixed32 value",
222 inputMessage: &pb3.Scalars{},
223 inputText: "s_fixed32: -42",
224 wantErr: true,
225 }, {
226 desc: "invalid fixed64 value",
227 inputMessage: &pb3.Scalars{},
228 inputText: "s_fixed64: -42",
229 wantErr: true,
230 }, {
231 desc: "invalid sfixed32 value",
232 inputMessage: &pb3.Scalars{},
233 inputText: "s_sfixed32: 'not valid'",
234 wantErr: true,
235 }, {
236 desc: "invalid sfixed64 value",
237 inputMessage: &pb3.Scalars{},
238 inputText: "s_sfixed64: bad",
239 wantErr: true,
240 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800241 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800242 inputMessage: &pb3.Scalars{},
243 inputText: "s_float: inf",
244 wantMessage: &pb3.Scalars{
245 SFloat: float32(math.Inf(1)),
246 },
247 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800248 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800249 inputMessage: &pb3.Scalars{},
250 inputText: "s_float: -inf",
251 wantMessage: &pb3.Scalars{
252 SFloat: float32(math.Inf(-1)),
253 },
254 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800255 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800256 inputMessage: &pb3.Scalars{},
257 inputText: "s_double: inf",
258 wantMessage: &pb3.Scalars{
259 SDouble: math.Inf(1),
260 },
261 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800262 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800263 inputMessage: &pb3.Scalars{},
264 inputText: "s_double: -inf",
265 wantMessage: &pb3.Scalars{
266 SDouble: math.Inf(-1),
267 },
268 }, {
269 desc: "invalid string value",
270 inputMessage: &pb3.Scalars{},
271 inputText: "s_string: invalid_string",
272 wantErr: true,
273 }, {
274 desc: "proto2 bytes set to empty string",
275 inputMessage: &pb2.Scalars{},
276 inputText: "opt_bytes: ''",
277 wantMessage: &pb2.Scalars{
278 OptBytes: []byte(""),
279 },
280 }, {
281 desc: "proto3 bytes set to empty string",
282 inputMessage: &pb3.Scalars{},
283 inputText: "s_bytes: ''",
284 wantMessage: &pb3.Scalars{},
285 }, {
286 desc: "proto2 duplicate singular field",
287 inputMessage: &pb2.Scalars{},
288 inputText: `
289opt_bool: true
290opt_bool: false
291`,
292 wantErr: true,
293 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800294 desc: "proto2 more duplicate singular field",
295 inputMessage: &pb2.Scalars{},
296 inputText: `
297opt_bool: true
298opt_string: "hello"
299opt_bool: false
300`,
301 wantErr: true,
302 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800303 desc: "proto2 invalid singular field",
304 inputMessage: &pb2.Scalars{},
305 inputText: `
306opt_bool: [true, false]
307`,
308 wantErr: true,
309 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800310 desc: "proto3 duplicate singular field",
311 inputMessage: &pb3.Scalars{},
312 inputText: `
313s_bool: false
314s_bool: true
315`,
316 wantErr: true,
317 }, {
318 desc: "proto3 more duplicate singular field",
319 inputMessage: &pb3.Scalars{},
320 inputText: `
321s_bool: false
322s_string: ""
323s_bool: true
324`,
325 wantErr: true,
326 }, {
327 desc: "proto2 enum",
328 inputMessage: &pb2.Enums{},
329 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800330opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800331opt_nested_enum: UNO
332`,
333 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800334 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800335 OptNestedEnum: pb2.Enums_UNO.Enum(),
336 },
337 }, {
338 desc: "proto2 enum set to numeric values",
339 inputMessage: &pb2.Enums{},
340 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800341opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800342opt_nested_enum: 2
343`,
344 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800345 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800346 OptNestedEnum: pb2.Enums_DOS.Enum(),
347 },
348 }, {
349 desc: "proto2 enum set to unnamed numeric values",
350 inputMessage: &pb2.Enums{},
351 inputText: `
352opt_enum: 101
353opt_nested_enum: -101
354`,
355 wantMessage: &pb2.Enums{
356 OptEnum: pb2Enum(101),
357 OptNestedEnum: pb2Enums_NestedEnum(-101),
358 },
359 }, {
360 desc: "proto2 enum set to invalid named",
361 inputMessage: &pb2.Enums{},
362 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800363opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800364opt_nested_enum: UNNAMED_TOO
365`,
366 wantErr: true,
367 }, {
368 desc: "proto3 enum name value",
369 inputMessage: &pb3.Enums{},
370 inputText: `
371s_enum: ONE
372s_nested_enum: DIEZ
373`,
374 wantMessage: &pb3.Enums{
375 SEnum: pb3.Enum_ONE,
376 SNestedEnum: pb3.Enums_DIEZ,
377 },
378 }, {
379 desc: "proto3 enum numeric value",
380 inputMessage: &pb3.Enums{},
381 inputText: `
382s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800383s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800384`,
385 wantMessage: &pb3.Enums{
386 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800387 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800388 },
389 }, {
390 desc: "proto3 enum unnamed numeric value",
391 inputMessage: &pb3.Enums{},
392 inputText: `
393s_enum: 0x7fffffff
394s_nested_enum: -0x80000000
395`,
396 wantMessage: &pb3.Enums{
397 SEnum: 0x7fffffff,
398 SNestedEnum: -0x80000000,
399 },
400 }, {
401 desc: "proto2 nested empty messages",
402 inputMessage: &pb2.Nests{},
403 inputText: `
404opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800405OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800406`,
407 wantMessage: &pb2.Nests{
408 OptNested: &pb2.Nested{},
409 Optgroup: &pb2.Nests_OptGroup{},
410 },
411 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700412 desc: "group field name",
413 inputMessage: &pb2.Nests{},
414 inputText: `optgroup: {}`,
415 wantErr: true,
416 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800417 desc: "proto2 nested messages",
418 inputMessage: &pb2.Nests{},
419 inputText: `
420opt_nested: {
421 opt_string: "nested message"
422 opt_nested: {
423 opt_string: "another nested message"
424 }
425}
426`,
427 wantMessage: &pb2.Nests{
428 OptNested: &pb2.Nested{
429 OptString: scalar.String("nested message"),
430 OptNested: &pb2.Nested{
431 OptString: scalar.String("another nested message"),
432 },
433 },
434 },
435 }, {
436 desc: "proto3 nested empty message",
437 inputMessage: &pb3.Nests{},
438 inputText: "s_nested: {}",
439 wantMessage: &pb3.Nests{
440 SNested: &pb3.Nested{},
441 },
442 }, {
443 desc: "proto3 nested message",
444 inputMessage: &pb3.Nests{},
445 inputText: `
446s_nested: {
447 s_string: "nested message"
448 s_nested: {
449 s_string: "another nested message"
450 }
451}
452`,
453 wantMessage: &pb3.Nests{
454 SNested: &pb3.Nested{
455 SString: "nested message",
456 SNested: &pb3.Nested{
457 SString: "another nested message",
458 },
459 },
460 },
461 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700462 desc: "proto3 nested message contains invalid UTF-8",
463 inputMessage: &pb3.Nests{},
464 inputText: `s_nested: {
465 s_string: "abc\xff"
466}
467`,
Herbie Ong21a39742019-04-08 17:32:44 -0700468 wantErr: true,
469 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800470 desc: "oneof set to empty string",
471 inputMessage: &pb3.Oneofs{},
472 inputText: "oneof_string: ''",
473 wantMessage: &pb3.Oneofs{
474 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800475 },
476 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800477 desc: "oneof set to string",
478 inputMessage: &pb3.Oneofs{},
479 inputText: "oneof_string: 'hello'",
480 wantMessage: &pb3.Oneofs{
481 Union: &pb3.Oneofs_OneofString{
482 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800483 },
484 },
485 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800486 desc: "oneof set to enum",
487 inputMessage: &pb3.Oneofs{},
488 inputText: "oneof_enum: TEN",
489 wantMessage: &pb3.Oneofs{
490 Union: &pb3.Oneofs_OneofEnum{
491 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800492 },
493 },
494 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800495 desc: "oneof set to empty message",
496 inputMessage: &pb3.Oneofs{},
497 inputText: "oneof_nested: {}",
498 wantMessage: &pb3.Oneofs{
499 Union: &pb3.Oneofs_OneofNested{
500 OneofNested: &pb3.Nested{},
501 },
502 },
503 }, {
504 desc: "oneof set to message",
505 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800506 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800507oneof_nested: {
508 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800509}
510`,
Herbie Ong8170d692019-02-13 14:13:21 -0800511 wantMessage: &pb3.Oneofs{
512 Union: &pb3.Oneofs_OneofNested{
513 OneofNested: &pb3.Nested{
514 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800515 },
516 },
517 },
518 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700519 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800520 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800521 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700522oneof_enum: ZERO
523oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800524`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700525 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800526 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800527 desc: "repeated scalar using same field name",
528 inputMessage: &pb2.Repeats{},
529 inputText: `
530rpt_string: "a"
531rpt_string: "b"
532rpt_int32: 0xff
533rpt_float: 1.23
534rpt_bytes: "bytes"
535`,
536 wantMessage: &pb2.Repeats{
537 RptString: []string{"a", "b"},
538 RptInt32: []int32{0xff},
539 RptFloat: []float32{1.23},
540 RptBytes: [][]byte{[]byte("bytes")},
541 },
542 }, {
543 desc: "repeated using mix of [] and repeated field name",
544 inputMessage: &pb2.Repeats{},
545 inputText: `
546rpt_string: "a"
547rpt_bool: true
548rpt_string: ["x", "y"]
549rpt_bool: [ false, true ]
550rpt_string: "b"
551`,
552 wantMessage: &pb2.Repeats{
553 RptString: []string{"a", "x", "y", "b"},
554 RptBool: []bool{true, false, true},
555 },
556 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700557 desc: "repeated contains invalid UTF-8",
558 inputMessage: &pb2.Repeats{},
559 inputText: `rpt_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700560 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700561 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800562 desc: "repeated enums",
563 inputMessage: &pb2.Enums{},
564 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800565rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800566rpt_enum: 1
567rpt_nested_enum: [DOS, 2]
568rpt_enum: 42
569rpt_nested_enum: -47
570`,
571 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800572 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800573 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
574 },
575 }, {
576 desc: "repeated nested messages",
577 inputMessage: &pb2.Nests{},
578 inputText: `
579rpt_nested: {
580 opt_string: "repeat nested one"
581}
582rpt_nested: {
583 opt_string: "repeat nested two"
584 opt_nested: {
585 opt_string: "inside repeat nested two"
586 }
587}
588rpt_nested: {}
589`,
590 wantMessage: &pb2.Nests{
591 RptNested: []*pb2.Nested{
592 {
593 OptString: scalar.String("repeat nested one"),
594 },
595 {
596 OptString: scalar.String("repeat nested two"),
597 OptNested: &pb2.Nested{
598 OptString: scalar.String("inside repeat nested two"),
599 },
600 },
601 {},
602 },
603 },
604 }, {
605 desc: "repeated group fields",
606 inputMessage: &pb2.Nests{},
607 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800608RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800609 rpt_string: "hello"
610 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800611}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800612RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800613`,
614 wantMessage: &pb2.Nests{
615 Rptgroup: []*pb2.Nests_RptGroup{
616 {
Herbie Ong8170d692019-02-13 14:13:21 -0800617 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800618 },
619 {},
620 },
621 },
622 }, {
623 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800624 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800625 inputText: `
626int32_to_str: {
627 key: -101
628 value: "-101"
629}
630int32_to_str: {
631 key: 0
632 value: "zero"
633}
Herbie Ong8170d692019-02-13 14:13:21 -0800634bool_to_uint32: {
635 key: false
636 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800637}
638int32_to_str: {
639 key: 255
640 value: "0xff"
641}
642bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800643 key: true
644 value: 42
645}
646`,
Herbie Ong8170d692019-02-13 14:13:21 -0800647 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800648 Int32ToStr: map[int32]string{
649 -101: "-101",
650 0xff: "0xff",
651 0: "zero",
652 },
Herbie Ong800c9902018-12-06 15:28:53 -0800653 BoolToUint32: map[bool]uint32{
654 true: 42,
655 false: 101,
656 },
657 },
658 }, {
659 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800660 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800661 inputText: `
662uint64_to_enum: {
663 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800664 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800665}
666uint64_to_enum: {
667 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800668 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800669}
670uint64_to_enum: {
671 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800672 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800673}
674`,
Herbie Ong8170d692019-02-13 14:13:21 -0800675 wantMessage: &pb3.Maps{
676 Uint64ToEnum: map[uint64]pb3.Enum{
677 1: pb3.Enum_ONE,
678 2: pb3.Enum_TWO,
679 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800680 },
681 },
682 }, {
683 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800684 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800685 inputText: `
686str_to_nested: {
687 key: "nested_one"
688 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800689 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800690 }
691}
692`,
Herbie Ong8170d692019-02-13 14:13:21 -0800693 wantMessage: &pb3.Maps{
694 StrToNested: map[string]*pb3.Nested{
695 "nested_one": &pb3.Nested{
696 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800697 },
698 },
699 },
700 }, {
701 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800702 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800703 inputText: `
704str_to_oneofs: {
705 key: "nested"
706 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800707 oneof_nested: {
708 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800709 }
710 }
711}
712str_to_oneofs: {
713 key: "string"
714 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800715 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800716 }
717}
718`,
Herbie Ong8170d692019-02-13 14:13:21 -0800719 wantMessage: &pb3.Maps{
720 StrToOneofs: map[string]*pb3.Oneofs{
721 "string": &pb3.Oneofs{
722 Union: &pb3.Oneofs_OneofString{
723 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800724 },
725 },
Herbie Ong8170d692019-02-13 14:13:21 -0800726 "nested": &pb3.Oneofs{
727 Union: &pb3.Oneofs_OneofNested{
728 OneofNested: &pb3.Nested{
729 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800730 },
731 },
732 },
733 },
734 },
735 }, {
736 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800737 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800738 inputText: `
739int32_to_str: {
740 key: 0
741 value: "cero"
742}
743int32_to_str: {
744 key: 0
745 value: "zero"
746}
747`,
Herbie Ong8170d692019-02-13 14:13:21 -0800748 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800749 Int32ToStr: map[int32]string{
750 0: "zero",
751 },
752 },
753 }, {
754 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800755 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800756 inputText: `
757int32_to_str: {
758 key: 0
759 key: 1
760 value: "cero"
761}
762`,
763 wantErr: true,
764 }, {
765 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800766 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800767 inputText: `
768int32_to_str: {
769 key: 1
770 value: "cero"
771 value: "uno"
772}
773`,
774 wantErr: true,
775 }, {
776 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800777 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800778 inputText: `
779int32_to_str: {
780 value: "zero"
781}
Herbie Ong8170d692019-02-13 14:13:21 -0800782bool_to_uint32: {
783 value: 47
784}
785str_to_nested: {
786 value: {}
787}
Herbie Ong800c9902018-12-06 15:28:53 -0800788`,
Herbie Ong8170d692019-02-13 14:13:21 -0800789 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800790 Int32ToStr: map[int32]string{
791 0: "zero",
792 },
Herbie Ong8170d692019-02-13 14:13:21 -0800793 BoolToUint32: map[bool]uint32{
794 false: 47,
795 },
796 StrToNested: map[string]*pb3.Nested{
797 "": {},
798 },
Herbie Ong800c9902018-12-06 15:28:53 -0800799 },
800 }, {
801 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800802 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800803 inputText: `
804int32_to_str: {
805 key: 100
806}
Herbie Ong8170d692019-02-13 14:13:21 -0800807bool_to_uint32: {
808 key: true
809}
810uint64_to_enum: {
811 key: 101
812}
813str_to_nested: {
814 key: "hello"
815}
Herbie Ong800c9902018-12-06 15:28:53 -0800816`,
Herbie Ong8170d692019-02-13 14:13:21 -0800817 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800818 Int32ToStr: map[int32]string{
819 100: "",
820 },
Herbie Ong8170d692019-02-13 14:13:21 -0800821 BoolToUint32: map[bool]uint32{
822 true: 0,
823 },
824 Uint64ToEnum: map[uint64]pb3.Enum{
825 101: pb3.Enum_ZERO,
826 },
827 StrToNested: map[string]*pb3.Nested{
828 "hello": {},
829 },
Herbie Ong800c9902018-12-06 15:28:53 -0800830 },
831 }, {
832 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800833 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800834 inputText: `
835int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800836bool_to_uint32: {}
837uint64_to_enum: {}
838str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800839`,
Herbie Ong8170d692019-02-13 14:13:21 -0800840 wantMessage: &pb3.Maps{
841 Int32ToStr: map[int32]string{
842 0: "",
843 },
844 BoolToUint32: map[bool]uint32{
845 false: 0,
846 },
847 Uint64ToEnum: map[uint64]pb3.Enum{
848 0: pb3.Enum_ZERO,
849 },
850 StrToNested: map[string]*pb3.Nested{
851 "": {},
852 },
853 },
854 }, {
855 desc: "map contains overriding entries",
856 inputMessage: &pb3.Maps{},
857 inputText: `
858int32_to_str: {
859 key: 0
860}
861int32_to_str: {
862 value: "empty"
863}
864int32_to_str: {}
865`,
866 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800867 Int32ToStr: map[int32]string{
868 0: "",
869 },
870 },
871 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700872 desc: "map field value contains invalid UTF-8",
873 inputMessage: &pb3.Maps{},
874 inputText: `int32_to_str: {
875 key: 101
876 value: "abc\xff"
877}
878`,
Herbie Ong21a39742019-04-08 17:32:44 -0700879 wantErr: true,
880 }, {
881 desc: "map field key contains invalid UTF-8",
882 inputMessage: &pb3.Maps{},
883 inputText: `str_to_nested: {
884 key: "abc\xff"
885 value: {}
886}
887`,
Herbie Ong21a39742019-04-08 17:32:44 -0700888 wantErr: true,
889 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800890 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800891 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800892 inputText: `
893int32_to_str: {
894 key: 0
895 value: "cero"
896 unknown: "bad"
897}
898`,
899 wantErr: true,
900 }, {
901 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800902 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800903 inputText: `
904int32_to_str: {
905 [key]: 10
906 value: "ten"
907}
908`,
909 wantErr: true,
910 }, {
911 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800912 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800913 inputText: `
914int32_to_str: {
915 key: "invalid"
916 value: "cero"
917}
918`,
919 wantErr: true,
920 }, {
921 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800922 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800923 inputText: `
924int32_to_str: {
925 key: 100
926 value: 101
927}
928`,
929 wantErr: true,
930 }, {
931 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800932 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800933 inputText: `
934int32_to_str: {
935 key: 1
936 value: "one"
937}
938int32_to_str: [
939 {
940 key: 2
941 value: "not this"
942 },
943 {
944 },
945 {
946 key: 3
947 value: "three"
948 }
949]
950int32_to_str: {
951 key: 2
952 value: "two"
953}
954`,
Herbie Ong8170d692019-02-13 14:13:21 -0800955 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800956 Int32ToStr: map[int32]string{
957 0: "",
958 1: "one",
959 2: "two",
960 3: "three",
961 },
962 },
963 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700964 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800965 inputMessage: &pb2.Requireds{},
966 wantErr: true,
967 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700968 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800969 inputMessage: &pb2.PartialRequired{},
970 inputText: "req_string: 'this is required'",
971 wantMessage: &pb2.PartialRequired{
972 ReqString: scalar.String("this is required"),
973 },
974 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700975 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800976 inputMessage: &pb2.Requireds{},
977 inputText: `
978req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800979req_sfixed64: 3203386110
980req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800981req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800982`,
983 wantMessage: &pb2.Requireds{
984 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800985 ReqSfixed64: scalar.Int64(0xbeefcafe),
986 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800987 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800988 },
989 wantErr: true,
990 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700991 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700992 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700993 inputMessage: &pb2.Requireds{},
994 inputText: `
995req_bool: false
996req_sfixed64: 3203386110
997req_string: "hello"
998req_enum: ONE
999`,
1000 wantMessage: &pb2.Requireds{
1001 ReqBool: scalar.Bool(false),
1002 ReqSfixed64: scalar.Int64(0xbeefcafe),
1003 ReqString: scalar.String("hello"),
1004 ReqEnum: pb2.Enum_ONE.Enum(),
1005 },
1006 }, {
1007 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001008 inputMessage: &pb2.Requireds{},
1009 inputText: `
1010req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001011req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001012req_double: 0
1013req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001014req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001015req_nested: {}
1016`,
1017 wantMessage: &pb2.Requireds{
1018 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001019 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001020 ReqDouble: scalar.Float64(0),
1021 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001022 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001023 ReqNested: &pb2.Nested{},
1024 },
1025 }, {
1026 desc: "indirect required field",
1027 inputMessage: &pb2.IndirectRequired{},
1028 inputText: "opt_nested: {}",
1029 wantMessage: &pb2.IndirectRequired{
1030 OptNested: &pb2.NestedWithRequired{},
1031 },
1032 wantErr: true,
1033 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001034 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001035 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001036 inputMessage: &pb2.IndirectRequired{},
1037 inputText: "opt_nested: {}",
1038 wantMessage: &pb2.IndirectRequired{
1039 OptNested: &pb2.NestedWithRequired{},
1040 },
1041 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001042 desc: "indirect required field in repeated",
1043 inputMessage: &pb2.IndirectRequired{},
1044 inputText: `
1045rpt_nested: {
1046 req_string: "one"
1047}
1048rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001049`,
1050 wantMessage: &pb2.IndirectRequired{
1051 RptNested: []*pb2.NestedWithRequired{
1052 {
1053 ReqString: scalar.String("one"),
1054 },
1055 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001056 },
1057 },
1058 wantErr: true,
1059 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001060 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001061 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001062 inputMessage: &pb2.IndirectRequired{},
1063 inputText: `
1064rpt_nested: {
1065 req_string: "one"
1066}
1067rpt_nested: {}
1068`,
1069 wantMessage: &pb2.IndirectRequired{
1070 RptNested: []*pb2.NestedWithRequired{
1071 {
1072 ReqString: scalar.String("one"),
1073 },
1074 {},
1075 },
1076 },
1077 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001078 desc: "indirect required field in map",
1079 inputMessage: &pb2.IndirectRequired{},
1080 inputText: `
1081str_to_nested: {
1082 key: "missing"
1083}
1084str_to_nested: {
1085 key: "contains"
1086 value: {
1087 req_string: "here"
1088 }
1089}
1090`,
1091 wantMessage: &pb2.IndirectRequired{
1092 StrToNested: map[string]*pb2.NestedWithRequired{
1093 "missing": &pb2.NestedWithRequired{},
1094 "contains": &pb2.NestedWithRequired{
1095 ReqString: scalar.String("here"),
1096 },
1097 },
1098 },
1099 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001100 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001101 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001102 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001103 inputMessage: &pb2.IndirectRequired{},
1104 inputText: `
1105str_to_nested: {
1106 key: "missing"
1107}
1108str_to_nested: {
1109 key: "contains"
1110 value: {
1111 req_string: "here"
1112 }
1113}
1114`,
1115 wantMessage: &pb2.IndirectRequired{
1116 StrToNested: map[string]*pb2.NestedWithRequired{
1117 "missing": &pb2.NestedWithRequired{},
1118 "contains": &pb2.NestedWithRequired{
1119 ReqString: scalar.String("here"),
1120 },
1121 },
1122 },
1123 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001124 desc: "indirect required field in oneof",
1125 inputMessage: &pb2.IndirectRequired{},
1126 inputText: `oneof_nested: {}
1127`,
1128 wantMessage: &pb2.IndirectRequired{
1129 Union: &pb2.IndirectRequired_OneofNested{
1130 OneofNested: &pb2.NestedWithRequired{},
1131 },
1132 },
1133 wantErr: true,
1134 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001135 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001136 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001137 inputMessage: &pb2.IndirectRequired{},
1138 inputText: `oneof_nested: {}
1139`,
1140 wantMessage: &pb2.IndirectRequired{
1141 Union: &pb2.IndirectRequired_OneofNested{
1142 OneofNested: &pb2.NestedWithRequired{},
1143 },
1144 },
1145 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001146 desc: "ignore reserved field",
1147 inputMessage: &pb2.Nests{},
1148 inputText: "reserved_field: 'ignore this'",
1149 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001150 }, {
1151 desc: "extensions of non-repeated fields",
1152 inputMessage: &pb2.Extensions{},
1153 inputText: `opt_string: "non-extension field"
1154[pb2.opt_ext_bool]: true
1155opt_bool: true
1156[pb2.opt_ext_nested]: {
1157 opt_string: "nested in an extension"
1158 opt_nested: {
1159 opt_string: "another nested in an extension"
1160 }
1161}
1162[pb2.opt_ext_string]: "extension field"
1163opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001164[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001165`,
1166 wantMessage: func() proto.Message {
1167 m := &pb2.Extensions{
1168 OptString: scalar.String("non-extension field"),
1169 OptBool: scalar.Bool(true),
1170 OptInt32: scalar.Int32(42),
1171 }
1172 setExtension(m, pb2.E_OptExtBool, true)
1173 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001174 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001175 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1176 OptString: scalar.String("nested in an extension"),
1177 OptNested: &pb2.Nested{
1178 OptString: scalar.String("another nested in an extension"),
1179 },
1180 })
1181 return m
1182 }(),
1183 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001184 desc: "extension field contains invalid UTF-8",
1185 inputMessage: &pb2.Extensions{},
1186 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -07001187 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -07001188 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001189 desc: "extensions of repeated fields",
1190 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001191 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001192[pb2.rpt_ext_enum]: 101
1193[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001194[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001195[pb2.rpt_ext_nested]: {
1196 opt_string: "one"
1197}
1198[pb2.rpt_ext_nested]: {
1199 opt_string: "two"
1200}
1201[pb2.rpt_ext_fixed32]: 47
1202[pb2.rpt_ext_nested]: {
1203 opt_string: "three"
1204}
1205`,
1206 wantMessage: func() proto.Message {
1207 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001208 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001209 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1210 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1211 &pb2.Nested{OptString: scalar.String("one")},
1212 &pb2.Nested{OptString: scalar.String("two")},
1213 &pb2.Nested{OptString: scalar.String("three")},
1214 })
1215 return m
1216 }(),
1217 }, {
1218 desc: "extensions of non-repeated fields in another message",
1219 inputMessage: &pb2.Extensions{},
1220 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001221[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001222[pb2.ExtensionsContainer.opt_ext_nested]: {
1223 opt_string: "nested in an extension"
1224 opt_nested: {
1225 opt_string: "another nested in an extension"
1226 }
1227}
1228[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1229`,
1230 wantMessage: func() proto.Message {
1231 m := &pb2.Extensions{}
1232 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1233 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001234 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001235 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1236 OptString: scalar.String("nested in an extension"),
1237 OptNested: &pb2.Nested{
1238 OptString: scalar.String("another nested in an extension"),
1239 },
1240 })
1241 return m
1242 }(),
1243 }, {
1244 desc: "extensions of repeated fields in another message",
1245 inputMessage: &pb2.Extensions{},
1246 inputText: `opt_string: "non-extension field"
1247opt_bool: true
1248opt_int32: 42
1249[pb2.ExtensionsContainer.rpt_ext_nested]: {
1250 opt_string: "one"
1251}
Herbie Ong8170d692019-02-13 14:13:21 -08001252[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001253[pb2.ExtensionsContainer.rpt_ext_nested]: {
1254 opt_string: "two"
1255}
1256[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1257[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001258[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001259[pb2.ExtensionsContainer.rpt_ext_nested]: {
1260 opt_string: "three"
1261}
1262[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1263`,
1264 wantMessage: func() proto.Message {
1265 m := &pb2.Extensions{
1266 OptString: scalar.String("non-extension field"),
1267 OptBool: scalar.Bool(true),
1268 OptInt32: scalar.Int32(42),
1269 }
Herbie Ong8170d692019-02-13 14:13:21 -08001270 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001271 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1272 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1273 &pb2.Nested{OptString: scalar.String("one")},
1274 &pb2.Nested{OptString: scalar.String("two")},
1275 &pb2.Nested{OptString: scalar.String("three")},
1276 })
1277 return m
1278 }(),
1279 }, {
1280 desc: "invalid extension field name",
1281 inputMessage: &pb2.Extensions{},
1282 inputText: "[pb2.invalid_message_field]: true",
1283 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001284 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001285 desc: "MessageSet",
1286 inputMessage: &pb2.MessageSet{},
1287 inputText: `
1288[pb2.MessageSetExtension]: {
1289 opt_string: "a messageset extension"
1290}
1291[pb2.MessageSetExtension.ext_nested]: {
1292 opt_string: "just a regular extension"
1293}
1294[pb2.MessageSetExtension.not_message_set_extension]: {
1295 opt_string: "not a messageset extension"
1296}
1297`,
1298 wantMessage: func() proto.Message {
1299 m := &pb2.MessageSet{}
1300 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1301 OptString: scalar.String("a messageset extension"),
1302 })
1303 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1304 OptString: scalar.String("not a messageset extension"),
1305 })
1306 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1307 OptString: scalar.String("just a regular extension"),
1308 })
1309 return m
1310 }(),
1311 }, {
1312 desc: "not real MessageSet 1",
1313 inputMessage: &pb2.FakeMessageSet{},
1314 inputText: `
1315[pb2.FakeMessageSetExtension.message_set_extension]: {
1316 opt_string: "not a messageset extension"
1317}
1318`,
1319 wantMessage: func() proto.Message {
1320 m := &pb2.FakeMessageSet{}
1321 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1322 OptString: scalar.String("not a messageset extension"),
1323 })
1324 return m
1325 }(),
1326 }, {
1327 desc: "not real MessageSet 2",
1328 inputMessage: &pb2.FakeMessageSet{},
1329 inputText: `
1330[pb2.FakeMessageSetExtension]: {
1331 opt_string: "not a messageset extension"
1332}
1333`,
1334 wantErr: true,
1335 }, {
1336 desc: "not real MessageSet 3",
1337 inputMessage: &pb2.MessageSet{},
1338 inputText: `
1339[pb2.message_set_extension]: {
1340 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001341}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001342 wantMessage: func() proto.Message {
1343 m := &pb2.MessageSet{}
1344 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1345 OptString: scalar.String("another not a messageset extension"),
1346 })
1347 return m
1348 }(),
1349 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001350 desc: "Any not expanded",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001351 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001352 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001353type_url: "pb2.Nested"
1354value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001355`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001356 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001357 TypeUrl: "pb2.Nested",
1358 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001359 },
1360 }, {
1361 desc: "Any not expanded missing value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001362 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001363 inputText: `type_url: "pb2.Nested"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001364 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001365 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001366 },
1367 }, {
1368 desc: "Any not expanded missing type_url",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001369 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001370 inputText: `value: "some bytes"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001371 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001372 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001373 },
1374 }, {
1375 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001376 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001377 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001378 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001379 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001380 inputText: `
1381[foobar/pb2.Nested]: {
1382 opt_string: "embedded inside Any"
1383 opt_nested: {
1384 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001385 }
1386}
1387`,
1388 wantMessage: func() proto.Message {
1389 m := &pb2.Nested{
1390 OptString: scalar.String("embedded inside Any"),
1391 OptNested: &pb2.Nested{
1392 OptString: scalar.String("inception"),
1393 },
1394 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001395 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001396 if err != nil {
1397 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1398 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001399 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001400 TypeUrl: "foobar/pb2.Nested",
1401 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001402 }
1403 }(),
1404 }, {
1405 desc: "Any expanded with empty value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001406 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001407 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001408 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001410 inputText: `[foo.com/pb2.Nested]: {}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001411 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001412 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001413 },
1414 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001415 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001416 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001417 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001418 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001419 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001420 inputText: `
1421[pb2.PartialRequired]: {
1422 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001423}
1424`,
1425 wantMessage: func() proto.Message {
1426 m := &pb2.PartialRequired{
1427 OptString: scalar.String("embedded inside Any"),
1428 }
Damien Neil96c229a2019-04-03 12:17:24 -07001429 b, err := proto.MarshalOptions{
1430 AllowPartial: true,
1431 Deterministic: true,
1432 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001433 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001434 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1435 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001436 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001437 TypeUrl: "pb2.PartialRequired",
1438 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001439 }
1440 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001441 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001442 desc: "Any with invalid UTF-8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001443 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001444 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
Herbie Ong21a39742019-04-08 17:32:44 -07001445 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001446 inputMessage: &anypb.Any{},
Herbie Ong21a39742019-04-08 17:32:44 -07001447 inputText: `
1448[pb3.Nested]: {
1449 s_string: "abc\xff"
1450}
1451`,
Herbie Ong21a39742019-04-08 17:32:44 -07001452 wantErr: true,
1453 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001454 desc: "Any expanded with unregistered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001455 umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001456 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001457 inputText: `[SomeMessage]: {}`,
1458 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001459 }, {
1460 desc: "Any expanded with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001461 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001462 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001463 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001464 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001465 inputText: `[pb2.Nested]: 123`,
1466 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001467 }, {
1468 desc: "Any expanded with unknown fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001469 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001470 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001471 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001472 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001473 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001474[pb2.Nested]: {}
1475unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001476`,
1477 wantErr: true,
1478 }, {
1479 desc: "Any contains expanded and unexpanded fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001480 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001481 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001482 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001483 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001484 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001485[pb2.Nested]: {}
1486type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001487`,
1488 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001489 }}
1490
1491 for _, tt := range tests {
1492 tt := tt
1493 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07001494 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ong800c9902018-12-06 15:28:53 -08001495 if err != nil && !tt.wantErr {
1496 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1497 }
1498 if err == nil && tt.wantErr {
1499 t.Error("Unmarshal() got nil error, want error\n\n")
1500 }
Herbie Ong70651952018-12-13 14:19:50 -08001501 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001502 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1503 }
1504 })
1505 }
1506}