blob: e98b0b3c2b007f4b21db27d3163f38955c490663 [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
5package textpb_test
6
7import (
8 "math"
9 "testing"
10
11 protoV1 "github.com/golang/protobuf/proto"
12 "github.com/golang/protobuf/v2/encoding/textpb"
Herbie Ong21a39742019-04-08 17:32:44 -070013 "github.com/golang/protobuf/v2/internal/errors"
Herbie Ongc525c972018-12-18 18:04:31 -080014 "github.com/golang/protobuf/v2/internal/legacy"
Herbie Ong800c9902018-12-06 15:28:53 -080015 "github.com/golang/protobuf/v2/internal/scalar"
Herbie Ong70651952018-12-13 14:19:50 -080016 "github.com/golang/protobuf/v2/proto"
Herbie Ongc525c972018-12-18 18:04:31 -080017 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Joe Tsai4fddeba2019-03-20 18:29:32 -070018 "github.com/golang/protobuf/v2/runtime/protoiface"
Herbie Ong800c9902018-12-06 15:28:53 -080019
Herbie Ong8170d692019-02-13 14:13:21 -080020 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
21 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Joe Tsai19058432019-02-27 21:46:29 -080022 knownpb "github.com/golang/protobuf/v2/types/known"
Herbie Ong800c9902018-12-06 15:28:53 -080023)
24
Herbie Ongc525c972018-12-18 18:04:31 -080025func init() {
Herbie Ong8170d692019-02-13 14:13:21 -080026 // TODO: remove these registerExtension calls when generated code registers
27 // to V2 global registry.
Herbie Ongc525c972018-12-18 18:04:31 -080028 registerExtension(pb2.E_OptExtBool)
29 registerExtension(pb2.E_OptExtString)
30 registerExtension(pb2.E_OptExtEnum)
31 registerExtension(pb2.E_OptExtNested)
32 registerExtension(pb2.E_RptExtFixed32)
33 registerExtension(pb2.E_RptExtEnum)
34 registerExtension(pb2.E_RptExtNested)
35 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
36 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
37 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
38 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
39 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
40 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
41 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
Herbie Ong6470ea62019-01-07 18:56:57 -080042 registerExtension(pb2.E_MessageSetExtension)
43 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
44 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
45 registerExtension(pb2.E_MessageSetExtension_ExtNested)
46 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
Herbie Ongc525c972018-12-18 18:04:31 -080047}
48
Joe Tsai4fddeba2019-03-20 18:29:32 -070049func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Ongc525c972018-12-18 18:04:31 -080050 xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
51 preg.GlobalTypes.Register(xt)
52}
53
Herbie Ong800c9902018-12-06 15:28:53 -080054func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080055 tests := []struct {
56 desc string
Herbie Ong66c365c2019-01-04 14:08:41 -080057 umo textpb.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080058 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080059 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080060 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070061 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080062 }{{
63 desc: "proto2 empty message",
64 inputMessage: &pb2.Scalars{},
65 wantMessage: &pb2.Scalars{},
66 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080067 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080068 inputMessage: &pb2.Scalars{},
69 inputText: `opt_bool: false
70opt_int32: 0
71opt_int64: 0
72opt_uint32: 0
73opt_uint64: 0
74opt_sint32: 0
75opt_sint64: 0
76opt_fixed32: 0
77opt_fixed64: 0
78opt_sfixed32: 0
79opt_sfixed64: 0
80opt_float: 0
81opt_double: 0
82opt_bytes: ""
83opt_string: ""
84`,
85 wantMessage: &pb2.Scalars{
86 OptBool: scalar.Bool(false),
87 OptInt32: scalar.Int32(0),
88 OptInt64: scalar.Int64(0),
89 OptUint32: scalar.Uint32(0),
90 OptUint64: scalar.Uint64(0),
91 OptSint32: scalar.Int32(0),
92 OptSint64: scalar.Int64(0),
93 OptFixed32: scalar.Uint32(0),
94 OptFixed64: scalar.Uint64(0),
95 OptSfixed32: scalar.Int32(0),
96 OptSfixed64: scalar.Int64(0),
97 OptFloat: scalar.Float32(0),
98 OptDouble: scalar.Float64(0),
99 OptBytes: []byte{},
100 OptString: scalar.String(""),
101 },
102 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800103 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800104 inputMessage: &pb3.Scalars{},
105 inputText: `s_bool: false
106s_int32: 0
107s_int64: 0
108s_uint32: 0
109s_uint64: 0
110s_sint32: 0
111s_sint64: 0
112s_fixed32: 0
113s_fixed64: 0
114s_sfixed32: 0
115s_sfixed64: 0
116s_float: 0
117s_double: 0
118s_bytes: ""
119s_string: ""
120`,
121 wantMessage: &pb3.Scalars{},
122 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800123 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800124 inputMessage: &pb2.Scalars{},
125 inputText: `opt_bool: true
126opt_int32: 255
127opt_int64: 3735928559
128opt_uint32: 0xff
129opt_uint64: 0xdeadbeef
130opt_sint32: -1001
131opt_sint64: -0xffff
132opt_fixed64: 64
133opt_sfixed32: -32
134opt_float: 1.234
135opt_double: 1.23e+100
136opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
137opt_string: "谷歌"
138`,
139 wantMessage: &pb2.Scalars{
140 OptBool: scalar.Bool(true),
141 OptInt32: scalar.Int32(0xff),
142 OptInt64: scalar.Int64(0xdeadbeef),
143 OptUint32: scalar.Uint32(0xff),
144 OptUint64: scalar.Uint64(0xdeadbeef),
145 OptSint32: scalar.Int32(-1001),
146 OptSint64: scalar.Int64(-0xffff),
147 OptFixed64: scalar.Uint64(64),
148 OptSfixed32: scalar.Int32(-32),
149 OptFloat: scalar.Float32(1.234),
150 OptDouble: scalar.Float64(1.23e100),
151 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
152 OptString: scalar.String("谷歌"),
153 },
154 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800155 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800156 inputMessage: &pb3.Scalars{},
157 inputText: `s_bool: true
158s_int32: 255
159s_int64: 3735928559
160s_uint32: 0xff
161s_uint64: 0xdeadbeef
162s_sint32: -1001
163s_sint64: -0xffff
164s_fixed64: 64
165s_sfixed32: -32
166s_float: 1.234
167s_double: 1.23e+100
168s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
169s_string: "谷歌"
170`,
171 wantMessage: &pb3.Scalars{
172 SBool: true,
173 SInt32: 0xff,
174 SInt64: 0xdeadbeef,
175 SUint32: 0xff,
176 SUint64: 0xdeadbeef,
177 SSint32: -1001,
178 SSint64: -0xffff,
179 SFixed64: 64,
180 SSfixed32: -32,
181 SFloat: 1.234,
182 SDouble: 1.23e100,
183 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
184 SString: "谷歌",
185 },
186 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700187 desc: "string with invalid UTF-8",
188 inputMessage: &pb3.Scalars{},
189 inputText: `s_string: "abc\xff"`,
190 wantMessage: &pb3.Scalars{
191 SString: "abc\xff",
192 },
193 wantErr: true,
194 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800195 desc: "proto2 message contains unknown field",
196 inputMessage: &pb2.Scalars{},
197 inputText: "unknown_field: 123",
198 wantErr: true,
199 }, {
200 desc: "proto3 message contains unknown field",
201 inputMessage: &pb3.Scalars{},
202 inputText: "unknown_field: 456",
203 wantErr: true,
204 }, {
205 desc: "proto2 numeric key field",
206 inputMessage: &pb2.Scalars{},
207 inputText: "1: true",
208 wantErr: true,
209 }, {
210 desc: "proto3 numeric key field",
211 inputMessage: &pb3.Scalars{},
212 inputText: "1: true",
213 wantErr: true,
214 }, {
215 desc: "invalid bool value",
216 inputMessage: &pb3.Scalars{},
217 inputText: "s_bool: 123",
218 wantErr: true,
219 }, {
220 desc: "invalid int32 value",
221 inputMessage: &pb3.Scalars{},
222 inputText: "s_int32: not_a_num",
223 wantErr: true,
224 }, {
225 desc: "invalid int64 value",
226 inputMessage: &pb3.Scalars{},
227 inputText: "s_int64: 'not a num either'",
228 wantErr: true,
229 }, {
230 desc: "invalid uint32 value",
231 inputMessage: &pb3.Scalars{},
232 inputText: "s_fixed32: -42",
233 wantErr: true,
234 }, {
235 desc: "invalid uint64 value",
236 inputMessage: &pb3.Scalars{},
237 inputText: "s_uint64: -47",
238 wantErr: true,
239 }, {
240 desc: "invalid sint32 value",
241 inputMessage: &pb3.Scalars{},
242 inputText: "s_sint32: '42'",
243 wantErr: true,
244 }, {
245 desc: "invalid sint64 value",
246 inputMessage: &pb3.Scalars{},
247 inputText: "s_sint64: '-47'",
248 wantErr: true,
249 }, {
250 desc: "invalid fixed32 value",
251 inputMessage: &pb3.Scalars{},
252 inputText: "s_fixed32: -42",
253 wantErr: true,
254 }, {
255 desc: "invalid fixed64 value",
256 inputMessage: &pb3.Scalars{},
257 inputText: "s_fixed64: -42",
258 wantErr: true,
259 }, {
260 desc: "invalid sfixed32 value",
261 inputMessage: &pb3.Scalars{},
262 inputText: "s_sfixed32: 'not valid'",
263 wantErr: true,
264 }, {
265 desc: "invalid sfixed64 value",
266 inputMessage: &pb3.Scalars{},
267 inputText: "s_sfixed64: bad",
268 wantErr: true,
269 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800270 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800271 inputMessage: &pb3.Scalars{},
272 inputText: "s_float: inf",
273 wantMessage: &pb3.Scalars{
274 SFloat: float32(math.Inf(1)),
275 },
276 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800277 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800278 inputMessage: &pb3.Scalars{},
279 inputText: "s_float: -inf",
280 wantMessage: &pb3.Scalars{
281 SFloat: float32(math.Inf(-1)),
282 },
283 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800284 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800285 inputMessage: &pb3.Scalars{},
286 inputText: "s_double: inf",
287 wantMessage: &pb3.Scalars{
288 SDouble: math.Inf(1),
289 },
290 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800291 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800292 inputMessage: &pb3.Scalars{},
293 inputText: "s_double: -inf",
294 wantMessage: &pb3.Scalars{
295 SDouble: math.Inf(-1),
296 },
297 }, {
298 desc: "invalid string value",
299 inputMessage: &pb3.Scalars{},
300 inputText: "s_string: invalid_string",
301 wantErr: true,
302 }, {
303 desc: "proto2 bytes set to empty string",
304 inputMessage: &pb2.Scalars{},
305 inputText: "opt_bytes: ''",
306 wantMessage: &pb2.Scalars{
307 OptBytes: []byte(""),
308 },
309 }, {
310 desc: "proto3 bytes set to empty string",
311 inputMessage: &pb3.Scalars{},
312 inputText: "s_bytes: ''",
313 wantMessage: &pb3.Scalars{},
314 }, {
315 desc: "proto2 duplicate singular field",
316 inputMessage: &pb2.Scalars{},
317 inputText: `
318opt_bool: true
319opt_bool: false
320`,
321 wantErr: true,
322 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800323 desc: "proto2 more duplicate singular field",
324 inputMessage: &pb2.Scalars{},
325 inputText: `
326opt_bool: true
327opt_string: "hello"
328opt_bool: false
329`,
330 wantErr: true,
331 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800332 desc: "proto2 invalid singular field",
333 inputMessage: &pb2.Scalars{},
334 inputText: `
335opt_bool: [true, false]
336`,
337 wantErr: true,
338 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800339 desc: "proto3 duplicate singular field",
340 inputMessage: &pb3.Scalars{},
341 inputText: `
342s_bool: false
343s_bool: true
344`,
345 wantErr: true,
346 }, {
347 desc: "proto3 more duplicate singular field",
348 inputMessage: &pb3.Scalars{},
349 inputText: `
350s_bool: false
351s_string: ""
352s_bool: true
353`,
354 wantErr: true,
355 }, {
356 desc: "proto2 enum",
357 inputMessage: &pb2.Enums{},
358 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800359opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800360opt_nested_enum: UNO
361`,
362 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800363 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800364 OptNestedEnum: pb2.Enums_UNO.Enum(),
365 },
366 }, {
367 desc: "proto2 enum set to numeric values",
368 inputMessage: &pb2.Enums{},
369 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800370opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800371opt_nested_enum: 2
372`,
373 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800374 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800375 OptNestedEnum: pb2.Enums_DOS.Enum(),
376 },
377 }, {
378 desc: "proto2 enum set to unnamed numeric values",
379 inputMessage: &pb2.Enums{},
380 inputText: `
381opt_enum: 101
382opt_nested_enum: -101
383`,
384 wantMessage: &pb2.Enums{
385 OptEnum: pb2Enum(101),
386 OptNestedEnum: pb2Enums_NestedEnum(-101),
387 },
388 }, {
389 desc: "proto2 enum set to invalid named",
390 inputMessage: &pb2.Enums{},
391 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800392opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800393opt_nested_enum: UNNAMED_TOO
394`,
395 wantErr: true,
396 }, {
397 desc: "proto3 enum name value",
398 inputMessage: &pb3.Enums{},
399 inputText: `
400s_enum: ONE
401s_nested_enum: DIEZ
402`,
403 wantMessage: &pb3.Enums{
404 SEnum: pb3.Enum_ONE,
405 SNestedEnum: pb3.Enums_DIEZ,
406 },
407 }, {
408 desc: "proto3 enum numeric value",
409 inputMessage: &pb3.Enums{},
410 inputText: `
411s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800412s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800413`,
414 wantMessage: &pb3.Enums{
415 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800416 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800417 },
418 }, {
419 desc: "proto3 enum unnamed numeric value",
420 inputMessage: &pb3.Enums{},
421 inputText: `
422s_enum: 0x7fffffff
423s_nested_enum: -0x80000000
424`,
425 wantMessage: &pb3.Enums{
426 SEnum: 0x7fffffff,
427 SNestedEnum: -0x80000000,
428 },
429 }, {
430 desc: "proto2 nested empty messages",
431 inputMessage: &pb2.Nests{},
432 inputText: `
433opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800434OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800435`,
436 wantMessage: &pb2.Nests{
437 OptNested: &pb2.Nested{},
438 Optgroup: &pb2.Nests_OptGroup{},
439 },
440 }, {
441 desc: "proto2 nested messages",
442 inputMessage: &pb2.Nests{},
443 inputText: `
444opt_nested: {
445 opt_string: "nested message"
446 opt_nested: {
447 opt_string: "another nested message"
448 }
449}
450`,
451 wantMessage: &pb2.Nests{
452 OptNested: &pb2.Nested{
453 OptString: scalar.String("nested message"),
454 OptNested: &pb2.Nested{
455 OptString: scalar.String("another nested message"),
456 },
457 },
458 },
459 }, {
460 desc: "proto3 nested empty message",
461 inputMessage: &pb3.Nests{},
462 inputText: "s_nested: {}",
463 wantMessage: &pb3.Nests{
464 SNested: &pb3.Nested{},
465 },
466 }, {
467 desc: "proto3 nested message",
468 inputMessage: &pb3.Nests{},
469 inputText: `
470s_nested: {
471 s_string: "nested message"
472 s_nested: {
473 s_string: "another nested message"
474 }
475}
476`,
477 wantMessage: &pb3.Nests{
478 SNested: &pb3.Nested{
479 SString: "nested message",
480 SNested: &pb3.Nested{
481 SString: "another nested message",
482 },
483 },
484 },
485 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700486 desc: "proto3 nested message contains invalid UTF-8",
487 inputMessage: &pb3.Nests{},
488 inputText: `s_nested: {
489 s_string: "abc\xff"
490}
491`,
492 wantMessage: &pb3.Nests{
493 SNested: &pb3.Nested{
494 SString: "abc\xff",
495 },
496 },
497 wantErr: true,
498 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800499 desc: "oneof set to empty string",
500 inputMessage: &pb3.Oneofs{},
501 inputText: "oneof_string: ''",
502 wantMessage: &pb3.Oneofs{
503 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800504 },
505 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800506 desc: "oneof set to string",
507 inputMessage: &pb3.Oneofs{},
508 inputText: "oneof_string: 'hello'",
509 wantMessage: &pb3.Oneofs{
510 Union: &pb3.Oneofs_OneofString{
511 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800512 },
513 },
514 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800515 desc: "oneof set to enum",
516 inputMessage: &pb3.Oneofs{},
517 inputText: "oneof_enum: TEN",
518 wantMessage: &pb3.Oneofs{
519 Union: &pb3.Oneofs_OneofEnum{
520 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800521 },
522 },
523 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800524 desc: "oneof set to empty message",
525 inputMessage: &pb3.Oneofs{},
526 inputText: "oneof_nested: {}",
527 wantMessage: &pb3.Oneofs{
528 Union: &pb3.Oneofs_OneofNested{
529 OneofNested: &pb3.Nested{},
530 },
531 },
532 }, {
533 desc: "oneof set to message",
534 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800535 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800536oneof_nested: {
537 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800538}
539`,
Herbie Ong8170d692019-02-13 14:13:21 -0800540 wantMessage: &pb3.Oneofs{
541 Union: &pb3.Oneofs_OneofNested{
542 OneofNested: &pb3.Nested{
543 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800544 },
545 },
546 },
547 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700548 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800549 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800550 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700551oneof_enum: ZERO
552oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800553`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700554 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800555 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800556 desc: "repeated scalar using same field name",
557 inputMessage: &pb2.Repeats{},
558 inputText: `
559rpt_string: "a"
560rpt_string: "b"
561rpt_int32: 0xff
562rpt_float: 1.23
563rpt_bytes: "bytes"
564`,
565 wantMessage: &pb2.Repeats{
566 RptString: []string{"a", "b"},
567 RptInt32: []int32{0xff},
568 RptFloat: []float32{1.23},
569 RptBytes: [][]byte{[]byte("bytes")},
570 },
571 }, {
572 desc: "repeated using mix of [] and repeated field name",
573 inputMessage: &pb2.Repeats{},
574 inputText: `
575rpt_string: "a"
576rpt_bool: true
577rpt_string: ["x", "y"]
578rpt_bool: [ false, true ]
579rpt_string: "b"
580`,
581 wantMessage: &pb2.Repeats{
582 RptString: []string{"a", "x", "y", "b"},
583 RptBool: []bool{true, false, true},
584 },
585 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700586 desc: "repeated contains invalid UTF-8",
587 inputMessage: &pb2.Repeats{},
588 inputText: `rpt_string: "abc\xff"`,
589 wantMessage: &pb2.Repeats{
590 RptString: []string{"abc\xff"},
591 },
592 wantErr: true,
593 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800594 desc: "repeated enums",
595 inputMessage: &pb2.Enums{},
596 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800597rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800598rpt_enum: 1
599rpt_nested_enum: [DOS, 2]
600rpt_enum: 42
601rpt_nested_enum: -47
602`,
603 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800604 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800605 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
606 },
607 }, {
608 desc: "repeated nested messages",
609 inputMessage: &pb2.Nests{},
610 inputText: `
611rpt_nested: {
612 opt_string: "repeat nested one"
613}
614rpt_nested: {
615 opt_string: "repeat nested two"
616 opt_nested: {
617 opt_string: "inside repeat nested two"
618 }
619}
620rpt_nested: {}
621`,
622 wantMessage: &pb2.Nests{
623 RptNested: []*pb2.Nested{
624 {
625 OptString: scalar.String("repeat nested one"),
626 },
627 {
628 OptString: scalar.String("repeat nested two"),
629 OptNested: &pb2.Nested{
630 OptString: scalar.String("inside repeat nested two"),
631 },
632 },
633 {},
634 },
635 },
636 }, {
637 desc: "repeated group fields",
638 inputMessage: &pb2.Nests{},
639 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800640RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800641 rpt_string: "hello"
642 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800643}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800644RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800645`,
646 wantMessage: &pb2.Nests{
647 Rptgroup: []*pb2.Nests_RptGroup{
648 {
Herbie Ong8170d692019-02-13 14:13:21 -0800649 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800650 },
651 {},
652 },
653 },
654 }, {
655 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800656 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800657 inputText: `
658int32_to_str: {
659 key: -101
660 value: "-101"
661}
662int32_to_str: {
663 key: 0
664 value: "zero"
665}
Herbie Ong8170d692019-02-13 14:13:21 -0800666bool_to_uint32: {
667 key: false
668 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800669}
670int32_to_str: {
671 key: 255
672 value: "0xff"
673}
674bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800675 key: true
676 value: 42
677}
678`,
Herbie Ong8170d692019-02-13 14:13:21 -0800679 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800680 Int32ToStr: map[int32]string{
681 -101: "-101",
682 0xff: "0xff",
683 0: "zero",
684 },
Herbie Ong800c9902018-12-06 15:28:53 -0800685 BoolToUint32: map[bool]uint32{
686 true: 42,
687 false: 101,
688 },
689 },
690 }, {
691 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800692 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800693 inputText: `
694uint64_to_enum: {
695 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800696 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800697}
698uint64_to_enum: {
699 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800700 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800701}
702uint64_to_enum: {
703 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800704 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800705}
706`,
Herbie Ong8170d692019-02-13 14:13:21 -0800707 wantMessage: &pb3.Maps{
708 Uint64ToEnum: map[uint64]pb3.Enum{
709 1: pb3.Enum_ONE,
710 2: pb3.Enum_TWO,
711 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800712 },
713 },
714 }, {
715 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800716 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800717 inputText: `
718str_to_nested: {
719 key: "nested_one"
720 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800721 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800722 }
723}
724`,
Herbie Ong8170d692019-02-13 14:13:21 -0800725 wantMessage: &pb3.Maps{
726 StrToNested: map[string]*pb3.Nested{
727 "nested_one": &pb3.Nested{
728 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800729 },
730 },
731 },
732 }, {
733 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800734 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800735 inputText: `
736str_to_oneofs: {
737 key: "nested"
738 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800739 oneof_nested: {
740 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800741 }
742 }
743}
744str_to_oneofs: {
745 key: "string"
746 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800747 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800748 }
749}
750`,
Herbie Ong8170d692019-02-13 14:13:21 -0800751 wantMessage: &pb3.Maps{
752 StrToOneofs: map[string]*pb3.Oneofs{
753 "string": &pb3.Oneofs{
754 Union: &pb3.Oneofs_OneofString{
755 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800756 },
757 },
Herbie Ong8170d692019-02-13 14:13:21 -0800758 "nested": &pb3.Oneofs{
759 Union: &pb3.Oneofs_OneofNested{
760 OneofNested: &pb3.Nested{
761 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800762 },
763 },
764 },
765 },
766 },
767 }, {
768 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800769 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800770 inputText: `
771int32_to_str: {
772 key: 0
773 value: "cero"
774}
775int32_to_str: {
776 key: 0
777 value: "zero"
778}
779`,
Herbie Ong8170d692019-02-13 14:13:21 -0800780 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800781 Int32ToStr: map[int32]string{
782 0: "zero",
783 },
784 },
785 }, {
786 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800787 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800788 inputText: `
789int32_to_str: {
790 key: 0
791 key: 1
792 value: "cero"
793}
794`,
795 wantErr: true,
796 }, {
797 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800798 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800799 inputText: `
800int32_to_str: {
801 key: 1
802 value: "cero"
803 value: "uno"
804}
805`,
806 wantErr: true,
807 }, {
808 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800809 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800810 inputText: `
811int32_to_str: {
812 value: "zero"
813}
Herbie Ong8170d692019-02-13 14:13:21 -0800814bool_to_uint32: {
815 value: 47
816}
817str_to_nested: {
818 value: {}
819}
Herbie Ong800c9902018-12-06 15:28:53 -0800820`,
Herbie Ong8170d692019-02-13 14:13:21 -0800821 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800822 Int32ToStr: map[int32]string{
823 0: "zero",
824 },
Herbie Ong8170d692019-02-13 14:13:21 -0800825 BoolToUint32: map[bool]uint32{
826 false: 47,
827 },
828 StrToNested: map[string]*pb3.Nested{
829 "": {},
830 },
Herbie Ong800c9902018-12-06 15:28:53 -0800831 },
832 }, {
833 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800834 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800835 inputText: `
836int32_to_str: {
837 key: 100
838}
Herbie Ong8170d692019-02-13 14:13:21 -0800839bool_to_uint32: {
840 key: true
841}
842uint64_to_enum: {
843 key: 101
844}
845str_to_nested: {
846 key: "hello"
847}
Herbie Ong800c9902018-12-06 15:28:53 -0800848`,
Herbie Ong8170d692019-02-13 14:13:21 -0800849 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800850 Int32ToStr: map[int32]string{
851 100: "",
852 },
Herbie Ong8170d692019-02-13 14:13:21 -0800853 BoolToUint32: map[bool]uint32{
854 true: 0,
855 },
856 Uint64ToEnum: map[uint64]pb3.Enum{
857 101: pb3.Enum_ZERO,
858 },
859 StrToNested: map[string]*pb3.Nested{
860 "hello": {},
861 },
Herbie Ong800c9902018-12-06 15:28:53 -0800862 },
863 }, {
864 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800865 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800866 inputText: `
867int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800868bool_to_uint32: {}
869uint64_to_enum: {}
870str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800871`,
Herbie Ong8170d692019-02-13 14:13:21 -0800872 wantMessage: &pb3.Maps{
873 Int32ToStr: map[int32]string{
874 0: "",
875 },
876 BoolToUint32: map[bool]uint32{
877 false: 0,
878 },
879 Uint64ToEnum: map[uint64]pb3.Enum{
880 0: pb3.Enum_ZERO,
881 },
882 StrToNested: map[string]*pb3.Nested{
883 "": {},
884 },
885 },
886 }, {
887 desc: "map contains overriding entries",
888 inputMessage: &pb3.Maps{},
889 inputText: `
890int32_to_str: {
891 key: 0
892}
893int32_to_str: {
894 value: "empty"
895}
896int32_to_str: {}
897`,
898 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800899 Int32ToStr: map[int32]string{
900 0: "",
901 },
902 },
903 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700904 desc: "map field value contains invalid UTF-8",
905 inputMessage: &pb3.Maps{},
906 inputText: `int32_to_str: {
907 key: 101
908 value: "abc\xff"
909}
910`,
911 wantMessage: &pb3.Maps{
912 Int32ToStr: map[int32]string{
913 101: "abc\xff",
914 },
915 },
916 wantErr: true,
917 }, {
918 desc: "map field key contains invalid UTF-8",
919 inputMessage: &pb3.Maps{},
920 inputText: `str_to_nested: {
921 key: "abc\xff"
922 value: {}
923}
924`,
925 wantMessage: &pb3.Maps{
926 StrToNested: map[string]*pb3.Nested{
927 "abc\xff": {},
928 },
929 },
930 wantErr: true,
931 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800932 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800933 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800934 inputText: `
935int32_to_str: {
936 key: 0
937 value: "cero"
938 unknown: "bad"
939}
940`,
941 wantErr: true,
942 }, {
943 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800944 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800945 inputText: `
946int32_to_str: {
947 [key]: 10
948 value: "ten"
949}
950`,
951 wantErr: true,
952 }, {
953 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800954 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800955 inputText: `
956int32_to_str: {
957 key: "invalid"
958 value: "cero"
959}
960`,
961 wantErr: true,
962 }, {
963 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800964 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800965 inputText: `
966int32_to_str: {
967 key: 100
968 value: 101
969}
970`,
971 wantErr: true,
972 }, {
973 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800974 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800975 inputText: `
976int32_to_str: {
977 key: 1
978 value: "one"
979}
980int32_to_str: [
981 {
982 key: 2
983 value: "not this"
984 },
985 {
986 },
987 {
988 key: 3
989 value: "three"
990 }
991]
992int32_to_str: {
993 key: 2
994 value: "two"
995}
996`,
Herbie Ong8170d692019-02-13 14:13:21 -0800997 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800998 Int32ToStr: map[int32]string{
999 0: "",
1000 1: "one",
1001 2: "two",
1002 3: "three",
1003 },
1004 },
1005 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001006 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -08001007 inputMessage: &pb2.Requireds{},
1008 wantErr: true,
1009 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001010 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -08001011 inputMessage: &pb2.PartialRequired{},
1012 inputText: "req_string: 'this is required'",
1013 wantMessage: &pb2.PartialRequired{
1014 ReqString: scalar.String("this is required"),
1015 },
1016 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001017 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -08001018 inputMessage: &pb2.Requireds{},
1019 inputText: `
1020req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001021req_sfixed64: 3203386110
1022req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001023req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001024`,
1025 wantMessage: &pb2.Requireds{
1026 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001027 ReqSfixed64: scalar.Int64(0xbeefcafe),
1028 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -08001029 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001030 },
1031 wantErr: true,
1032 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001033 desc: "required fields partially set with AllowPartial",
1034 umo: textpb.UnmarshalOptions{AllowPartial: true},
1035 inputMessage: &pb2.Requireds{},
1036 inputText: `
1037req_bool: false
1038req_sfixed64: 3203386110
1039req_string: "hello"
1040req_enum: ONE
1041`,
1042 wantMessage: &pb2.Requireds{
1043 ReqBool: scalar.Bool(false),
1044 ReqSfixed64: scalar.Int64(0xbeefcafe),
1045 ReqString: scalar.String("hello"),
1046 ReqEnum: pb2.Enum_ONE.Enum(),
1047 },
1048 }, {
1049 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001050 inputMessage: &pb2.Requireds{},
1051 inputText: `
1052req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001053req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001054req_double: 0
1055req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001056req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001057req_nested: {}
1058`,
1059 wantMessage: &pb2.Requireds{
1060 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001061 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001062 ReqDouble: scalar.Float64(0),
1063 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001064 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001065 ReqNested: &pb2.Nested{},
1066 },
1067 }, {
1068 desc: "indirect required field",
1069 inputMessage: &pb2.IndirectRequired{},
1070 inputText: "opt_nested: {}",
1071 wantMessage: &pb2.IndirectRequired{
1072 OptNested: &pb2.NestedWithRequired{},
1073 },
1074 wantErr: true,
1075 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001076 desc: "indirect required field with AllowPartial",
1077 umo: textpb.UnmarshalOptions{AllowPartial: true},
1078 inputMessage: &pb2.IndirectRequired{},
1079 inputText: "opt_nested: {}",
1080 wantMessage: &pb2.IndirectRequired{
1081 OptNested: &pb2.NestedWithRequired{},
1082 },
1083 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001084 desc: "indirect required field in repeated",
1085 inputMessage: &pb2.IndirectRequired{},
1086 inputText: `
1087rpt_nested: {
1088 req_string: "one"
1089}
1090rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001091`,
1092 wantMessage: &pb2.IndirectRequired{
1093 RptNested: []*pb2.NestedWithRequired{
1094 {
1095 ReqString: scalar.String("one"),
1096 },
1097 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001098 },
1099 },
1100 wantErr: true,
1101 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001102 desc: "indirect required field in repeated with AllowPartial",
1103 umo: textpb.UnmarshalOptions{AllowPartial: true},
1104 inputMessage: &pb2.IndirectRequired{},
1105 inputText: `
1106rpt_nested: {
1107 req_string: "one"
1108}
1109rpt_nested: {}
1110`,
1111 wantMessage: &pb2.IndirectRequired{
1112 RptNested: []*pb2.NestedWithRequired{
1113 {
1114 ReqString: scalar.String("one"),
1115 },
1116 {},
1117 },
1118 },
1119 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001120 desc: "indirect required field in map",
1121 inputMessage: &pb2.IndirectRequired{},
1122 inputText: `
1123str_to_nested: {
1124 key: "missing"
1125}
1126str_to_nested: {
1127 key: "contains"
1128 value: {
1129 req_string: "here"
1130 }
1131}
1132`,
1133 wantMessage: &pb2.IndirectRequired{
1134 StrToNested: map[string]*pb2.NestedWithRequired{
1135 "missing": &pb2.NestedWithRequired{},
1136 "contains": &pb2.NestedWithRequired{
1137 ReqString: scalar.String("here"),
1138 },
1139 },
1140 },
1141 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001142 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001143 desc: "indirect required field in map with AllowPartial",
1144 umo: textpb.UnmarshalOptions{AllowPartial: true},
1145 inputMessage: &pb2.IndirectRequired{},
1146 inputText: `
1147str_to_nested: {
1148 key: "missing"
1149}
1150str_to_nested: {
1151 key: "contains"
1152 value: {
1153 req_string: "here"
1154 }
1155}
1156`,
1157 wantMessage: &pb2.IndirectRequired{
1158 StrToNested: map[string]*pb2.NestedWithRequired{
1159 "missing": &pb2.NestedWithRequired{},
1160 "contains": &pb2.NestedWithRequired{
1161 ReqString: scalar.String("here"),
1162 },
1163 },
1164 },
1165 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001166 desc: "indirect required field in oneof",
1167 inputMessage: &pb2.IndirectRequired{},
1168 inputText: `oneof_nested: {}
1169`,
1170 wantMessage: &pb2.IndirectRequired{
1171 Union: &pb2.IndirectRequired_OneofNested{
1172 OneofNested: &pb2.NestedWithRequired{},
1173 },
1174 },
1175 wantErr: true,
1176 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001177 desc: "indirect required field in oneof with AllowPartial",
1178 umo: textpb.UnmarshalOptions{AllowPartial: true},
1179 inputMessage: &pb2.IndirectRequired{},
1180 inputText: `oneof_nested: {}
1181`,
1182 wantMessage: &pb2.IndirectRequired{
1183 Union: &pb2.IndirectRequired_OneofNested{
1184 OneofNested: &pb2.NestedWithRequired{},
1185 },
1186 },
1187 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001188 desc: "ignore reserved field",
1189 inputMessage: &pb2.Nests{},
1190 inputText: "reserved_field: 'ignore this'",
1191 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001192 }, {
1193 desc: "extensions of non-repeated fields",
1194 inputMessage: &pb2.Extensions{},
1195 inputText: `opt_string: "non-extension field"
1196[pb2.opt_ext_bool]: true
1197opt_bool: true
1198[pb2.opt_ext_nested]: {
1199 opt_string: "nested in an extension"
1200 opt_nested: {
1201 opt_string: "another nested in an extension"
1202 }
1203}
1204[pb2.opt_ext_string]: "extension field"
1205opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001206[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001207`,
1208 wantMessage: func() proto.Message {
1209 m := &pb2.Extensions{
1210 OptString: scalar.String("non-extension field"),
1211 OptBool: scalar.Bool(true),
1212 OptInt32: scalar.Int32(42),
1213 }
1214 setExtension(m, pb2.E_OptExtBool, true)
1215 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001216 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001217 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1218 OptString: scalar.String("nested in an extension"),
1219 OptNested: &pb2.Nested{
1220 OptString: scalar.String("another nested in an extension"),
1221 },
1222 })
1223 return m
1224 }(),
1225 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001226 desc: "extension field contains invalid UTF-8",
1227 inputMessage: &pb2.Extensions{},
1228 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
1229 wantMessage: func() proto.Message {
1230 m := &pb2.Extensions{}
1231 setExtension(m, pb2.E_OptExtString, "abc\xff")
1232 return m
1233 }(),
1234 wantErr: true,
1235 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001236 desc: "extensions of repeated fields",
1237 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001238 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001239[pb2.rpt_ext_enum]: 101
1240[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001241[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001242[pb2.rpt_ext_nested]: {
1243 opt_string: "one"
1244}
1245[pb2.rpt_ext_nested]: {
1246 opt_string: "two"
1247}
1248[pb2.rpt_ext_fixed32]: 47
1249[pb2.rpt_ext_nested]: {
1250 opt_string: "three"
1251}
1252`,
1253 wantMessage: func() proto.Message {
1254 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001255 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001256 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1257 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1258 &pb2.Nested{OptString: scalar.String("one")},
1259 &pb2.Nested{OptString: scalar.String("two")},
1260 &pb2.Nested{OptString: scalar.String("three")},
1261 })
1262 return m
1263 }(),
1264 }, {
1265 desc: "extensions of non-repeated fields in another message",
1266 inputMessage: &pb2.Extensions{},
1267 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001268[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001269[pb2.ExtensionsContainer.opt_ext_nested]: {
1270 opt_string: "nested in an extension"
1271 opt_nested: {
1272 opt_string: "another nested in an extension"
1273 }
1274}
1275[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1276`,
1277 wantMessage: func() proto.Message {
1278 m := &pb2.Extensions{}
1279 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1280 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001281 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001282 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1283 OptString: scalar.String("nested in an extension"),
1284 OptNested: &pb2.Nested{
1285 OptString: scalar.String("another nested in an extension"),
1286 },
1287 })
1288 return m
1289 }(),
1290 }, {
1291 desc: "extensions of repeated fields in another message",
1292 inputMessage: &pb2.Extensions{},
1293 inputText: `opt_string: "non-extension field"
1294opt_bool: true
1295opt_int32: 42
1296[pb2.ExtensionsContainer.rpt_ext_nested]: {
1297 opt_string: "one"
1298}
Herbie Ong8170d692019-02-13 14:13:21 -08001299[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001300[pb2.ExtensionsContainer.rpt_ext_nested]: {
1301 opt_string: "two"
1302}
1303[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1304[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001305[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001306[pb2.ExtensionsContainer.rpt_ext_nested]: {
1307 opt_string: "three"
1308}
1309[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1310`,
1311 wantMessage: func() proto.Message {
1312 m := &pb2.Extensions{
1313 OptString: scalar.String("non-extension field"),
1314 OptBool: scalar.Bool(true),
1315 OptInt32: scalar.Int32(42),
1316 }
Herbie Ong8170d692019-02-13 14:13:21 -08001317 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001318 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1319 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1320 &pb2.Nested{OptString: scalar.String("one")},
1321 &pb2.Nested{OptString: scalar.String("two")},
1322 &pb2.Nested{OptString: scalar.String("three")},
1323 })
1324 return m
1325 }(),
1326 }, {
1327 desc: "invalid extension field name",
1328 inputMessage: &pb2.Extensions{},
1329 inputText: "[pb2.invalid_message_field]: true",
1330 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001331 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001332 desc: "MessageSet",
1333 inputMessage: &pb2.MessageSet{},
1334 inputText: `
1335[pb2.MessageSetExtension]: {
1336 opt_string: "a messageset extension"
1337}
1338[pb2.MessageSetExtension.ext_nested]: {
1339 opt_string: "just a regular extension"
1340}
1341[pb2.MessageSetExtension.not_message_set_extension]: {
1342 opt_string: "not a messageset extension"
1343}
1344`,
1345 wantMessage: func() proto.Message {
1346 m := &pb2.MessageSet{}
1347 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1348 OptString: scalar.String("a messageset extension"),
1349 })
1350 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1351 OptString: scalar.String("not a messageset extension"),
1352 })
1353 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1354 OptString: scalar.String("just a regular extension"),
1355 })
1356 return m
1357 }(),
1358 }, {
1359 desc: "not real MessageSet 1",
1360 inputMessage: &pb2.FakeMessageSet{},
1361 inputText: `
1362[pb2.FakeMessageSetExtension.message_set_extension]: {
1363 opt_string: "not a messageset extension"
1364}
1365`,
1366 wantMessage: func() proto.Message {
1367 m := &pb2.FakeMessageSet{}
1368 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1369 OptString: scalar.String("not a messageset extension"),
1370 })
1371 return m
1372 }(),
1373 }, {
1374 desc: "not real MessageSet 2",
1375 inputMessage: &pb2.FakeMessageSet{},
1376 inputText: `
1377[pb2.FakeMessageSetExtension]: {
1378 opt_string: "not a messageset extension"
1379}
1380`,
1381 wantErr: true,
1382 }, {
1383 desc: "not real MessageSet 3",
1384 inputMessage: &pb2.MessageSet{},
1385 inputText: `
1386[pb2.message_set_extension]: {
1387 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001388}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001389 wantMessage: func() proto.Message {
1390 m := &pb2.MessageSet{}
1391 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1392 OptString: scalar.String("another not a messageset extension"),
1393 })
1394 return m
1395 }(),
1396 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001397 desc: "Any not expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001398 inputMessage: &knownpb.Any{},
1399 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001400type_url: "pb2.Nested"
1401value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001402`,
Herbie Ong300cff02019-03-20 18:05:16 -07001403 wantMessage: &knownpb.Any{
1404 TypeUrl: "pb2.Nested",
1405 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001406 },
1407 }, {
1408 desc: "Any not expanded missing value",
Herbie Ong300cff02019-03-20 18:05:16 -07001409 inputMessage: &knownpb.Any{},
1410 inputText: `type_url: "pb2.Nested"`,
1411 wantMessage: &knownpb.Any{
1412 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001413 },
1414 }, {
1415 desc: "Any not expanded missing type_url",
Herbie Ong300cff02019-03-20 18:05:16 -07001416 inputMessage: &knownpb.Any{},
1417 inputText: `value: "some bytes"`,
1418 wantMessage: &knownpb.Any{
1419 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001420 },
1421 }, {
1422 desc: "Any expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001423 umo: textpb.UnmarshalOptions{
1424 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1425 },
1426 inputMessage: &knownpb.Any{},
1427 inputText: `
1428[foobar/pb2.Nested]: {
1429 opt_string: "embedded inside Any"
1430 opt_nested: {
1431 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001432 }
1433}
1434`,
1435 wantMessage: func() proto.Message {
1436 m := &pb2.Nested{
1437 OptString: scalar.String("embedded inside Any"),
1438 OptNested: &pb2.Nested{
1439 OptString: scalar.String("inception"),
1440 },
1441 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001442 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001443 if err != nil {
1444 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1445 }
Herbie Ong300cff02019-03-20 18:05:16 -07001446 return &knownpb.Any{
1447 TypeUrl: "foobar/pb2.Nested",
1448 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001449 }
1450 }(),
1451 }, {
1452 desc: "Any expanded with empty value",
Herbie Ong300cff02019-03-20 18:05:16 -07001453 umo: textpb.UnmarshalOptions{
1454 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1455 },
1456 inputMessage: &knownpb.Any{},
1457 inputText: `[foo.com/pb2.Nested]: {}`,
1458 wantMessage: &knownpb.Any{
1459 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001460 },
1461 }, {
1462 desc: "Any expanded with missing required error",
Herbie Ong300cff02019-03-20 18:05:16 -07001463 umo: textpb.UnmarshalOptions{
1464 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
1465 },
1466 inputMessage: &knownpb.Any{},
1467 inputText: `
1468[pb2.PartialRequired]: {
1469 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001470}
1471`,
1472 wantMessage: func() proto.Message {
1473 m := &pb2.PartialRequired{
1474 OptString: scalar.String("embedded inside Any"),
1475 }
Damien Neil96c229a2019-04-03 12:17:24 -07001476 b, err := proto.MarshalOptions{
1477 AllowPartial: true,
1478 Deterministic: true,
1479 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001480 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001481 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1482 }
Herbie Ong300cff02019-03-20 18:05:16 -07001483 return &knownpb.Any{
1484 TypeUrl: "pb2.PartialRequired",
1485 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001486 }
1487 }(),
1488 wantErr: true,
1489 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001490 desc: "Any with invalid UTF-8",
1491 umo: textpb.UnmarshalOptions{
1492 Resolver: preg.NewTypes((&pb3.Nested{}).ProtoReflect().Type()),
1493 },
1494 inputMessage: &knownpb.Any{},
1495 inputText: `
1496[pb3.Nested]: {
1497 s_string: "abc\xff"
1498}
1499`,
1500 wantMessage: func() proto.Message {
1501 m := &pb3.Nested{
1502 SString: "abc\xff",
1503 }
1504 var nerr errors.NonFatal
1505 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1506 if !nerr.Merge(err) {
1507 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1508 }
1509 return &knownpb.Any{
1510 TypeUrl: string(m.ProtoReflect().Type().FullName()),
1511 Value: b,
1512 }
1513 }(),
1514 wantErr: true,
1515 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001516 desc: "Any expanded with unregistered type",
1517 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
Herbie Ong300cff02019-03-20 18:05:16 -07001518 inputMessage: &knownpb.Any{},
1519 inputText: `[SomeMessage]: {}`,
1520 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001521 }, {
1522 desc: "Any expanded with invalid value",
Herbie Ong300cff02019-03-20 18:05:16 -07001523 umo: textpb.UnmarshalOptions{
1524 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1525 },
1526 inputMessage: &knownpb.Any{},
1527 inputText: `[pb2.Nested]: 123`,
1528 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001529 }, {
1530 desc: "Any expanded with unknown fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001531 umo: textpb.UnmarshalOptions{
1532 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1533 },
1534 inputMessage: &knownpb.Any{},
1535 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001536[pb2.Nested]: {}
1537unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001538`,
1539 wantErr: true,
1540 }, {
1541 desc: "Any contains expanded and unexpanded fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001542 umo: textpb.UnmarshalOptions{
1543 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1544 },
1545 inputMessage: &knownpb.Any{},
1546 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001547[pb2.Nested]: {}
1548type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001549`,
1550 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001551 }}
1552
1553 for _, tt := range tests {
1554 tt := tt
1555 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong66c365c2019-01-04 14:08:41 -08001556 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001557 if err != nil && !tt.wantErr {
1558 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1559 }
1560 if err == nil && tt.wantErr {
1561 t.Error("Unmarshal() got nil error, want error\n\n")
1562 }
Herbie Ong70651952018-12-13 14:19:50 -08001563 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001564 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1565 }
1566 })
1567 }
1568}