blob: 14b7c7c4d6a60f60ea6064db1b8ee6f8c014c4f1 [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"
Herbie Ongc525c972018-12-18 18:04:31 -080012 "github.com/golang/protobuf/protoapi"
Herbie Ong800c9902018-12-06 15:28:53 -080013 "github.com/golang/protobuf/v2/encoding/textpb"
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"
Herbie Ong800c9902018-12-06 15:28:53 -080018
Herbie Ong8170d692019-02-13 14:13:21 -080019 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
20 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Joe Tsai19058432019-02-27 21:46:29 -080021 knownpb "github.com/golang/protobuf/v2/types/known"
Herbie Ong800c9902018-12-06 15:28:53 -080022)
23
Herbie Ongc525c972018-12-18 18:04:31 -080024func init() {
Herbie Ong8170d692019-02-13 14:13:21 -080025 // TODO: remove these registerExtension calls when generated code registers
26 // to V2 global registry.
Herbie Ongc525c972018-12-18 18:04:31 -080027 registerExtension(pb2.E_OptExtBool)
28 registerExtension(pb2.E_OptExtString)
29 registerExtension(pb2.E_OptExtEnum)
30 registerExtension(pb2.E_OptExtNested)
31 registerExtension(pb2.E_RptExtFixed32)
32 registerExtension(pb2.E_RptExtEnum)
33 registerExtension(pb2.E_RptExtNested)
34 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
35 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
36 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
37 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
38 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
39 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
40 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
Herbie Ong6470ea62019-01-07 18:56:57 -080041 registerExtension(pb2.E_MessageSetExtension)
42 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
43 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
44 registerExtension(pb2.E_MessageSetExtension_ExtNested)
45 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
Herbie Ongc525c972018-12-18 18:04:31 -080046}
47
48func registerExtension(xd *protoapi.ExtensionDesc) {
49 xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
50 preg.GlobalTypes.Register(xt)
51}
52
Herbie Ong800c9902018-12-06 15:28:53 -080053func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080054 tests := []struct {
55 desc string
Herbie Ong66c365c2019-01-04 14:08:41 -080056 umo textpb.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080057 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080058 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080059 wantMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080060 wantErr bool
61 }{{
62 desc: "proto2 empty message",
63 inputMessage: &pb2.Scalars{},
64 wantMessage: &pb2.Scalars{},
65 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080066 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080067 inputMessage: &pb2.Scalars{},
68 inputText: `opt_bool: false
69opt_int32: 0
70opt_int64: 0
71opt_uint32: 0
72opt_uint64: 0
73opt_sint32: 0
74opt_sint64: 0
75opt_fixed32: 0
76opt_fixed64: 0
77opt_sfixed32: 0
78opt_sfixed64: 0
79opt_float: 0
80opt_double: 0
81opt_bytes: ""
82opt_string: ""
83`,
84 wantMessage: &pb2.Scalars{
85 OptBool: scalar.Bool(false),
86 OptInt32: scalar.Int32(0),
87 OptInt64: scalar.Int64(0),
88 OptUint32: scalar.Uint32(0),
89 OptUint64: scalar.Uint64(0),
90 OptSint32: scalar.Int32(0),
91 OptSint64: scalar.Int64(0),
92 OptFixed32: scalar.Uint32(0),
93 OptFixed64: scalar.Uint64(0),
94 OptSfixed32: scalar.Int32(0),
95 OptSfixed64: scalar.Int64(0),
96 OptFloat: scalar.Float32(0),
97 OptDouble: scalar.Float64(0),
98 OptBytes: []byte{},
99 OptString: scalar.String(""),
100 },
101 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800102 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800103 inputMessage: &pb3.Scalars{},
104 inputText: `s_bool: false
105s_int32: 0
106s_int64: 0
107s_uint32: 0
108s_uint64: 0
109s_sint32: 0
110s_sint64: 0
111s_fixed32: 0
112s_fixed64: 0
113s_sfixed32: 0
114s_sfixed64: 0
115s_float: 0
116s_double: 0
117s_bytes: ""
118s_string: ""
119`,
120 wantMessage: &pb3.Scalars{},
121 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800122 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800123 inputMessage: &pb2.Scalars{},
124 inputText: `opt_bool: true
125opt_int32: 255
126opt_int64: 3735928559
127opt_uint32: 0xff
128opt_uint64: 0xdeadbeef
129opt_sint32: -1001
130opt_sint64: -0xffff
131opt_fixed64: 64
132opt_sfixed32: -32
133opt_float: 1.234
134opt_double: 1.23e+100
135opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
136opt_string: "谷歌"
137`,
138 wantMessage: &pb2.Scalars{
139 OptBool: scalar.Bool(true),
140 OptInt32: scalar.Int32(0xff),
141 OptInt64: scalar.Int64(0xdeadbeef),
142 OptUint32: scalar.Uint32(0xff),
143 OptUint64: scalar.Uint64(0xdeadbeef),
144 OptSint32: scalar.Int32(-1001),
145 OptSint64: scalar.Int64(-0xffff),
146 OptFixed64: scalar.Uint64(64),
147 OptSfixed32: scalar.Int32(-32),
148 OptFloat: scalar.Float32(1.234),
149 OptDouble: scalar.Float64(1.23e100),
150 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
151 OptString: scalar.String("谷歌"),
152 },
153 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800154 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800155 inputMessage: &pb3.Scalars{},
156 inputText: `s_bool: true
157s_int32: 255
158s_int64: 3735928559
159s_uint32: 0xff
160s_uint64: 0xdeadbeef
161s_sint32: -1001
162s_sint64: -0xffff
163s_fixed64: 64
164s_sfixed32: -32
165s_float: 1.234
166s_double: 1.23e+100
167s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
168s_string: "谷歌"
169`,
170 wantMessage: &pb3.Scalars{
171 SBool: true,
172 SInt32: 0xff,
173 SInt64: 0xdeadbeef,
174 SUint32: 0xff,
175 SUint64: 0xdeadbeef,
176 SSint32: -1001,
177 SSint64: -0xffff,
178 SFixed64: 64,
179 SSfixed32: -32,
180 SFloat: 1.234,
181 SDouble: 1.23e100,
182 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
183 SString: "谷歌",
184 },
185 }, {
186 desc: "proto2 message contains unknown field",
187 inputMessage: &pb2.Scalars{},
188 inputText: "unknown_field: 123",
189 wantErr: true,
190 }, {
191 desc: "proto3 message contains unknown field",
192 inputMessage: &pb3.Scalars{},
193 inputText: "unknown_field: 456",
194 wantErr: true,
195 }, {
196 desc: "proto2 numeric key field",
197 inputMessage: &pb2.Scalars{},
198 inputText: "1: true",
199 wantErr: true,
200 }, {
201 desc: "proto3 numeric key field",
202 inputMessage: &pb3.Scalars{},
203 inputText: "1: true",
204 wantErr: true,
205 }, {
206 desc: "invalid bool value",
207 inputMessage: &pb3.Scalars{},
208 inputText: "s_bool: 123",
209 wantErr: true,
210 }, {
211 desc: "invalid int32 value",
212 inputMessage: &pb3.Scalars{},
213 inputText: "s_int32: not_a_num",
214 wantErr: true,
215 }, {
216 desc: "invalid int64 value",
217 inputMessage: &pb3.Scalars{},
218 inputText: "s_int64: 'not a num either'",
219 wantErr: true,
220 }, {
221 desc: "invalid uint32 value",
222 inputMessage: &pb3.Scalars{},
223 inputText: "s_fixed32: -42",
224 wantErr: true,
225 }, {
226 desc: "invalid uint64 value",
227 inputMessage: &pb3.Scalars{},
228 inputText: "s_uint64: -47",
229 wantErr: true,
230 }, {
231 desc: "invalid sint32 value",
232 inputMessage: &pb3.Scalars{},
233 inputText: "s_sint32: '42'",
234 wantErr: true,
235 }, {
236 desc: "invalid sint64 value",
237 inputMessage: &pb3.Scalars{},
238 inputText: "s_sint64: '-47'",
239 wantErr: true,
240 }, {
241 desc: "invalid fixed32 value",
242 inputMessage: &pb3.Scalars{},
243 inputText: "s_fixed32: -42",
244 wantErr: true,
245 }, {
246 desc: "invalid fixed64 value",
247 inputMessage: &pb3.Scalars{},
248 inputText: "s_fixed64: -42",
249 wantErr: true,
250 }, {
251 desc: "invalid sfixed32 value",
252 inputMessage: &pb3.Scalars{},
253 inputText: "s_sfixed32: 'not valid'",
254 wantErr: true,
255 }, {
256 desc: "invalid sfixed64 value",
257 inputMessage: &pb3.Scalars{},
258 inputText: "s_sfixed64: bad",
259 wantErr: true,
260 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800261 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800262 inputMessage: &pb3.Scalars{},
263 inputText: "s_float: inf",
264 wantMessage: &pb3.Scalars{
265 SFloat: float32(math.Inf(1)),
266 },
267 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800268 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800269 inputMessage: &pb3.Scalars{},
270 inputText: "s_float: -inf",
271 wantMessage: &pb3.Scalars{
272 SFloat: float32(math.Inf(-1)),
273 },
274 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800275 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800276 inputMessage: &pb3.Scalars{},
277 inputText: "s_double: inf",
278 wantMessage: &pb3.Scalars{
279 SDouble: math.Inf(1),
280 },
281 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800282 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800283 inputMessage: &pb3.Scalars{},
284 inputText: "s_double: -inf",
285 wantMessage: &pb3.Scalars{
286 SDouble: math.Inf(-1),
287 },
288 }, {
289 desc: "invalid string value",
290 inputMessage: &pb3.Scalars{},
291 inputText: "s_string: invalid_string",
292 wantErr: true,
293 }, {
294 desc: "proto2 bytes set to empty string",
295 inputMessage: &pb2.Scalars{},
296 inputText: "opt_bytes: ''",
297 wantMessage: &pb2.Scalars{
298 OptBytes: []byte(""),
299 },
300 }, {
301 desc: "proto3 bytes set to empty string",
302 inputMessage: &pb3.Scalars{},
303 inputText: "s_bytes: ''",
304 wantMessage: &pb3.Scalars{},
305 }, {
306 desc: "proto2 duplicate singular field",
307 inputMessage: &pb2.Scalars{},
308 inputText: `
309opt_bool: true
310opt_bool: false
311`,
312 wantErr: true,
313 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800314 desc: "proto2 more duplicate singular field",
315 inputMessage: &pb2.Scalars{},
316 inputText: `
317opt_bool: true
318opt_string: "hello"
319opt_bool: false
320`,
321 wantErr: true,
322 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800323 desc: "proto2 invalid singular field",
324 inputMessage: &pb2.Scalars{},
325 inputText: `
326opt_bool: [true, false]
327`,
328 wantErr: true,
329 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800330 desc: "proto3 duplicate singular field",
331 inputMessage: &pb3.Scalars{},
332 inputText: `
333s_bool: false
334s_bool: true
335`,
336 wantErr: true,
337 }, {
338 desc: "proto3 more duplicate singular field",
339 inputMessage: &pb3.Scalars{},
340 inputText: `
341s_bool: false
342s_string: ""
343s_bool: true
344`,
345 wantErr: true,
346 }, {
347 desc: "proto2 enum",
348 inputMessage: &pb2.Enums{},
349 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800350opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800351opt_nested_enum: UNO
352`,
353 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800354 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800355 OptNestedEnum: pb2.Enums_UNO.Enum(),
356 },
357 }, {
358 desc: "proto2 enum set to numeric values",
359 inputMessage: &pb2.Enums{},
360 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800361opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800362opt_nested_enum: 2
363`,
364 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800365 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800366 OptNestedEnum: pb2.Enums_DOS.Enum(),
367 },
368 }, {
369 desc: "proto2 enum set to unnamed numeric values",
370 inputMessage: &pb2.Enums{},
371 inputText: `
372opt_enum: 101
373opt_nested_enum: -101
374`,
375 wantMessage: &pb2.Enums{
376 OptEnum: pb2Enum(101),
377 OptNestedEnum: pb2Enums_NestedEnum(-101),
378 },
379 }, {
380 desc: "proto2 enum set to invalid named",
381 inputMessage: &pb2.Enums{},
382 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800383opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800384opt_nested_enum: UNNAMED_TOO
385`,
386 wantErr: true,
387 }, {
388 desc: "proto3 enum name value",
389 inputMessage: &pb3.Enums{},
390 inputText: `
391s_enum: ONE
392s_nested_enum: DIEZ
393`,
394 wantMessage: &pb3.Enums{
395 SEnum: pb3.Enum_ONE,
396 SNestedEnum: pb3.Enums_DIEZ,
397 },
398 }, {
399 desc: "proto3 enum numeric value",
400 inputMessage: &pb3.Enums{},
401 inputText: `
402s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800403s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800404`,
405 wantMessage: &pb3.Enums{
406 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800407 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800408 },
409 }, {
410 desc: "proto3 enum unnamed numeric value",
411 inputMessage: &pb3.Enums{},
412 inputText: `
413s_enum: 0x7fffffff
414s_nested_enum: -0x80000000
415`,
416 wantMessage: &pb3.Enums{
417 SEnum: 0x7fffffff,
418 SNestedEnum: -0x80000000,
419 },
420 }, {
421 desc: "proto2 nested empty messages",
422 inputMessage: &pb2.Nests{},
423 inputText: `
424opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800425OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800426`,
427 wantMessage: &pb2.Nests{
428 OptNested: &pb2.Nested{},
429 Optgroup: &pb2.Nests_OptGroup{},
430 },
431 }, {
432 desc: "proto2 nested messages",
433 inputMessage: &pb2.Nests{},
434 inputText: `
435opt_nested: {
436 opt_string: "nested message"
437 opt_nested: {
438 opt_string: "another nested message"
439 }
440}
441`,
442 wantMessage: &pb2.Nests{
443 OptNested: &pb2.Nested{
444 OptString: scalar.String("nested message"),
445 OptNested: &pb2.Nested{
446 OptString: scalar.String("another nested message"),
447 },
448 },
449 },
450 }, {
451 desc: "proto3 nested empty message",
452 inputMessage: &pb3.Nests{},
453 inputText: "s_nested: {}",
454 wantMessage: &pb3.Nests{
455 SNested: &pb3.Nested{},
456 },
457 }, {
458 desc: "proto3 nested message",
459 inputMessage: &pb3.Nests{},
460 inputText: `
461s_nested: {
462 s_string: "nested message"
463 s_nested: {
464 s_string: "another nested message"
465 }
466}
467`,
468 wantMessage: &pb3.Nests{
469 SNested: &pb3.Nested{
470 SString: "nested message",
471 SNested: &pb3.Nested{
472 SString: "another nested message",
473 },
474 },
475 },
476 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800477 desc: "oneof set to empty string",
478 inputMessage: &pb3.Oneofs{},
479 inputText: "oneof_string: ''",
480 wantMessage: &pb3.Oneofs{
481 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800482 },
483 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800484 desc: "oneof set to string",
485 inputMessage: &pb3.Oneofs{},
486 inputText: "oneof_string: 'hello'",
487 wantMessage: &pb3.Oneofs{
488 Union: &pb3.Oneofs_OneofString{
489 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800490 },
491 },
492 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800493 desc: "oneof set to enum",
494 inputMessage: &pb3.Oneofs{},
495 inputText: "oneof_enum: TEN",
496 wantMessage: &pb3.Oneofs{
497 Union: &pb3.Oneofs_OneofEnum{
498 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800499 },
500 },
501 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800502 desc: "oneof set to empty message",
503 inputMessage: &pb3.Oneofs{},
504 inputText: "oneof_nested: {}",
505 wantMessage: &pb3.Oneofs{
506 Union: &pb3.Oneofs_OneofNested{
507 OneofNested: &pb3.Nested{},
508 },
509 },
510 }, {
511 desc: "oneof set to message",
512 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800513 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800514oneof_nested: {
515 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800516}
517`,
Herbie Ong8170d692019-02-13 14:13:21 -0800518 wantMessage: &pb3.Oneofs{
519 Union: &pb3.Oneofs_OneofNested{
520 OneofNested: &pb3.Nested{
521 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800522 },
523 },
524 },
525 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800526 desc: "oneof set to last value",
527 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800528 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800529oneof_nested: {
530 s_string: "nested message"
Herbie Ong6470ea62019-01-07 18:56:57 -0800531}
Herbie Ong8170d692019-02-13 14:13:21 -0800532oneof_enum: TEN
533oneof_string: "wins"
Herbie Ong6470ea62019-01-07 18:56:57 -0800534`,
Herbie Ong8170d692019-02-13 14:13:21 -0800535 wantMessage: &pb3.Oneofs{
536 Union: &pb3.Oneofs_OneofString{
537 OneofString: "wins",
Herbie Ong6470ea62019-01-07 18:56:57 -0800538 },
539 },
540 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800541 desc: "repeated scalar using same field name",
542 inputMessage: &pb2.Repeats{},
543 inputText: `
544rpt_string: "a"
545rpt_string: "b"
546rpt_int32: 0xff
547rpt_float: 1.23
548rpt_bytes: "bytes"
549`,
550 wantMessage: &pb2.Repeats{
551 RptString: []string{"a", "b"},
552 RptInt32: []int32{0xff},
553 RptFloat: []float32{1.23},
554 RptBytes: [][]byte{[]byte("bytes")},
555 },
556 }, {
557 desc: "repeated using mix of [] and repeated field name",
558 inputMessage: &pb2.Repeats{},
559 inputText: `
560rpt_string: "a"
561rpt_bool: true
562rpt_string: ["x", "y"]
563rpt_bool: [ false, true ]
564rpt_string: "b"
565`,
566 wantMessage: &pb2.Repeats{
567 RptString: []string{"a", "x", "y", "b"},
568 RptBool: []bool{true, false, true},
569 },
570 }, {
571 desc: "repeated enums",
572 inputMessage: &pb2.Enums{},
573 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800574rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800575rpt_enum: 1
576rpt_nested_enum: [DOS, 2]
577rpt_enum: 42
578rpt_nested_enum: -47
579`,
580 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800581 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800582 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
583 },
584 }, {
585 desc: "repeated nested messages",
586 inputMessage: &pb2.Nests{},
587 inputText: `
588rpt_nested: {
589 opt_string: "repeat nested one"
590}
591rpt_nested: {
592 opt_string: "repeat nested two"
593 opt_nested: {
594 opt_string: "inside repeat nested two"
595 }
596}
597rpt_nested: {}
598`,
599 wantMessage: &pb2.Nests{
600 RptNested: []*pb2.Nested{
601 {
602 OptString: scalar.String("repeat nested one"),
603 },
604 {
605 OptString: scalar.String("repeat nested two"),
606 OptNested: &pb2.Nested{
607 OptString: scalar.String("inside repeat nested two"),
608 },
609 },
610 {},
611 },
612 },
613 }, {
614 desc: "repeated group fields",
615 inputMessage: &pb2.Nests{},
616 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800617RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800618 rpt_string: "hello"
619 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800620}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800621RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800622`,
623 wantMessage: &pb2.Nests{
624 Rptgroup: []*pb2.Nests_RptGroup{
625 {
Herbie Ong8170d692019-02-13 14:13:21 -0800626 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800627 },
628 {},
629 },
630 },
631 }, {
632 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800633 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800634 inputText: `
635int32_to_str: {
636 key: -101
637 value: "-101"
638}
639int32_to_str: {
640 key: 0
641 value: "zero"
642}
Herbie Ong8170d692019-02-13 14:13:21 -0800643bool_to_uint32: {
644 key: false
645 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800646}
647int32_to_str: {
648 key: 255
649 value: "0xff"
650}
651bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800652 key: true
653 value: 42
654}
655`,
Herbie Ong8170d692019-02-13 14:13:21 -0800656 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800657 Int32ToStr: map[int32]string{
658 -101: "-101",
659 0xff: "0xff",
660 0: "zero",
661 },
Herbie Ong800c9902018-12-06 15:28:53 -0800662 BoolToUint32: map[bool]uint32{
663 true: 42,
664 false: 101,
665 },
666 },
667 }, {
668 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800669 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800670 inputText: `
671uint64_to_enum: {
672 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800673 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800674}
675uint64_to_enum: {
676 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800677 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800678}
679uint64_to_enum: {
680 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800681 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800682}
683`,
Herbie Ong8170d692019-02-13 14:13:21 -0800684 wantMessage: &pb3.Maps{
685 Uint64ToEnum: map[uint64]pb3.Enum{
686 1: pb3.Enum_ONE,
687 2: pb3.Enum_TWO,
688 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800689 },
690 },
691 }, {
692 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800693 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800694 inputText: `
695str_to_nested: {
696 key: "nested_one"
697 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800698 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800699 }
700}
701`,
Herbie Ong8170d692019-02-13 14:13:21 -0800702 wantMessage: &pb3.Maps{
703 StrToNested: map[string]*pb3.Nested{
704 "nested_one": &pb3.Nested{
705 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800706 },
707 },
708 },
709 }, {
710 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800711 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800712 inputText: `
713str_to_oneofs: {
714 key: "nested"
715 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800716 oneof_nested: {
717 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800718 }
719 }
720}
721str_to_oneofs: {
722 key: "string"
723 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800724 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800725 }
726}
727`,
Herbie Ong8170d692019-02-13 14:13:21 -0800728 wantMessage: &pb3.Maps{
729 StrToOneofs: map[string]*pb3.Oneofs{
730 "string": &pb3.Oneofs{
731 Union: &pb3.Oneofs_OneofString{
732 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800733 },
734 },
Herbie Ong8170d692019-02-13 14:13:21 -0800735 "nested": &pb3.Oneofs{
736 Union: &pb3.Oneofs_OneofNested{
737 OneofNested: &pb3.Nested{
738 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800739 },
740 },
741 },
742 },
743 },
744 }, {
745 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800746 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800747 inputText: `
748int32_to_str: {
749 key: 0
750 value: "cero"
751}
752int32_to_str: {
753 key: 0
754 value: "zero"
755}
756`,
Herbie Ong8170d692019-02-13 14:13:21 -0800757 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800758 Int32ToStr: map[int32]string{
759 0: "zero",
760 },
761 },
762 }, {
763 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800764 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800765 inputText: `
766int32_to_str: {
767 key: 0
768 key: 1
769 value: "cero"
770}
771`,
772 wantErr: true,
773 }, {
774 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800775 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800776 inputText: `
777int32_to_str: {
778 key: 1
779 value: "cero"
780 value: "uno"
781}
782`,
783 wantErr: true,
784 }, {
785 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800786 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800787 inputText: `
788int32_to_str: {
789 value: "zero"
790}
Herbie Ong8170d692019-02-13 14:13:21 -0800791bool_to_uint32: {
792 value: 47
793}
794str_to_nested: {
795 value: {}
796}
Herbie Ong800c9902018-12-06 15:28:53 -0800797`,
Herbie Ong8170d692019-02-13 14:13:21 -0800798 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800799 Int32ToStr: map[int32]string{
800 0: "zero",
801 },
Herbie Ong8170d692019-02-13 14:13:21 -0800802 BoolToUint32: map[bool]uint32{
803 false: 47,
804 },
805 StrToNested: map[string]*pb3.Nested{
806 "": {},
807 },
Herbie Ong800c9902018-12-06 15:28:53 -0800808 },
809 }, {
810 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800811 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800812 inputText: `
813int32_to_str: {
814 key: 100
815}
Herbie Ong8170d692019-02-13 14:13:21 -0800816bool_to_uint32: {
817 key: true
818}
819uint64_to_enum: {
820 key: 101
821}
822str_to_nested: {
823 key: "hello"
824}
Herbie Ong800c9902018-12-06 15:28:53 -0800825`,
Herbie Ong8170d692019-02-13 14:13:21 -0800826 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800827 Int32ToStr: map[int32]string{
828 100: "",
829 },
Herbie Ong8170d692019-02-13 14:13:21 -0800830 BoolToUint32: map[bool]uint32{
831 true: 0,
832 },
833 Uint64ToEnum: map[uint64]pb3.Enum{
834 101: pb3.Enum_ZERO,
835 },
836 StrToNested: map[string]*pb3.Nested{
837 "hello": {},
838 },
Herbie Ong800c9902018-12-06 15:28:53 -0800839 },
840 }, {
841 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800842 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800843 inputText: `
844int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800845bool_to_uint32: {}
846uint64_to_enum: {}
847str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800848`,
Herbie Ong8170d692019-02-13 14:13:21 -0800849 wantMessage: &pb3.Maps{
850 Int32ToStr: map[int32]string{
851 0: "",
852 },
853 BoolToUint32: map[bool]uint32{
854 false: 0,
855 },
856 Uint64ToEnum: map[uint64]pb3.Enum{
857 0: pb3.Enum_ZERO,
858 },
859 StrToNested: map[string]*pb3.Nested{
860 "": {},
861 },
862 },
863 }, {
864 desc: "map contains overriding entries",
865 inputMessage: &pb3.Maps{},
866 inputText: `
867int32_to_str: {
868 key: 0
869}
870int32_to_str: {
871 value: "empty"
872}
873int32_to_str: {}
874`,
875 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800876 Int32ToStr: map[int32]string{
877 0: "",
878 },
879 },
880 }, {
881 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800882 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800883 inputText: `
884int32_to_str: {
885 key: 0
886 value: "cero"
887 unknown: "bad"
888}
889`,
890 wantErr: true,
891 }, {
892 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800893 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800894 inputText: `
895int32_to_str: {
896 [key]: 10
897 value: "ten"
898}
899`,
900 wantErr: true,
901 }, {
902 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800903 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800904 inputText: `
905int32_to_str: {
906 key: "invalid"
907 value: "cero"
908}
909`,
910 wantErr: true,
911 }, {
912 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800913 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800914 inputText: `
915int32_to_str: {
916 key: 100
917 value: 101
918}
919`,
920 wantErr: true,
921 }, {
922 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800923 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800924 inputText: `
925int32_to_str: {
926 key: 1
927 value: "one"
928}
929int32_to_str: [
930 {
931 key: 2
932 value: "not this"
933 },
934 {
935 },
936 {
937 key: 3
938 value: "three"
939 }
940]
941int32_to_str: {
942 key: 2
943 value: "two"
944}
945`,
Herbie Ong8170d692019-02-13 14:13:21 -0800946 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800947 Int32ToStr: map[int32]string{
948 0: "",
949 1: "one",
950 2: "two",
951 3: "three",
952 },
953 },
954 }, {
955 desc: "proto2 required fields not set",
956 inputMessage: &pb2.Requireds{},
957 wantErr: true,
958 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800959 desc: "proto2 required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800960 inputMessage: &pb2.PartialRequired{},
961 inputText: "req_string: 'this is required'",
962 wantMessage: &pb2.PartialRequired{
963 ReqString: scalar.String("this is required"),
964 },
965 }, {
966 desc: "proto2 required fields partially set",
967 inputMessage: &pb2.Requireds{},
968 inputText: `
969req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800970req_sfixed64: 3203386110
971req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800972req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800973`,
974 wantMessage: &pb2.Requireds{
975 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800976 ReqSfixed64: scalar.Int64(0xbeefcafe),
977 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800978 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800979 },
980 wantErr: true,
981 }, {
982 desc: "proto2 required fields all set",
983 inputMessage: &pb2.Requireds{},
984 inputText: `
985req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800986req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800987req_double: 0
988req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800989req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800990req_nested: {}
991`,
992 wantMessage: &pb2.Requireds{
993 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800994 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -0800995 ReqDouble: scalar.Float64(0),
996 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800997 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800998 ReqNested: &pb2.Nested{},
999 },
1000 }, {
1001 desc: "indirect required field",
1002 inputMessage: &pb2.IndirectRequired{},
1003 inputText: "opt_nested: {}",
1004 wantMessage: &pb2.IndirectRequired{
1005 OptNested: &pb2.NestedWithRequired{},
1006 },
1007 wantErr: true,
1008 }, {
1009 desc: "indirect required field in repeated",
1010 inputMessage: &pb2.IndirectRequired{},
1011 inputText: `
1012rpt_nested: {
1013 req_string: "one"
1014}
1015rpt_nested: {}
1016rpt_nested: {
1017 req_string: "three"
1018}
1019`,
1020 wantMessage: &pb2.IndirectRequired{
1021 RptNested: []*pb2.NestedWithRequired{
1022 {
1023 ReqString: scalar.String("one"),
1024 },
1025 {},
1026 {
1027 ReqString: scalar.String("three"),
1028 },
1029 },
1030 },
1031 wantErr: true,
1032 }, {
1033 desc: "indirect required field in map",
1034 inputMessage: &pb2.IndirectRequired{},
1035 inputText: `
1036str_to_nested: {
1037 key: "missing"
1038}
1039str_to_nested: {
1040 key: "contains"
1041 value: {
1042 req_string: "here"
1043 }
1044}
1045`,
1046 wantMessage: &pb2.IndirectRequired{
1047 StrToNested: map[string]*pb2.NestedWithRequired{
1048 "missing": &pb2.NestedWithRequired{},
1049 "contains": &pb2.NestedWithRequired{
1050 ReqString: scalar.String("here"),
1051 },
1052 },
1053 },
1054 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001055 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001056 desc: "indirect required field in oneof",
1057 inputMessage: &pb2.IndirectRequired{},
1058 inputText: `oneof_nested: {}
1059`,
1060 wantMessage: &pb2.IndirectRequired{
1061 Union: &pb2.IndirectRequired_OneofNested{
1062 OneofNested: &pb2.NestedWithRequired{},
1063 },
1064 },
1065 wantErr: true,
1066 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001067 desc: "ignore reserved field",
1068 inputMessage: &pb2.Nests{},
1069 inputText: "reserved_field: 'ignore this'",
1070 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001071 }, {
1072 desc: "extensions of non-repeated fields",
1073 inputMessage: &pb2.Extensions{},
1074 inputText: `opt_string: "non-extension field"
1075[pb2.opt_ext_bool]: true
1076opt_bool: true
1077[pb2.opt_ext_nested]: {
1078 opt_string: "nested in an extension"
1079 opt_nested: {
1080 opt_string: "another nested in an extension"
1081 }
1082}
1083[pb2.opt_ext_string]: "extension field"
1084opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001085[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001086`,
1087 wantMessage: func() proto.Message {
1088 m := &pb2.Extensions{
1089 OptString: scalar.String("non-extension field"),
1090 OptBool: scalar.Bool(true),
1091 OptInt32: scalar.Int32(42),
1092 }
1093 setExtension(m, pb2.E_OptExtBool, true)
1094 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001095 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001096 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1097 OptString: scalar.String("nested in an extension"),
1098 OptNested: &pb2.Nested{
1099 OptString: scalar.String("another nested in an extension"),
1100 },
1101 })
1102 return m
1103 }(),
1104 }, {
1105 desc: "extensions of repeated fields",
1106 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001107 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001108[pb2.rpt_ext_enum]: 101
1109[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001110[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001111[pb2.rpt_ext_nested]: {
1112 opt_string: "one"
1113}
1114[pb2.rpt_ext_nested]: {
1115 opt_string: "two"
1116}
1117[pb2.rpt_ext_fixed32]: 47
1118[pb2.rpt_ext_nested]: {
1119 opt_string: "three"
1120}
1121`,
1122 wantMessage: func() proto.Message {
1123 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001124 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001125 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1126 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1127 &pb2.Nested{OptString: scalar.String("one")},
1128 &pb2.Nested{OptString: scalar.String("two")},
1129 &pb2.Nested{OptString: scalar.String("three")},
1130 })
1131 return m
1132 }(),
1133 }, {
1134 desc: "extensions of non-repeated fields in another message",
1135 inputMessage: &pb2.Extensions{},
1136 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001137[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001138[pb2.ExtensionsContainer.opt_ext_nested]: {
1139 opt_string: "nested in an extension"
1140 opt_nested: {
1141 opt_string: "another nested in an extension"
1142 }
1143}
1144[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1145`,
1146 wantMessage: func() proto.Message {
1147 m := &pb2.Extensions{}
1148 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1149 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001150 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001151 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1152 OptString: scalar.String("nested in an extension"),
1153 OptNested: &pb2.Nested{
1154 OptString: scalar.String("another nested in an extension"),
1155 },
1156 })
1157 return m
1158 }(),
1159 }, {
1160 desc: "extensions of repeated fields in another message",
1161 inputMessage: &pb2.Extensions{},
1162 inputText: `opt_string: "non-extension field"
1163opt_bool: true
1164opt_int32: 42
1165[pb2.ExtensionsContainer.rpt_ext_nested]: {
1166 opt_string: "one"
1167}
Herbie Ong8170d692019-02-13 14:13:21 -08001168[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001169[pb2.ExtensionsContainer.rpt_ext_nested]: {
1170 opt_string: "two"
1171}
1172[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1173[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001174[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001175[pb2.ExtensionsContainer.rpt_ext_nested]: {
1176 opt_string: "three"
1177}
1178[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1179`,
1180 wantMessage: func() proto.Message {
1181 m := &pb2.Extensions{
1182 OptString: scalar.String("non-extension field"),
1183 OptBool: scalar.Bool(true),
1184 OptInt32: scalar.Int32(42),
1185 }
Herbie Ong8170d692019-02-13 14:13:21 -08001186 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001187 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1188 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1189 &pb2.Nested{OptString: scalar.String("one")},
1190 &pb2.Nested{OptString: scalar.String("two")},
1191 &pb2.Nested{OptString: scalar.String("three")},
1192 })
1193 return m
1194 }(),
1195 }, {
1196 desc: "invalid extension field name",
1197 inputMessage: &pb2.Extensions{},
1198 inputText: "[pb2.invalid_message_field]: true",
1199 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001200 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001201 desc: "MessageSet",
1202 inputMessage: &pb2.MessageSet{},
1203 inputText: `
1204[pb2.MessageSetExtension]: {
1205 opt_string: "a messageset extension"
1206}
1207[pb2.MessageSetExtension.ext_nested]: {
1208 opt_string: "just a regular extension"
1209}
1210[pb2.MessageSetExtension.not_message_set_extension]: {
1211 opt_string: "not a messageset extension"
1212}
1213`,
1214 wantMessage: func() proto.Message {
1215 m := &pb2.MessageSet{}
1216 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1217 OptString: scalar.String("a messageset extension"),
1218 })
1219 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1220 OptString: scalar.String("not a messageset extension"),
1221 })
1222 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1223 OptString: scalar.String("just a regular extension"),
1224 })
1225 return m
1226 }(),
1227 }, {
1228 desc: "not real MessageSet 1",
1229 inputMessage: &pb2.FakeMessageSet{},
1230 inputText: `
1231[pb2.FakeMessageSetExtension.message_set_extension]: {
1232 opt_string: "not a messageset extension"
1233}
1234`,
1235 wantMessage: func() proto.Message {
1236 m := &pb2.FakeMessageSet{}
1237 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1238 OptString: scalar.String("not a messageset extension"),
1239 })
1240 return m
1241 }(),
1242 }, {
1243 desc: "not real MessageSet 2",
1244 inputMessage: &pb2.FakeMessageSet{},
1245 inputText: `
1246[pb2.FakeMessageSetExtension]: {
1247 opt_string: "not a messageset extension"
1248}
1249`,
1250 wantErr: true,
1251 }, {
1252 desc: "not real MessageSet 3",
1253 inputMessage: &pb2.MessageSet{},
1254 inputText: `
1255[pb2.message_set_extension]: {
1256 opt_string: "another not a messageset extension"
1257}
1258`,
1259 wantMessage: func() proto.Message {
1260 m := &pb2.MessageSet{}
1261 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1262 OptString: scalar.String("another not a messageset extension"),
1263 })
1264 return m
1265 }(),
1266 }, {
Joe Tsai19058432019-02-27 21:46:29 -08001267 // TODO: Change these tests to directly use knownpb.Any type instead once
Herbie Ong8170d692019-02-13 14:13:21 -08001268 // type has been regenerated with V2 compiler.
Herbie Ong66c365c2019-01-04 14:08:41 -08001269 desc: "Any not expanded",
1270 inputMessage: &pb2.KnownTypes{},
1271 inputText: `opt_any: {
1272type_url: "pb2.Nested"
1273value: "some bytes"
1274}
1275`,
1276 wantMessage: &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001277 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001278 TypeUrl: "pb2.Nested",
1279 Value: []byte("some bytes"),
1280 },
1281 },
1282 }, {
1283 desc: "Any not expanded missing value",
1284 inputMessage: &pb2.KnownTypes{},
1285 inputText: `opt_any: {
1286type_url: "pb2.Nested"
1287}
1288`,
1289 wantMessage: &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001290 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001291 TypeUrl: "pb2.Nested",
1292 },
1293 },
1294 }, {
1295 desc: "Any not expanded missing type_url",
1296 inputMessage: &pb2.KnownTypes{},
1297 inputText: `opt_any: {
1298value: "some bytes"
1299}
1300`,
1301 wantMessage: &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001302 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001303 Value: []byte("some bytes"),
1304 },
1305 },
1306 }, {
1307 desc: "Any expanded",
1308 umo: func() textpb.UnmarshalOptions {
1309 m := &pb2.Nested{}
1310 resolver := preg.NewTypes(m.ProtoReflect().Type())
1311 return textpb.UnmarshalOptions{Resolver: resolver}
1312 }(),
1313 inputMessage: &pb2.KnownTypes{},
1314 inputText: `opt_any: {
1315 [foobar/pb2.Nested]: {
1316 opt_string: "embedded inside Any"
1317 opt_nested: {
1318 opt_string: "inception"
1319 }
1320 }
1321}
1322`,
1323 wantMessage: func() proto.Message {
1324 m := &pb2.Nested{
1325 OptString: scalar.String("embedded inside Any"),
1326 OptNested: &pb2.Nested{
1327 OptString: scalar.String("inception"),
1328 },
1329 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001330 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001331 if err != nil {
1332 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1333 }
1334 return &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001335 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001336 TypeUrl: "foobar/pb2.Nested",
1337 Value: b,
1338 },
1339 }
1340 }(),
1341 }, {
1342 desc: "Any expanded with empty value",
1343 umo: func() textpb.UnmarshalOptions {
1344 m := &pb2.Nested{}
1345 resolver := preg.NewTypes(m.ProtoReflect().Type())
1346 return textpb.UnmarshalOptions{Resolver: resolver}
1347 }(),
1348 inputMessage: &pb2.KnownTypes{},
1349 inputText: `opt_any: {
1350[foo.com/pb2.Nested]: {}
1351}
1352`,
1353 wantMessage: &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001354 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001355 TypeUrl: "foo.com/pb2.Nested",
1356 },
1357 },
1358 }, {
1359 desc: "Any expanded with missing required error",
1360 umo: func() textpb.UnmarshalOptions {
1361 m := &pb2.PartialRequired{}
1362 resolver := preg.NewTypes(m.ProtoReflect().Type())
1363 return textpb.UnmarshalOptions{Resolver: resolver}
1364 }(),
1365 inputMessage: &pb2.KnownTypes{},
1366 inputText: `opt_any: {
1367 [pb2.PartialRequired]: {
1368 opt_string: "embedded inside Any"
1369 }
1370}
1371`,
1372 wantMessage: func() proto.Message {
1373 m := &pb2.PartialRequired{
1374 OptString: scalar.String("embedded inside Any"),
1375 }
1376 // TODO: Switch to V2 marshal when ready.
1377 b, err := protoV1.Marshal(m)
1378 // Ignore required not set error.
1379 if _, ok := err.(*protoV1.RequiredNotSetError); !ok {
1380 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1381 }
1382 return &pb2.KnownTypes{
Joe Tsai19058432019-02-27 21:46:29 -08001383 OptAny: &knownpb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001384 TypeUrl: "pb2.PartialRequired",
1385 Value: b,
1386 },
1387 }
1388 }(),
1389 wantErr: true,
1390 }, {
1391 desc: "Any expanded with unregistered type",
1392 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
1393 inputMessage: &pb2.KnownTypes{},
1394 inputText: `opt_any: {
1395[SomeMessage]: {}
1396}
1397`,
1398 wantErr: true,
1399 }, {
1400 desc: "Any expanded with invalid value",
1401 umo: func() textpb.UnmarshalOptions {
1402 m := &pb2.Nested{}
1403 resolver := preg.NewTypes(m.ProtoReflect().Type())
1404 return textpb.UnmarshalOptions{Resolver: resolver}
1405 }(),
1406 inputMessage: &pb2.KnownTypes{},
1407 inputText: `opt_any: {
1408[pb2.Nested]: 123
1409}
1410`,
1411 wantErr: true,
1412 }, {
1413 desc: "Any expanded with unknown fields",
1414 umo: func() textpb.UnmarshalOptions {
1415 m := &pb2.Nested{}
1416 resolver := preg.NewTypes(m.ProtoReflect().Type())
1417 return textpb.UnmarshalOptions{Resolver: resolver}
1418 }(),
1419 inputMessage: &pb2.KnownTypes{},
1420 inputText: `opt_any: {
1421[pb2.Nested]: {}
1422unknown: ""
1423}
1424`,
1425 wantErr: true,
1426 }, {
1427 desc: "Any contains expanded and unexpanded fields",
1428 umo: func() textpb.UnmarshalOptions {
1429 m := &pb2.Nested{}
1430 resolver := preg.NewTypes(m.ProtoReflect().Type())
1431 return textpb.UnmarshalOptions{Resolver: resolver}
1432 }(),
1433 inputMessage: &pb2.KnownTypes{},
1434 inputText: `opt_any: {
1435[pb2.Nested]: {}
1436type_url: "pb2.Nested"
1437}
1438`,
1439 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001440 }}
1441
1442 for _, tt := range tests {
1443 tt := tt
1444 t.Run(tt.desc, func(t *testing.T) {
1445 t.Parallel()
Herbie Ong66c365c2019-01-04 14:08:41 -08001446 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001447 if err != nil && !tt.wantErr {
1448 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1449 }
1450 if err == nil && tt.wantErr {
1451 t.Error("Unmarshal() got nil error, want error\n\n")
1452 }
Herbie Ong70651952018-12-13 14:19:50 -08001453 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001454 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1455 }
1456 })
1457 }
1458}