blob: 56c09b2913a219fefef9fb0aac4e15b45f14cfff [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 Ong66c365c2019-01-04 14:08:41 -080013 anypb "github.com/golang/protobuf/ptypes/any"
Herbie Ong800c9902018-12-06 15:28:53 -080014 "github.com/golang/protobuf/v2/encoding/textpb"
Herbie Ongc525c972018-12-18 18:04:31 -080015 "github.com/golang/protobuf/v2/internal/legacy"
Herbie Ong800c9902018-12-06 15:28:53 -080016 "github.com/golang/protobuf/v2/internal/scalar"
Herbie Ong70651952018-12-13 14:19:50 -080017 "github.com/golang/protobuf/v2/proto"
Herbie Ongc525c972018-12-18 18:04:31 -080018 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080019
20 // The legacy package must be imported prior to use of any legacy messages.
21 // TODO: Remove this when protoV1 registers these hooks for you.
22 _ "github.com/golang/protobuf/v2/internal/legacy"
23
Herbie Ong8170d692019-02-13 14:13:21 -080024 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
25 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Herbie Ong800c9902018-12-06 15:28:53 -080026)
27
Herbie Ongc525c972018-12-18 18:04:31 -080028func init() {
Herbie Ong8170d692019-02-13 14:13:21 -080029 // TODO: remove these registerExtension calls when generated code registers
30 // to V2 global registry.
Herbie Ongc525c972018-12-18 18:04:31 -080031 registerExtension(pb2.E_OptExtBool)
32 registerExtension(pb2.E_OptExtString)
33 registerExtension(pb2.E_OptExtEnum)
34 registerExtension(pb2.E_OptExtNested)
35 registerExtension(pb2.E_RptExtFixed32)
36 registerExtension(pb2.E_RptExtEnum)
37 registerExtension(pb2.E_RptExtNested)
38 registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
39 registerExtension(pb2.E_ExtensionsContainer_OptExtString)
40 registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
41 registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
42 registerExtension(pb2.E_ExtensionsContainer_RptExtString)
43 registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
44 registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
Herbie Ong6470ea62019-01-07 18:56:57 -080045 registerExtension(pb2.E_MessageSetExtension)
46 registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
47 registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
48 registerExtension(pb2.E_MessageSetExtension_ExtNested)
49 registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
Herbie Ongc525c972018-12-18 18:04:31 -080050}
51
52func registerExtension(xd *protoapi.ExtensionDesc) {
53 xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
54 preg.GlobalTypes.Register(xt)
55}
56
Herbie Ong800c9902018-12-06 15:28:53 -080057func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080058 tests := []struct {
59 desc string
Herbie Ong66c365c2019-01-04 14:08:41 -080060 umo textpb.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080061 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080062 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080063 wantMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080064 wantErr bool
65 }{{
66 desc: "proto2 empty message",
67 inputMessage: &pb2.Scalars{},
68 wantMessage: &pb2.Scalars{},
69 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080070 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080071 inputMessage: &pb2.Scalars{},
72 inputText: `opt_bool: false
73opt_int32: 0
74opt_int64: 0
75opt_uint32: 0
76opt_uint64: 0
77opt_sint32: 0
78opt_sint64: 0
79opt_fixed32: 0
80opt_fixed64: 0
81opt_sfixed32: 0
82opt_sfixed64: 0
83opt_float: 0
84opt_double: 0
85opt_bytes: ""
86opt_string: ""
87`,
88 wantMessage: &pb2.Scalars{
89 OptBool: scalar.Bool(false),
90 OptInt32: scalar.Int32(0),
91 OptInt64: scalar.Int64(0),
92 OptUint32: scalar.Uint32(0),
93 OptUint64: scalar.Uint64(0),
94 OptSint32: scalar.Int32(0),
95 OptSint64: scalar.Int64(0),
96 OptFixed32: scalar.Uint32(0),
97 OptFixed64: scalar.Uint64(0),
98 OptSfixed32: scalar.Int32(0),
99 OptSfixed64: scalar.Int64(0),
100 OptFloat: scalar.Float32(0),
101 OptDouble: scalar.Float64(0),
102 OptBytes: []byte{},
103 OptString: scalar.String(""),
104 },
105 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800106 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -0800107 inputMessage: &pb3.Scalars{},
108 inputText: `s_bool: false
109s_int32: 0
110s_int64: 0
111s_uint32: 0
112s_uint64: 0
113s_sint32: 0
114s_sint64: 0
115s_fixed32: 0
116s_fixed64: 0
117s_sfixed32: 0
118s_sfixed64: 0
119s_float: 0
120s_double: 0
121s_bytes: ""
122s_string: ""
123`,
124 wantMessage: &pb3.Scalars{},
125 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800126 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800127 inputMessage: &pb2.Scalars{},
128 inputText: `opt_bool: true
129opt_int32: 255
130opt_int64: 3735928559
131opt_uint32: 0xff
132opt_uint64: 0xdeadbeef
133opt_sint32: -1001
134opt_sint64: -0xffff
135opt_fixed64: 64
136opt_sfixed32: -32
137opt_float: 1.234
138opt_double: 1.23e+100
139opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
140opt_string: "谷歌"
141`,
142 wantMessage: &pb2.Scalars{
143 OptBool: scalar.Bool(true),
144 OptInt32: scalar.Int32(0xff),
145 OptInt64: scalar.Int64(0xdeadbeef),
146 OptUint32: scalar.Uint32(0xff),
147 OptUint64: scalar.Uint64(0xdeadbeef),
148 OptSint32: scalar.Int32(-1001),
149 OptSint64: scalar.Int64(-0xffff),
150 OptFixed64: scalar.Uint64(64),
151 OptSfixed32: scalar.Int32(-32),
152 OptFloat: scalar.Float32(1.234),
153 OptDouble: scalar.Float64(1.23e100),
154 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
155 OptString: scalar.String("谷歌"),
156 },
157 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800158 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800159 inputMessage: &pb3.Scalars{},
160 inputText: `s_bool: true
161s_int32: 255
162s_int64: 3735928559
163s_uint32: 0xff
164s_uint64: 0xdeadbeef
165s_sint32: -1001
166s_sint64: -0xffff
167s_fixed64: 64
168s_sfixed32: -32
169s_float: 1.234
170s_double: 1.23e+100
171s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
172s_string: "谷歌"
173`,
174 wantMessage: &pb3.Scalars{
175 SBool: true,
176 SInt32: 0xff,
177 SInt64: 0xdeadbeef,
178 SUint32: 0xff,
179 SUint64: 0xdeadbeef,
180 SSint32: -1001,
181 SSint64: -0xffff,
182 SFixed64: 64,
183 SSfixed32: -32,
184 SFloat: 1.234,
185 SDouble: 1.23e100,
186 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
187 SString: "谷歌",
188 },
189 }, {
190 desc: "proto2 message contains unknown field",
191 inputMessage: &pb2.Scalars{},
192 inputText: "unknown_field: 123",
193 wantErr: true,
194 }, {
195 desc: "proto3 message contains unknown field",
196 inputMessage: &pb3.Scalars{},
197 inputText: "unknown_field: 456",
198 wantErr: true,
199 }, {
200 desc: "proto2 numeric key field",
201 inputMessage: &pb2.Scalars{},
202 inputText: "1: true",
203 wantErr: true,
204 }, {
205 desc: "proto3 numeric key field",
206 inputMessage: &pb3.Scalars{},
207 inputText: "1: true",
208 wantErr: true,
209 }, {
210 desc: "invalid bool value",
211 inputMessage: &pb3.Scalars{},
212 inputText: "s_bool: 123",
213 wantErr: true,
214 }, {
215 desc: "invalid int32 value",
216 inputMessage: &pb3.Scalars{},
217 inputText: "s_int32: not_a_num",
218 wantErr: true,
219 }, {
220 desc: "invalid int64 value",
221 inputMessage: &pb3.Scalars{},
222 inputText: "s_int64: 'not a num either'",
223 wantErr: true,
224 }, {
225 desc: "invalid uint32 value",
226 inputMessage: &pb3.Scalars{},
227 inputText: "s_fixed32: -42",
228 wantErr: true,
229 }, {
230 desc: "invalid uint64 value",
231 inputMessage: &pb3.Scalars{},
232 inputText: "s_uint64: -47",
233 wantErr: true,
234 }, {
235 desc: "invalid sint32 value",
236 inputMessage: &pb3.Scalars{},
237 inputText: "s_sint32: '42'",
238 wantErr: true,
239 }, {
240 desc: "invalid sint64 value",
241 inputMessage: &pb3.Scalars{},
242 inputText: "s_sint64: '-47'",
243 wantErr: true,
244 }, {
245 desc: "invalid fixed32 value",
246 inputMessage: &pb3.Scalars{},
247 inputText: "s_fixed32: -42",
248 wantErr: true,
249 }, {
250 desc: "invalid fixed64 value",
251 inputMessage: &pb3.Scalars{},
252 inputText: "s_fixed64: -42",
253 wantErr: true,
254 }, {
255 desc: "invalid sfixed32 value",
256 inputMessage: &pb3.Scalars{},
257 inputText: "s_sfixed32: 'not valid'",
258 wantErr: true,
259 }, {
260 desc: "invalid sfixed64 value",
261 inputMessage: &pb3.Scalars{},
262 inputText: "s_sfixed64: bad",
263 wantErr: true,
264 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800265 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800266 inputMessage: &pb3.Scalars{},
267 inputText: "s_float: inf",
268 wantMessage: &pb3.Scalars{
269 SFloat: float32(math.Inf(1)),
270 },
271 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800272 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800273 inputMessage: &pb3.Scalars{},
274 inputText: "s_float: -inf",
275 wantMessage: &pb3.Scalars{
276 SFloat: float32(math.Inf(-1)),
277 },
278 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800279 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800280 inputMessage: &pb3.Scalars{},
281 inputText: "s_double: inf",
282 wantMessage: &pb3.Scalars{
283 SDouble: math.Inf(1),
284 },
285 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800286 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800287 inputMessage: &pb3.Scalars{},
288 inputText: "s_double: -inf",
289 wantMessage: &pb3.Scalars{
290 SDouble: math.Inf(-1),
291 },
292 }, {
293 desc: "invalid string value",
294 inputMessage: &pb3.Scalars{},
295 inputText: "s_string: invalid_string",
296 wantErr: true,
297 }, {
298 desc: "proto2 bytes set to empty string",
299 inputMessage: &pb2.Scalars{},
300 inputText: "opt_bytes: ''",
301 wantMessage: &pb2.Scalars{
302 OptBytes: []byte(""),
303 },
304 }, {
305 desc: "proto3 bytes set to empty string",
306 inputMessage: &pb3.Scalars{},
307 inputText: "s_bytes: ''",
308 wantMessage: &pb3.Scalars{},
309 }, {
310 desc: "proto2 duplicate singular field",
311 inputMessage: &pb2.Scalars{},
312 inputText: `
313opt_bool: true
314opt_bool: false
315`,
316 wantErr: true,
317 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800318 desc: "proto2 more duplicate singular field",
319 inputMessage: &pb2.Scalars{},
320 inputText: `
321opt_bool: true
322opt_string: "hello"
323opt_bool: false
324`,
325 wantErr: true,
326 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800327 desc: "proto2 invalid singular field",
328 inputMessage: &pb2.Scalars{},
329 inputText: `
330opt_bool: [true, false]
331`,
332 wantErr: true,
333 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800334 desc: "proto3 duplicate singular field",
335 inputMessage: &pb3.Scalars{},
336 inputText: `
337s_bool: false
338s_bool: true
339`,
340 wantErr: true,
341 }, {
342 desc: "proto3 more duplicate singular field",
343 inputMessage: &pb3.Scalars{},
344 inputText: `
345s_bool: false
346s_string: ""
347s_bool: true
348`,
349 wantErr: true,
350 }, {
351 desc: "proto2 enum",
352 inputMessage: &pb2.Enums{},
353 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800354opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800355opt_nested_enum: UNO
356`,
357 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800358 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800359 OptNestedEnum: pb2.Enums_UNO.Enum(),
360 },
361 }, {
362 desc: "proto2 enum set to numeric values",
363 inputMessage: &pb2.Enums{},
364 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800365opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800366opt_nested_enum: 2
367`,
368 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800369 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800370 OptNestedEnum: pb2.Enums_DOS.Enum(),
371 },
372 }, {
373 desc: "proto2 enum set to unnamed numeric values",
374 inputMessage: &pb2.Enums{},
375 inputText: `
376opt_enum: 101
377opt_nested_enum: -101
378`,
379 wantMessage: &pb2.Enums{
380 OptEnum: pb2Enum(101),
381 OptNestedEnum: pb2Enums_NestedEnum(-101),
382 },
383 }, {
384 desc: "proto2 enum set to invalid named",
385 inputMessage: &pb2.Enums{},
386 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800387opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800388opt_nested_enum: UNNAMED_TOO
389`,
390 wantErr: true,
391 }, {
392 desc: "proto3 enum name value",
393 inputMessage: &pb3.Enums{},
394 inputText: `
395s_enum: ONE
396s_nested_enum: DIEZ
397`,
398 wantMessage: &pb3.Enums{
399 SEnum: pb3.Enum_ONE,
400 SNestedEnum: pb3.Enums_DIEZ,
401 },
402 }, {
403 desc: "proto3 enum numeric value",
404 inputMessage: &pb3.Enums{},
405 inputText: `
406s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800407s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800408`,
409 wantMessage: &pb3.Enums{
410 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800411 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800412 },
413 }, {
414 desc: "proto3 enum unnamed numeric value",
415 inputMessage: &pb3.Enums{},
416 inputText: `
417s_enum: 0x7fffffff
418s_nested_enum: -0x80000000
419`,
420 wantMessage: &pb3.Enums{
421 SEnum: 0x7fffffff,
422 SNestedEnum: -0x80000000,
423 },
424 }, {
425 desc: "proto2 nested empty messages",
426 inputMessage: &pb2.Nests{},
427 inputText: `
428opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800429OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800430`,
431 wantMessage: &pb2.Nests{
432 OptNested: &pb2.Nested{},
433 Optgroup: &pb2.Nests_OptGroup{},
434 },
435 }, {
436 desc: "proto2 nested messages",
437 inputMessage: &pb2.Nests{},
438 inputText: `
439opt_nested: {
440 opt_string: "nested message"
441 opt_nested: {
442 opt_string: "another nested message"
443 }
444}
445`,
446 wantMessage: &pb2.Nests{
447 OptNested: &pb2.Nested{
448 OptString: scalar.String("nested message"),
449 OptNested: &pb2.Nested{
450 OptString: scalar.String("another nested message"),
451 },
452 },
453 },
454 }, {
455 desc: "proto3 nested empty message",
456 inputMessage: &pb3.Nests{},
457 inputText: "s_nested: {}",
458 wantMessage: &pb3.Nests{
459 SNested: &pb3.Nested{},
460 },
461 }, {
462 desc: "proto3 nested message",
463 inputMessage: &pb3.Nests{},
464 inputText: `
465s_nested: {
466 s_string: "nested message"
467 s_nested: {
468 s_string: "another nested message"
469 }
470}
471`,
472 wantMessage: &pb3.Nests{
473 SNested: &pb3.Nested{
474 SString: "nested message",
475 SNested: &pb3.Nested{
476 SString: "another nested message",
477 },
478 },
479 },
480 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800481 desc: "oneof set to empty string",
482 inputMessage: &pb3.Oneofs{},
483 inputText: "oneof_string: ''",
484 wantMessage: &pb3.Oneofs{
485 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800486 },
487 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800488 desc: "oneof set to string",
489 inputMessage: &pb3.Oneofs{},
490 inputText: "oneof_string: 'hello'",
491 wantMessage: &pb3.Oneofs{
492 Union: &pb3.Oneofs_OneofString{
493 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800494 },
495 },
496 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800497 desc: "oneof set to enum",
498 inputMessage: &pb3.Oneofs{},
499 inputText: "oneof_enum: TEN",
500 wantMessage: &pb3.Oneofs{
501 Union: &pb3.Oneofs_OneofEnum{
502 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800503 },
504 },
505 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800506 desc: "oneof set to empty message",
507 inputMessage: &pb3.Oneofs{},
508 inputText: "oneof_nested: {}",
509 wantMessage: &pb3.Oneofs{
510 Union: &pb3.Oneofs_OneofNested{
511 OneofNested: &pb3.Nested{},
512 },
513 },
514 }, {
515 desc: "oneof set to message",
516 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800517 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800518oneof_nested: {
519 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800520}
521`,
Herbie Ong8170d692019-02-13 14:13:21 -0800522 wantMessage: &pb3.Oneofs{
523 Union: &pb3.Oneofs_OneofNested{
524 OneofNested: &pb3.Nested{
525 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800526 },
527 },
528 },
529 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800530 desc: "oneof set to last value",
531 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800532 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800533oneof_nested: {
534 s_string: "nested message"
Herbie Ong6470ea62019-01-07 18:56:57 -0800535}
Herbie Ong8170d692019-02-13 14:13:21 -0800536oneof_enum: TEN
537oneof_string: "wins"
Herbie Ong6470ea62019-01-07 18:56:57 -0800538`,
Herbie Ong8170d692019-02-13 14:13:21 -0800539 wantMessage: &pb3.Oneofs{
540 Union: &pb3.Oneofs_OneofString{
541 OneofString: "wins",
Herbie Ong6470ea62019-01-07 18:56:57 -0800542 },
543 },
544 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800545 desc: "repeated scalar using same field name",
546 inputMessage: &pb2.Repeats{},
547 inputText: `
548rpt_string: "a"
549rpt_string: "b"
550rpt_int32: 0xff
551rpt_float: 1.23
552rpt_bytes: "bytes"
553`,
554 wantMessage: &pb2.Repeats{
555 RptString: []string{"a", "b"},
556 RptInt32: []int32{0xff},
557 RptFloat: []float32{1.23},
558 RptBytes: [][]byte{[]byte("bytes")},
559 },
560 }, {
561 desc: "repeated using mix of [] and repeated field name",
562 inputMessage: &pb2.Repeats{},
563 inputText: `
564rpt_string: "a"
565rpt_bool: true
566rpt_string: ["x", "y"]
567rpt_bool: [ false, true ]
568rpt_string: "b"
569`,
570 wantMessage: &pb2.Repeats{
571 RptString: []string{"a", "x", "y", "b"},
572 RptBool: []bool{true, false, true},
573 },
574 }, {
575 desc: "repeated enums",
576 inputMessage: &pb2.Enums{},
577 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800578rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800579rpt_enum: 1
580rpt_nested_enum: [DOS, 2]
581rpt_enum: 42
582rpt_nested_enum: -47
583`,
584 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800585 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800586 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
587 },
588 }, {
589 desc: "repeated nested messages",
590 inputMessage: &pb2.Nests{},
591 inputText: `
592rpt_nested: {
593 opt_string: "repeat nested one"
594}
595rpt_nested: {
596 opt_string: "repeat nested two"
597 opt_nested: {
598 opt_string: "inside repeat nested two"
599 }
600}
601rpt_nested: {}
602`,
603 wantMessage: &pb2.Nests{
604 RptNested: []*pb2.Nested{
605 {
606 OptString: scalar.String("repeat nested one"),
607 },
608 {
609 OptString: scalar.String("repeat nested two"),
610 OptNested: &pb2.Nested{
611 OptString: scalar.String("inside repeat nested two"),
612 },
613 },
614 {},
615 },
616 },
617 }, {
618 desc: "repeated group fields",
619 inputMessage: &pb2.Nests{},
620 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800621RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800622 rpt_string: "hello"
623 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800624}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800625RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800626`,
627 wantMessage: &pb2.Nests{
628 Rptgroup: []*pb2.Nests_RptGroup{
629 {
Herbie Ong8170d692019-02-13 14:13:21 -0800630 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800631 },
632 {},
633 },
634 },
635 }, {
636 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800637 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800638 inputText: `
639int32_to_str: {
640 key: -101
641 value: "-101"
642}
643int32_to_str: {
644 key: 0
645 value: "zero"
646}
Herbie Ong8170d692019-02-13 14:13:21 -0800647bool_to_uint32: {
648 key: false
649 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800650}
651int32_to_str: {
652 key: 255
653 value: "0xff"
654}
655bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800656 key: true
657 value: 42
658}
659`,
Herbie Ong8170d692019-02-13 14:13:21 -0800660 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800661 Int32ToStr: map[int32]string{
662 -101: "-101",
663 0xff: "0xff",
664 0: "zero",
665 },
Herbie Ong800c9902018-12-06 15:28:53 -0800666 BoolToUint32: map[bool]uint32{
667 true: 42,
668 false: 101,
669 },
670 },
671 }, {
672 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800673 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800674 inputText: `
675uint64_to_enum: {
676 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800677 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800678}
679uint64_to_enum: {
680 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800681 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800682}
683uint64_to_enum: {
684 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800685 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800686}
687`,
Herbie Ong8170d692019-02-13 14:13:21 -0800688 wantMessage: &pb3.Maps{
689 Uint64ToEnum: map[uint64]pb3.Enum{
690 1: pb3.Enum_ONE,
691 2: pb3.Enum_TWO,
692 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800693 },
694 },
695 }, {
696 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800697 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800698 inputText: `
699str_to_nested: {
700 key: "nested_one"
701 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800702 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800703 }
704}
705`,
Herbie Ong8170d692019-02-13 14:13:21 -0800706 wantMessage: &pb3.Maps{
707 StrToNested: map[string]*pb3.Nested{
708 "nested_one": &pb3.Nested{
709 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800710 },
711 },
712 },
713 }, {
714 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800715 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800716 inputText: `
717str_to_oneofs: {
718 key: "nested"
719 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800720 oneof_nested: {
721 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800722 }
723 }
724}
725str_to_oneofs: {
726 key: "string"
727 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800728 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800729 }
730}
731`,
Herbie Ong8170d692019-02-13 14:13:21 -0800732 wantMessage: &pb3.Maps{
733 StrToOneofs: map[string]*pb3.Oneofs{
734 "string": &pb3.Oneofs{
735 Union: &pb3.Oneofs_OneofString{
736 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800737 },
738 },
Herbie Ong8170d692019-02-13 14:13:21 -0800739 "nested": &pb3.Oneofs{
740 Union: &pb3.Oneofs_OneofNested{
741 OneofNested: &pb3.Nested{
742 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800743 },
744 },
745 },
746 },
747 },
748 }, {
749 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800750 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800751 inputText: `
752int32_to_str: {
753 key: 0
754 value: "cero"
755}
756int32_to_str: {
757 key: 0
758 value: "zero"
759}
760`,
Herbie Ong8170d692019-02-13 14:13:21 -0800761 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800762 Int32ToStr: map[int32]string{
763 0: "zero",
764 },
765 },
766 }, {
767 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800768 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800769 inputText: `
770int32_to_str: {
771 key: 0
772 key: 1
773 value: "cero"
774}
775`,
776 wantErr: true,
777 }, {
778 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800779 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800780 inputText: `
781int32_to_str: {
782 key: 1
783 value: "cero"
784 value: "uno"
785}
786`,
787 wantErr: true,
788 }, {
789 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800790 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800791 inputText: `
792int32_to_str: {
793 value: "zero"
794}
Herbie Ong8170d692019-02-13 14:13:21 -0800795bool_to_uint32: {
796 value: 47
797}
798str_to_nested: {
799 value: {}
800}
Herbie Ong800c9902018-12-06 15:28:53 -0800801`,
Herbie Ong8170d692019-02-13 14:13:21 -0800802 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800803 Int32ToStr: map[int32]string{
804 0: "zero",
805 },
Herbie Ong8170d692019-02-13 14:13:21 -0800806 BoolToUint32: map[bool]uint32{
807 false: 47,
808 },
809 StrToNested: map[string]*pb3.Nested{
810 "": {},
811 },
Herbie Ong800c9902018-12-06 15:28:53 -0800812 },
813 }, {
814 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800815 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800816 inputText: `
817int32_to_str: {
818 key: 100
819}
Herbie Ong8170d692019-02-13 14:13:21 -0800820bool_to_uint32: {
821 key: true
822}
823uint64_to_enum: {
824 key: 101
825}
826str_to_nested: {
827 key: "hello"
828}
Herbie Ong800c9902018-12-06 15:28:53 -0800829`,
Herbie Ong8170d692019-02-13 14:13:21 -0800830 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800831 Int32ToStr: map[int32]string{
832 100: "",
833 },
Herbie Ong8170d692019-02-13 14:13:21 -0800834 BoolToUint32: map[bool]uint32{
835 true: 0,
836 },
837 Uint64ToEnum: map[uint64]pb3.Enum{
838 101: pb3.Enum_ZERO,
839 },
840 StrToNested: map[string]*pb3.Nested{
841 "hello": {},
842 },
Herbie Ong800c9902018-12-06 15:28:53 -0800843 },
844 }, {
845 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800846 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800847 inputText: `
848int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800849bool_to_uint32: {}
850uint64_to_enum: {}
851str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800852`,
Herbie Ong8170d692019-02-13 14:13:21 -0800853 wantMessage: &pb3.Maps{
854 Int32ToStr: map[int32]string{
855 0: "",
856 },
857 BoolToUint32: map[bool]uint32{
858 false: 0,
859 },
860 Uint64ToEnum: map[uint64]pb3.Enum{
861 0: pb3.Enum_ZERO,
862 },
863 StrToNested: map[string]*pb3.Nested{
864 "": {},
865 },
866 },
867 }, {
868 desc: "map contains overriding entries",
869 inputMessage: &pb3.Maps{},
870 inputText: `
871int32_to_str: {
872 key: 0
873}
874int32_to_str: {
875 value: "empty"
876}
877int32_to_str: {}
878`,
879 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800880 Int32ToStr: map[int32]string{
881 0: "",
882 },
883 },
884 }, {
885 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800886 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800887 inputText: `
888int32_to_str: {
889 key: 0
890 value: "cero"
891 unknown: "bad"
892}
893`,
894 wantErr: true,
895 }, {
896 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800897 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800898 inputText: `
899int32_to_str: {
900 [key]: 10
901 value: "ten"
902}
903`,
904 wantErr: true,
905 }, {
906 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800907 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800908 inputText: `
909int32_to_str: {
910 key: "invalid"
911 value: "cero"
912}
913`,
914 wantErr: true,
915 }, {
916 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800917 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800918 inputText: `
919int32_to_str: {
920 key: 100
921 value: 101
922}
923`,
924 wantErr: true,
925 }, {
926 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800927 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800928 inputText: `
929int32_to_str: {
930 key: 1
931 value: "one"
932}
933int32_to_str: [
934 {
935 key: 2
936 value: "not this"
937 },
938 {
939 },
940 {
941 key: 3
942 value: "three"
943 }
944]
945int32_to_str: {
946 key: 2
947 value: "two"
948}
949`,
Herbie Ong8170d692019-02-13 14:13:21 -0800950 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800951 Int32ToStr: map[int32]string{
952 0: "",
953 1: "one",
954 2: "two",
955 3: "three",
956 },
957 },
958 }, {
959 desc: "proto2 required fields not set",
960 inputMessage: &pb2.Requireds{},
961 wantErr: true,
962 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800963 desc: "proto2 required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800964 inputMessage: &pb2.PartialRequired{},
965 inputText: "req_string: 'this is required'",
966 wantMessage: &pb2.PartialRequired{
967 ReqString: scalar.String("this is required"),
968 },
969 }, {
970 desc: "proto2 required fields partially set",
971 inputMessage: &pb2.Requireds{},
972 inputText: `
973req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800974req_sfixed64: 3203386110
975req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800976req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800977`,
978 wantMessage: &pb2.Requireds{
979 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800980 ReqSfixed64: scalar.Int64(0xbeefcafe),
981 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800982 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800983 },
984 wantErr: true,
985 }, {
986 desc: "proto2 required fields all set",
987 inputMessage: &pb2.Requireds{},
988 inputText: `
989req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800990req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800991req_double: 0
992req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800993req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800994req_nested: {}
995`,
996 wantMessage: &pb2.Requireds{
997 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800998 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -0800999 ReqDouble: scalar.Float64(0),
1000 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001001 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001002 ReqNested: &pb2.Nested{},
1003 },
1004 }, {
1005 desc: "indirect required field",
1006 inputMessage: &pb2.IndirectRequired{},
1007 inputText: "opt_nested: {}",
1008 wantMessage: &pb2.IndirectRequired{
1009 OptNested: &pb2.NestedWithRequired{},
1010 },
1011 wantErr: true,
1012 }, {
1013 desc: "indirect required field in repeated",
1014 inputMessage: &pb2.IndirectRequired{},
1015 inputText: `
1016rpt_nested: {
1017 req_string: "one"
1018}
1019rpt_nested: {}
1020rpt_nested: {
1021 req_string: "three"
1022}
1023`,
1024 wantMessage: &pb2.IndirectRequired{
1025 RptNested: []*pb2.NestedWithRequired{
1026 {
1027 ReqString: scalar.String("one"),
1028 },
1029 {},
1030 {
1031 ReqString: scalar.String("three"),
1032 },
1033 },
1034 },
1035 wantErr: true,
1036 }, {
1037 desc: "indirect required field in map",
1038 inputMessage: &pb2.IndirectRequired{},
1039 inputText: `
1040str_to_nested: {
1041 key: "missing"
1042}
1043str_to_nested: {
1044 key: "contains"
1045 value: {
1046 req_string: "here"
1047 }
1048}
1049`,
1050 wantMessage: &pb2.IndirectRequired{
1051 StrToNested: map[string]*pb2.NestedWithRequired{
1052 "missing": &pb2.NestedWithRequired{},
1053 "contains": &pb2.NestedWithRequired{
1054 ReqString: scalar.String("here"),
1055 },
1056 },
1057 },
1058 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001059 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001060 desc: "indirect required field in oneof",
1061 inputMessage: &pb2.IndirectRequired{},
1062 inputText: `oneof_nested: {}
1063`,
1064 wantMessage: &pb2.IndirectRequired{
1065 Union: &pb2.IndirectRequired_OneofNested{
1066 OneofNested: &pb2.NestedWithRequired{},
1067 },
1068 },
1069 wantErr: true,
1070 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001071 desc: "ignore reserved field",
1072 inputMessage: &pb2.Nests{},
1073 inputText: "reserved_field: 'ignore this'",
1074 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001075 }, {
1076 desc: "extensions of non-repeated fields",
1077 inputMessage: &pb2.Extensions{},
1078 inputText: `opt_string: "non-extension field"
1079[pb2.opt_ext_bool]: true
1080opt_bool: true
1081[pb2.opt_ext_nested]: {
1082 opt_string: "nested in an extension"
1083 opt_nested: {
1084 opt_string: "another nested in an extension"
1085 }
1086}
1087[pb2.opt_ext_string]: "extension field"
1088opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001089[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001090`,
1091 wantMessage: func() proto.Message {
1092 m := &pb2.Extensions{
1093 OptString: scalar.String("non-extension field"),
1094 OptBool: scalar.Bool(true),
1095 OptInt32: scalar.Int32(42),
1096 }
1097 setExtension(m, pb2.E_OptExtBool, true)
1098 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001099 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001100 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1101 OptString: scalar.String("nested in an extension"),
1102 OptNested: &pb2.Nested{
1103 OptString: scalar.String("another nested in an extension"),
1104 },
1105 })
1106 return m
1107 }(),
1108 }, {
1109 desc: "extensions of repeated fields",
1110 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001111 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001112[pb2.rpt_ext_enum]: 101
1113[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001114[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001115[pb2.rpt_ext_nested]: {
1116 opt_string: "one"
1117}
1118[pb2.rpt_ext_nested]: {
1119 opt_string: "two"
1120}
1121[pb2.rpt_ext_fixed32]: 47
1122[pb2.rpt_ext_nested]: {
1123 opt_string: "three"
1124}
1125`,
1126 wantMessage: func() proto.Message {
1127 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001128 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001129 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1130 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1131 &pb2.Nested{OptString: scalar.String("one")},
1132 &pb2.Nested{OptString: scalar.String("two")},
1133 &pb2.Nested{OptString: scalar.String("three")},
1134 })
1135 return m
1136 }(),
1137 }, {
1138 desc: "extensions of non-repeated fields in another message",
1139 inputMessage: &pb2.Extensions{},
1140 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001141[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001142[pb2.ExtensionsContainer.opt_ext_nested]: {
1143 opt_string: "nested in an extension"
1144 opt_nested: {
1145 opt_string: "another nested in an extension"
1146 }
1147}
1148[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1149`,
1150 wantMessage: func() proto.Message {
1151 m := &pb2.Extensions{}
1152 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1153 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001154 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001155 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1156 OptString: scalar.String("nested in an extension"),
1157 OptNested: &pb2.Nested{
1158 OptString: scalar.String("another nested in an extension"),
1159 },
1160 })
1161 return m
1162 }(),
1163 }, {
1164 desc: "extensions of repeated fields in another message",
1165 inputMessage: &pb2.Extensions{},
1166 inputText: `opt_string: "non-extension field"
1167opt_bool: true
1168opt_int32: 42
1169[pb2.ExtensionsContainer.rpt_ext_nested]: {
1170 opt_string: "one"
1171}
Herbie Ong8170d692019-02-13 14:13:21 -08001172[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001173[pb2.ExtensionsContainer.rpt_ext_nested]: {
1174 opt_string: "two"
1175}
1176[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1177[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001178[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001179[pb2.ExtensionsContainer.rpt_ext_nested]: {
1180 opt_string: "three"
1181}
1182[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1183`,
1184 wantMessage: func() proto.Message {
1185 m := &pb2.Extensions{
1186 OptString: scalar.String("non-extension field"),
1187 OptBool: scalar.Bool(true),
1188 OptInt32: scalar.Int32(42),
1189 }
Herbie Ong8170d692019-02-13 14:13:21 -08001190 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001191 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1192 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1193 &pb2.Nested{OptString: scalar.String("one")},
1194 &pb2.Nested{OptString: scalar.String("two")},
1195 &pb2.Nested{OptString: scalar.String("three")},
1196 })
1197 return m
1198 }(),
1199 }, {
1200 desc: "invalid extension field name",
1201 inputMessage: &pb2.Extensions{},
1202 inputText: "[pb2.invalid_message_field]: true",
1203 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001204 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001205 desc: "MessageSet",
1206 inputMessage: &pb2.MessageSet{},
1207 inputText: `
1208[pb2.MessageSetExtension]: {
1209 opt_string: "a messageset extension"
1210}
1211[pb2.MessageSetExtension.ext_nested]: {
1212 opt_string: "just a regular extension"
1213}
1214[pb2.MessageSetExtension.not_message_set_extension]: {
1215 opt_string: "not a messageset extension"
1216}
1217`,
1218 wantMessage: func() proto.Message {
1219 m := &pb2.MessageSet{}
1220 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1221 OptString: scalar.String("a messageset extension"),
1222 })
1223 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1224 OptString: scalar.String("not a messageset extension"),
1225 })
1226 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1227 OptString: scalar.String("just a regular extension"),
1228 })
1229 return m
1230 }(),
1231 }, {
1232 desc: "not real MessageSet 1",
1233 inputMessage: &pb2.FakeMessageSet{},
1234 inputText: `
1235[pb2.FakeMessageSetExtension.message_set_extension]: {
1236 opt_string: "not a messageset extension"
1237}
1238`,
1239 wantMessage: func() proto.Message {
1240 m := &pb2.FakeMessageSet{}
1241 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1242 OptString: scalar.String("not a messageset extension"),
1243 })
1244 return m
1245 }(),
1246 }, {
1247 desc: "not real MessageSet 2",
1248 inputMessage: &pb2.FakeMessageSet{},
1249 inputText: `
1250[pb2.FakeMessageSetExtension]: {
1251 opt_string: "not a messageset extension"
1252}
1253`,
1254 wantErr: true,
1255 }, {
1256 desc: "not real MessageSet 3",
1257 inputMessage: &pb2.MessageSet{},
1258 inputText: `
1259[pb2.message_set_extension]: {
1260 opt_string: "another not a messageset extension"
1261}
1262`,
1263 wantMessage: func() proto.Message {
1264 m := &pb2.MessageSet{}
1265 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1266 OptString: scalar.String("another not a messageset extension"),
1267 })
1268 return m
1269 }(),
1270 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001271 // TODO: Change these tests to directly use anypb.Any type instead once
1272 // type has been regenerated with V2 compiler.
Herbie Ong66c365c2019-01-04 14:08:41 -08001273 desc: "Any not expanded",
1274 inputMessage: &pb2.KnownTypes{},
1275 inputText: `opt_any: {
1276type_url: "pb2.Nested"
1277value: "some bytes"
1278}
1279`,
1280 wantMessage: &pb2.KnownTypes{
1281 OptAny: &anypb.Any{
1282 TypeUrl: "pb2.Nested",
1283 Value: []byte("some bytes"),
1284 },
1285 },
1286 }, {
1287 desc: "Any not expanded missing value",
1288 inputMessage: &pb2.KnownTypes{},
1289 inputText: `opt_any: {
1290type_url: "pb2.Nested"
1291}
1292`,
1293 wantMessage: &pb2.KnownTypes{
1294 OptAny: &anypb.Any{
1295 TypeUrl: "pb2.Nested",
1296 },
1297 },
1298 }, {
1299 desc: "Any not expanded missing type_url",
1300 inputMessage: &pb2.KnownTypes{},
1301 inputText: `opt_any: {
1302value: "some bytes"
1303}
1304`,
1305 wantMessage: &pb2.KnownTypes{
1306 OptAny: &anypb.Any{
1307 Value: []byte("some bytes"),
1308 },
1309 },
1310 }, {
1311 desc: "Any expanded",
1312 umo: func() textpb.UnmarshalOptions {
1313 m := &pb2.Nested{}
1314 resolver := preg.NewTypes(m.ProtoReflect().Type())
1315 return textpb.UnmarshalOptions{Resolver: resolver}
1316 }(),
1317 inputMessage: &pb2.KnownTypes{},
1318 inputText: `opt_any: {
1319 [foobar/pb2.Nested]: {
1320 opt_string: "embedded inside Any"
1321 opt_nested: {
1322 opt_string: "inception"
1323 }
1324 }
1325}
1326`,
1327 wantMessage: func() proto.Message {
1328 m := &pb2.Nested{
1329 OptString: scalar.String("embedded inside Any"),
1330 OptNested: &pb2.Nested{
1331 OptString: scalar.String("inception"),
1332 },
1333 }
1334 // TODO: Switch to V2 marshal when ready.
1335 b, err := protoV1.Marshal(m)
1336 if err != nil {
1337 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1338 }
1339 return &pb2.KnownTypes{
1340 OptAny: &anypb.Any{
1341 TypeUrl: "foobar/pb2.Nested",
1342 Value: b,
1343 },
1344 }
1345 }(),
1346 }, {
1347 desc: "Any expanded with empty value",
1348 umo: func() textpb.UnmarshalOptions {
1349 m := &pb2.Nested{}
1350 resolver := preg.NewTypes(m.ProtoReflect().Type())
1351 return textpb.UnmarshalOptions{Resolver: resolver}
1352 }(),
1353 inputMessage: &pb2.KnownTypes{},
1354 inputText: `opt_any: {
1355[foo.com/pb2.Nested]: {}
1356}
1357`,
1358 wantMessage: &pb2.KnownTypes{
1359 OptAny: &anypb.Any{
1360 TypeUrl: "foo.com/pb2.Nested",
1361 },
1362 },
1363 }, {
1364 desc: "Any expanded with missing required error",
1365 umo: func() textpb.UnmarshalOptions {
1366 m := &pb2.PartialRequired{}
1367 resolver := preg.NewTypes(m.ProtoReflect().Type())
1368 return textpb.UnmarshalOptions{Resolver: resolver}
1369 }(),
1370 inputMessage: &pb2.KnownTypes{},
1371 inputText: `opt_any: {
1372 [pb2.PartialRequired]: {
1373 opt_string: "embedded inside Any"
1374 }
1375}
1376`,
1377 wantMessage: func() proto.Message {
1378 m := &pb2.PartialRequired{
1379 OptString: scalar.String("embedded inside Any"),
1380 }
1381 // TODO: Switch to V2 marshal when ready.
1382 b, err := protoV1.Marshal(m)
1383 // Ignore required not set error.
1384 if _, ok := err.(*protoV1.RequiredNotSetError); !ok {
1385 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1386 }
1387 return &pb2.KnownTypes{
1388 OptAny: &anypb.Any{
1389 TypeUrl: "pb2.PartialRequired",
1390 Value: b,
1391 },
1392 }
1393 }(),
1394 wantErr: true,
1395 }, {
1396 desc: "Any expanded with unregistered type",
1397 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
1398 inputMessage: &pb2.KnownTypes{},
1399 inputText: `opt_any: {
1400[SomeMessage]: {}
1401}
1402`,
1403 wantErr: true,
1404 }, {
1405 desc: "Any expanded with invalid value",
1406 umo: func() textpb.UnmarshalOptions {
1407 m := &pb2.Nested{}
1408 resolver := preg.NewTypes(m.ProtoReflect().Type())
1409 return textpb.UnmarshalOptions{Resolver: resolver}
1410 }(),
1411 inputMessage: &pb2.KnownTypes{},
1412 inputText: `opt_any: {
1413[pb2.Nested]: 123
1414}
1415`,
1416 wantErr: true,
1417 }, {
1418 desc: "Any expanded with unknown fields",
1419 umo: func() textpb.UnmarshalOptions {
1420 m := &pb2.Nested{}
1421 resolver := preg.NewTypes(m.ProtoReflect().Type())
1422 return textpb.UnmarshalOptions{Resolver: resolver}
1423 }(),
1424 inputMessage: &pb2.KnownTypes{},
1425 inputText: `opt_any: {
1426[pb2.Nested]: {}
1427unknown: ""
1428}
1429`,
1430 wantErr: true,
1431 }, {
1432 desc: "Any contains expanded and unexpanded fields",
1433 umo: func() textpb.UnmarshalOptions {
1434 m := &pb2.Nested{}
1435 resolver := preg.NewTypes(m.ProtoReflect().Type())
1436 return textpb.UnmarshalOptions{Resolver: resolver}
1437 }(),
1438 inputMessage: &pb2.KnownTypes{},
1439 inputText: `opt_any: {
1440[pb2.Nested]: {}
1441type_url: "pb2.Nested"
1442}
1443`,
1444 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001445 }}
1446
1447 for _, tt := range tests {
1448 tt := tt
1449 t.Run(tt.desc, func(t *testing.T) {
1450 t.Parallel()
Herbie Ong66c365c2019-01-04 14:08:41 -08001451 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001452 if err != nil && !tt.wantErr {
1453 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1454 }
1455 if err == nil && tt.wantErr {
1456 t.Error("Unmarshal() got nil error, want error\n\n")
1457 }
Herbie Ong70651952018-12-13 14:19:50 -08001458 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001459 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1460 }
1461 })
1462 }
1463}