blob: 2f14029573c9cccdf044b60513a7c22da9e6a750 [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 Ongc525c972018-12-18 18:04:31 -080013 "github.com/golang/protobuf/v2/internal/legacy"
Herbie Ong800c9902018-12-06 15:28:53 -080014 "github.com/golang/protobuf/v2/internal/scalar"
Herbie Ong70651952018-12-13 14:19:50 -080015 "github.com/golang/protobuf/v2/proto"
Herbie Ongc525c972018-12-18 18:04:31 -080016 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Joe Tsai4fddeba2019-03-20 18:29:32 -070017 "github.com/golang/protobuf/v2/runtime/protoiface"
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
Joe Tsai4fddeba2019-03-20 18:29:32 -070048func registerExtension(xd *protoiface.ExtensionDescV1) {
Herbie Ongc525c972018-12-18 18:04:31 -080049 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 Ong300cff02019-03-20 18:05:16 -070060 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080061 }{{
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 Ong8a1d4602019-04-02 20:19:36 -0700526 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800527 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800528 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700529oneof_enum: ZERO
530oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800531`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700532 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800533 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800534 desc: "repeated scalar using same field name",
535 inputMessage: &pb2.Repeats{},
536 inputText: `
537rpt_string: "a"
538rpt_string: "b"
539rpt_int32: 0xff
540rpt_float: 1.23
541rpt_bytes: "bytes"
542`,
543 wantMessage: &pb2.Repeats{
544 RptString: []string{"a", "b"},
545 RptInt32: []int32{0xff},
546 RptFloat: []float32{1.23},
547 RptBytes: [][]byte{[]byte("bytes")},
548 },
549 }, {
550 desc: "repeated using mix of [] and repeated field name",
551 inputMessage: &pb2.Repeats{},
552 inputText: `
553rpt_string: "a"
554rpt_bool: true
555rpt_string: ["x", "y"]
556rpt_bool: [ false, true ]
557rpt_string: "b"
558`,
559 wantMessage: &pb2.Repeats{
560 RptString: []string{"a", "x", "y", "b"},
561 RptBool: []bool{true, false, true},
562 },
563 }, {
564 desc: "repeated enums",
565 inputMessage: &pb2.Enums{},
566 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800567rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800568rpt_enum: 1
569rpt_nested_enum: [DOS, 2]
570rpt_enum: 42
571rpt_nested_enum: -47
572`,
573 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800574 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800575 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
576 },
577 }, {
578 desc: "repeated nested messages",
579 inputMessage: &pb2.Nests{},
580 inputText: `
581rpt_nested: {
582 opt_string: "repeat nested one"
583}
584rpt_nested: {
585 opt_string: "repeat nested two"
586 opt_nested: {
587 opt_string: "inside repeat nested two"
588 }
589}
590rpt_nested: {}
591`,
592 wantMessage: &pb2.Nests{
593 RptNested: []*pb2.Nested{
594 {
595 OptString: scalar.String("repeat nested one"),
596 },
597 {
598 OptString: scalar.String("repeat nested two"),
599 OptNested: &pb2.Nested{
600 OptString: scalar.String("inside repeat nested two"),
601 },
602 },
603 {},
604 },
605 },
606 }, {
607 desc: "repeated group fields",
608 inputMessage: &pb2.Nests{},
609 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800610RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800611 rpt_string: "hello"
612 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800613}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800614RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800615`,
616 wantMessage: &pb2.Nests{
617 Rptgroup: []*pb2.Nests_RptGroup{
618 {
Herbie Ong8170d692019-02-13 14:13:21 -0800619 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800620 },
621 {},
622 },
623 },
624 }, {
625 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800626 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800627 inputText: `
628int32_to_str: {
629 key: -101
630 value: "-101"
631}
632int32_to_str: {
633 key: 0
634 value: "zero"
635}
Herbie Ong8170d692019-02-13 14:13:21 -0800636bool_to_uint32: {
637 key: false
638 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800639}
640int32_to_str: {
641 key: 255
642 value: "0xff"
643}
644bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800645 key: true
646 value: 42
647}
648`,
Herbie Ong8170d692019-02-13 14:13:21 -0800649 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800650 Int32ToStr: map[int32]string{
651 -101: "-101",
652 0xff: "0xff",
653 0: "zero",
654 },
Herbie Ong800c9902018-12-06 15:28:53 -0800655 BoolToUint32: map[bool]uint32{
656 true: 42,
657 false: 101,
658 },
659 },
660 }, {
661 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800662 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800663 inputText: `
664uint64_to_enum: {
665 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800666 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800667}
668uint64_to_enum: {
669 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800670 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800671}
672uint64_to_enum: {
673 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800674 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800675}
676`,
Herbie Ong8170d692019-02-13 14:13:21 -0800677 wantMessage: &pb3.Maps{
678 Uint64ToEnum: map[uint64]pb3.Enum{
679 1: pb3.Enum_ONE,
680 2: pb3.Enum_TWO,
681 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800682 },
683 },
684 }, {
685 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800686 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800687 inputText: `
688str_to_nested: {
689 key: "nested_one"
690 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800691 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800692 }
693}
694`,
Herbie Ong8170d692019-02-13 14:13:21 -0800695 wantMessage: &pb3.Maps{
696 StrToNested: map[string]*pb3.Nested{
697 "nested_one": &pb3.Nested{
698 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800699 },
700 },
701 },
702 }, {
703 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800704 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800705 inputText: `
706str_to_oneofs: {
707 key: "nested"
708 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800709 oneof_nested: {
710 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800711 }
712 }
713}
714str_to_oneofs: {
715 key: "string"
716 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800717 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800718 }
719}
720`,
Herbie Ong8170d692019-02-13 14:13:21 -0800721 wantMessage: &pb3.Maps{
722 StrToOneofs: map[string]*pb3.Oneofs{
723 "string": &pb3.Oneofs{
724 Union: &pb3.Oneofs_OneofString{
725 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800726 },
727 },
Herbie Ong8170d692019-02-13 14:13:21 -0800728 "nested": &pb3.Oneofs{
729 Union: &pb3.Oneofs_OneofNested{
730 OneofNested: &pb3.Nested{
731 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800732 },
733 },
734 },
735 },
736 },
737 }, {
738 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800739 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800740 inputText: `
741int32_to_str: {
742 key: 0
743 value: "cero"
744}
745int32_to_str: {
746 key: 0
747 value: "zero"
748}
749`,
Herbie Ong8170d692019-02-13 14:13:21 -0800750 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800751 Int32ToStr: map[int32]string{
752 0: "zero",
753 },
754 },
755 }, {
756 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800757 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800758 inputText: `
759int32_to_str: {
760 key: 0
761 key: 1
762 value: "cero"
763}
764`,
765 wantErr: true,
766 }, {
767 desc: "map contains duplicate value 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: 1
772 value: "cero"
773 value: "uno"
774}
775`,
776 wantErr: true,
777 }, {
778 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800779 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800780 inputText: `
781int32_to_str: {
782 value: "zero"
783}
Herbie Ong8170d692019-02-13 14:13:21 -0800784bool_to_uint32: {
785 value: 47
786}
787str_to_nested: {
788 value: {}
789}
Herbie Ong800c9902018-12-06 15:28:53 -0800790`,
Herbie Ong8170d692019-02-13 14:13:21 -0800791 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800792 Int32ToStr: map[int32]string{
793 0: "zero",
794 },
Herbie Ong8170d692019-02-13 14:13:21 -0800795 BoolToUint32: map[bool]uint32{
796 false: 47,
797 },
798 StrToNested: map[string]*pb3.Nested{
799 "": {},
800 },
Herbie Ong800c9902018-12-06 15:28:53 -0800801 },
802 }, {
803 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800804 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800805 inputText: `
806int32_to_str: {
807 key: 100
808}
Herbie Ong8170d692019-02-13 14:13:21 -0800809bool_to_uint32: {
810 key: true
811}
812uint64_to_enum: {
813 key: 101
814}
815str_to_nested: {
816 key: "hello"
817}
Herbie Ong800c9902018-12-06 15:28:53 -0800818`,
Herbie Ong8170d692019-02-13 14:13:21 -0800819 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800820 Int32ToStr: map[int32]string{
821 100: "",
822 },
Herbie Ong8170d692019-02-13 14:13:21 -0800823 BoolToUint32: map[bool]uint32{
824 true: 0,
825 },
826 Uint64ToEnum: map[uint64]pb3.Enum{
827 101: pb3.Enum_ZERO,
828 },
829 StrToNested: map[string]*pb3.Nested{
830 "hello": {},
831 },
Herbie Ong800c9902018-12-06 15:28:53 -0800832 },
833 }, {
834 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800835 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800836 inputText: `
837int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800838bool_to_uint32: {}
839uint64_to_enum: {}
840str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800841`,
Herbie Ong8170d692019-02-13 14:13:21 -0800842 wantMessage: &pb3.Maps{
843 Int32ToStr: map[int32]string{
844 0: "",
845 },
846 BoolToUint32: map[bool]uint32{
847 false: 0,
848 },
849 Uint64ToEnum: map[uint64]pb3.Enum{
850 0: pb3.Enum_ZERO,
851 },
852 StrToNested: map[string]*pb3.Nested{
853 "": {},
854 },
855 },
856 }, {
857 desc: "map contains overriding entries",
858 inputMessage: &pb3.Maps{},
859 inputText: `
860int32_to_str: {
861 key: 0
862}
863int32_to_str: {
864 value: "empty"
865}
866int32_to_str: {}
867`,
868 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800869 Int32ToStr: map[int32]string{
870 0: "",
871 },
872 },
873 }, {
874 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800875 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800876 inputText: `
877int32_to_str: {
878 key: 0
879 value: "cero"
880 unknown: "bad"
881}
882`,
883 wantErr: true,
884 }, {
885 desc: "map contains extension-like key 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]: 10
890 value: "ten"
891}
892`,
893 wantErr: true,
894 }, {
895 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800896 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800897 inputText: `
898int32_to_str: {
899 key: "invalid"
900 value: "cero"
901}
902`,
903 wantErr: true,
904 }, {
905 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800906 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800907 inputText: `
908int32_to_str: {
909 key: 100
910 value: 101
911}
912`,
913 wantErr: true,
914 }, {
915 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800916 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800917 inputText: `
918int32_to_str: {
919 key: 1
920 value: "one"
921}
922int32_to_str: [
923 {
924 key: 2
925 value: "not this"
926 },
927 {
928 },
929 {
930 key: 3
931 value: "three"
932 }
933]
934int32_to_str: {
935 key: 2
936 value: "two"
937}
938`,
Herbie Ong8170d692019-02-13 14:13:21 -0800939 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800940 Int32ToStr: map[int32]string{
941 0: "",
942 1: "one",
943 2: "two",
944 3: "three",
945 },
946 },
947 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700948 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800949 inputMessage: &pb2.Requireds{},
950 wantErr: true,
951 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700952 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800953 inputMessage: &pb2.PartialRequired{},
954 inputText: "req_string: 'this is required'",
955 wantMessage: &pb2.PartialRequired{
956 ReqString: scalar.String("this is required"),
957 },
958 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700959 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800960 inputMessage: &pb2.Requireds{},
961 inputText: `
962req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800963req_sfixed64: 3203386110
964req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800965req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800966`,
967 wantMessage: &pb2.Requireds{
968 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800969 ReqSfixed64: scalar.Int64(0xbeefcafe),
970 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800971 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800972 },
973 wantErr: true,
974 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700975 desc: "required fields partially set with AllowPartial",
976 umo: textpb.UnmarshalOptions{AllowPartial: true},
977 inputMessage: &pb2.Requireds{},
978 inputText: `
979req_bool: false
980req_sfixed64: 3203386110
981req_string: "hello"
982req_enum: ONE
983`,
984 wantMessage: &pb2.Requireds{
985 ReqBool: scalar.Bool(false),
986 ReqSfixed64: scalar.Int64(0xbeefcafe),
987 ReqString: scalar.String("hello"),
988 ReqEnum: pb2.Enum_ONE.Enum(),
989 },
990 }, {
991 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800992 inputMessage: &pb2.Requireds{},
993 inputText: `
994req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800995req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800996req_double: 0
997req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800998req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800999req_nested: {}
1000`,
1001 wantMessage: &pb2.Requireds{
1002 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001003 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001004 ReqDouble: scalar.Float64(0),
1005 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001006 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001007 ReqNested: &pb2.Nested{},
1008 },
1009 }, {
1010 desc: "indirect required field",
1011 inputMessage: &pb2.IndirectRequired{},
1012 inputText: "opt_nested: {}",
1013 wantMessage: &pb2.IndirectRequired{
1014 OptNested: &pb2.NestedWithRequired{},
1015 },
1016 wantErr: true,
1017 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001018 desc: "indirect required field with AllowPartial",
1019 umo: textpb.UnmarshalOptions{AllowPartial: true},
1020 inputMessage: &pb2.IndirectRequired{},
1021 inputText: "opt_nested: {}",
1022 wantMessage: &pb2.IndirectRequired{
1023 OptNested: &pb2.NestedWithRequired{},
1024 },
1025 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001026 desc: "indirect required field in repeated",
1027 inputMessage: &pb2.IndirectRequired{},
1028 inputText: `
1029rpt_nested: {
1030 req_string: "one"
1031}
1032rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001033`,
1034 wantMessage: &pb2.IndirectRequired{
1035 RptNested: []*pb2.NestedWithRequired{
1036 {
1037 ReqString: scalar.String("one"),
1038 },
1039 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001040 },
1041 },
1042 wantErr: true,
1043 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001044 desc: "indirect required field in repeated with AllowPartial",
1045 umo: textpb.UnmarshalOptions{AllowPartial: true},
1046 inputMessage: &pb2.IndirectRequired{},
1047 inputText: `
1048rpt_nested: {
1049 req_string: "one"
1050}
1051rpt_nested: {}
1052`,
1053 wantMessage: &pb2.IndirectRequired{
1054 RptNested: []*pb2.NestedWithRequired{
1055 {
1056 ReqString: scalar.String("one"),
1057 },
1058 {},
1059 },
1060 },
1061 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001062 desc: "indirect required field in map",
1063 inputMessage: &pb2.IndirectRequired{},
1064 inputText: `
1065str_to_nested: {
1066 key: "missing"
1067}
1068str_to_nested: {
1069 key: "contains"
1070 value: {
1071 req_string: "here"
1072 }
1073}
1074`,
1075 wantMessage: &pb2.IndirectRequired{
1076 StrToNested: map[string]*pb2.NestedWithRequired{
1077 "missing": &pb2.NestedWithRequired{},
1078 "contains": &pb2.NestedWithRequired{
1079 ReqString: scalar.String("here"),
1080 },
1081 },
1082 },
1083 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001084 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001085 desc: "indirect required field in map with AllowPartial",
1086 umo: textpb.UnmarshalOptions{AllowPartial: true},
1087 inputMessage: &pb2.IndirectRequired{},
1088 inputText: `
1089str_to_nested: {
1090 key: "missing"
1091}
1092str_to_nested: {
1093 key: "contains"
1094 value: {
1095 req_string: "here"
1096 }
1097}
1098`,
1099 wantMessage: &pb2.IndirectRequired{
1100 StrToNested: map[string]*pb2.NestedWithRequired{
1101 "missing": &pb2.NestedWithRequired{},
1102 "contains": &pb2.NestedWithRequired{
1103 ReqString: scalar.String("here"),
1104 },
1105 },
1106 },
1107 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001108 desc: "indirect required field in oneof",
1109 inputMessage: &pb2.IndirectRequired{},
1110 inputText: `oneof_nested: {}
1111`,
1112 wantMessage: &pb2.IndirectRequired{
1113 Union: &pb2.IndirectRequired_OneofNested{
1114 OneofNested: &pb2.NestedWithRequired{},
1115 },
1116 },
1117 wantErr: true,
1118 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001119 desc: "indirect required field in oneof with AllowPartial",
1120 umo: textpb.UnmarshalOptions{AllowPartial: true},
1121 inputMessage: &pb2.IndirectRequired{},
1122 inputText: `oneof_nested: {}
1123`,
1124 wantMessage: &pb2.IndirectRequired{
1125 Union: &pb2.IndirectRequired_OneofNested{
1126 OneofNested: &pb2.NestedWithRequired{},
1127 },
1128 },
1129 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001130 desc: "ignore reserved field",
1131 inputMessage: &pb2.Nests{},
1132 inputText: "reserved_field: 'ignore this'",
1133 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001134 }, {
1135 desc: "extensions of non-repeated fields",
1136 inputMessage: &pb2.Extensions{},
1137 inputText: `opt_string: "non-extension field"
1138[pb2.opt_ext_bool]: true
1139opt_bool: true
1140[pb2.opt_ext_nested]: {
1141 opt_string: "nested in an extension"
1142 opt_nested: {
1143 opt_string: "another nested in an extension"
1144 }
1145}
1146[pb2.opt_ext_string]: "extension field"
1147opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001148[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001149`,
1150 wantMessage: func() proto.Message {
1151 m := &pb2.Extensions{
1152 OptString: scalar.String("non-extension field"),
1153 OptBool: scalar.Bool(true),
1154 OptInt32: scalar.Int32(42),
1155 }
1156 setExtension(m, pb2.E_OptExtBool, true)
1157 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001158 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001159 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1160 OptString: scalar.String("nested in an extension"),
1161 OptNested: &pb2.Nested{
1162 OptString: scalar.String("another nested in an extension"),
1163 },
1164 })
1165 return m
1166 }(),
1167 }, {
1168 desc: "extensions of repeated fields",
1169 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001170 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001171[pb2.rpt_ext_enum]: 101
1172[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001173[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001174[pb2.rpt_ext_nested]: {
1175 opt_string: "one"
1176}
1177[pb2.rpt_ext_nested]: {
1178 opt_string: "two"
1179}
1180[pb2.rpt_ext_fixed32]: 47
1181[pb2.rpt_ext_nested]: {
1182 opt_string: "three"
1183}
1184`,
1185 wantMessage: func() proto.Message {
1186 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001187 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001188 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1189 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1190 &pb2.Nested{OptString: scalar.String("one")},
1191 &pb2.Nested{OptString: scalar.String("two")},
1192 &pb2.Nested{OptString: scalar.String("three")},
1193 })
1194 return m
1195 }(),
1196 }, {
1197 desc: "extensions of non-repeated fields in another message",
1198 inputMessage: &pb2.Extensions{},
1199 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001200[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001201[pb2.ExtensionsContainer.opt_ext_nested]: {
1202 opt_string: "nested in an extension"
1203 opt_nested: {
1204 opt_string: "another nested in an extension"
1205 }
1206}
1207[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1208`,
1209 wantMessage: func() proto.Message {
1210 m := &pb2.Extensions{}
1211 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1212 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001213 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001214 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1215 OptString: scalar.String("nested in an extension"),
1216 OptNested: &pb2.Nested{
1217 OptString: scalar.String("another nested in an extension"),
1218 },
1219 })
1220 return m
1221 }(),
1222 }, {
1223 desc: "extensions of repeated fields in another message",
1224 inputMessage: &pb2.Extensions{},
1225 inputText: `opt_string: "non-extension field"
1226opt_bool: true
1227opt_int32: 42
1228[pb2.ExtensionsContainer.rpt_ext_nested]: {
1229 opt_string: "one"
1230}
Herbie Ong8170d692019-02-13 14:13:21 -08001231[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001232[pb2.ExtensionsContainer.rpt_ext_nested]: {
1233 opt_string: "two"
1234}
1235[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1236[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001237[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001238[pb2.ExtensionsContainer.rpt_ext_nested]: {
1239 opt_string: "three"
1240}
1241[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1242`,
1243 wantMessage: func() proto.Message {
1244 m := &pb2.Extensions{
1245 OptString: scalar.String("non-extension field"),
1246 OptBool: scalar.Bool(true),
1247 OptInt32: scalar.Int32(42),
1248 }
Herbie Ong8170d692019-02-13 14:13:21 -08001249 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001250 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1251 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1252 &pb2.Nested{OptString: scalar.String("one")},
1253 &pb2.Nested{OptString: scalar.String("two")},
1254 &pb2.Nested{OptString: scalar.String("three")},
1255 })
1256 return m
1257 }(),
1258 }, {
1259 desc: "invalid extension field name",
1260 inputMessage: &pb2.Extensions{},
1261 inputText: "[pb2.invalid_message_field]: true",
1262 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001263 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001264 desc: "MessageSet",
1265 inputMessage: &pb2.MessageSet{},
1266 inputText: `
1267[pb2.MessageSetExtension]: {
1268 opt_string: "a messageset extension"
1269}
1270[pb2.MessageSetExtension.ext_nested]: {
1271 opt_string: "just a regular extension"
1272}
1273[pb2.MessageSetExtension.not_message_set_extension]: {
1274 opt_string: "not a messageset extension"
1275}
1276`,
1277 wantMessage: func() proto.Message {
1278 m := &pb2.MessageSet{}
1279 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1280 OptString: scalar.String("a messageset extension"),
1281 })
1282 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1283 OptString: scalar.String("not a messageset extension"),
1284 })
1285 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1286 OptString: scalar.String("just a regular extension"),
1287 })
1288 return m
1289 }(),
1290 }, {
1291 desc: "not real MessageSet 1",
1292 inputMessage: &pb2.FakeMessageSet{},
1293 inputText: `
1294[pb2.FakeMessageSetExtension.message_set_extension]: {
1295 opt_string: "not a messageset extension"
1296}
1297`,
1298 wantMessage: func() proto.Message {
1299 m := &pb2.FakeMessageSet{}
1300 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1301 OptString: scalar.String("not a messageset extension"),
1302 })
1303 return m
1304 }(),
1305 }, {
1306 desc: "not real MessageSet 2",
1307 inputMessage: &pb2.FakeMessageSet{},
1308 inputText: `
1309[pb2.FakeMessageSetExtension]: {
1310 opt_string: "not a messageset extension"
1311}
1312`,
1313 wantErr: true,
1314 }, {
1315 desc: "not real MessageSet 3",
1316 inputMessage: &pb2.MessageSet{},
1317 inputText: `
1318[pb2.message_set_extension]: {
1319 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001320}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001321 wantMessage: func() proto.Message {
1322 m := &pb2.MessageSet{}
1323 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1324 OptString: scalar.String("another not a messageset extension"),
1325 })
1326 return m
1327 }(),
1328 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001329 desc: "Any not expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001330 inputMessage: &knownpb.Any{},
1331 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001332type_url: "pb2.Nested"
1333value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001334`,
Herbie Ong300cff02019-03-20 18:05:16 -07001335 wantMessage: &knownpb.Any{
1336 TypeUrl: "pb2.Nested",
1337 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001338 },
1339 }, {
1340 desc: "Any not expanded missing value",
Herbie Ong300cff02019-03-20 18:05:16 -07001341 inputMessage: &knownpb.Any{},
1342 inputText: `type_url: "pb2.Nested"`,
1343 wantMessage: &knownpb.Any{
1344 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001345 },
1346 }, {
1347 desc: "Any not expanded missing type_url",
Herbie Ong300cff02019-03-20 18:05:16 -07001348 inputMessage: &knownpb.Any{},
1349 inputText: `value: "some bytes"`,
1350 wantMessage: &knownpb.Any{
1351 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001352 },
1353 }, {
1354 desc: "Any expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001355 umo: textpb.UnmarshalOptions{
1356 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1357 },
1358 inputMessage: &knownpb.Any{},
1359 inputText: `
1360[foobar/pb2.Nested]: {
1361 opt_string: "embedded inside Any"
1362 opt_nested: {
1363 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001364 }
1365}
1366`,
1367 wantMessage: func() proto.Message {
1368 m := &pb2.Nested{
1369 OptString: scalar.String("embedded inside Any"),
1370 OptNested: &pb2.Nested{
1371 OptString: scalar.String("inception"),
1372 },
1373 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001374 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001375 if err != nil {
1376 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1377 }
Herbie Ong300cff02019-03-20 18:05:16 -07001378 return &knownpb.Any{
1379 TypeUrl: "foobar/pb2.Nested",
1380 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001381 }
1382 }(),
1383 }, {
1384 desc: "Any expanded with empty value",
Herbie Ong300cff02019-03-20 18:05:16 -07001385 umo: textpb.UnmarshalOptions{
1386 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1387 },
1388 inputMessage: &knownpb.Any{},
1389 inputText: `[foo.com/pb2.Nested]: {}`,
1390 wantMessage: &knownpb.Any{
1391 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001392 },
1393 }, {
1394 desc: "Any expanded with missing required error",
Herbie Ong300cff02019-03-20 18:05:16 -07001395 umo: textpb.UnmarshalOptions{
1396 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
1397 },
1398 inputMessage: &knownpb.Any{},
1399 inputText: `
1400[pb2.PartialRequired]: {
1401 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001402}
1403`,
1404 wantMessage: func() proto.Message {
1405 m := &pb2.PartialRequired{
1406 OptString: scalar.String("embedded inside Any"),
1407 }
Herbie Ong300cff02019-03-20 18:05:16 -07001408 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1409 // TODO: Marshal may fail due to required field not set at some
1410 // point. Need to ignore required not set error here.
1411 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001412 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1413 }
Herbie Ong300cff02019-03-20 18:05:16 -07001414 return &knownpb.Any{
1415 TypeUrl: "pb2.PartialRequired",
1416 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001417 }
1418 }(),
1419 wantErr: true,
1420 }, {
1421 desc: "Any expanded with unregistered type",
1422 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
Herbie Ong300cff02019-03-20 18:05:16 -07001423 inputMessage: &knownpb.Any{},
1424 inputText: `[SomeMessage]: {}`,
1425 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001426 }, {
1427 desc: "Any expanded with invalid value",
Herbie Ong300cff02019-03-20 18:05:16 -07001428 umo: textpb.UnmarshalOptions{
1429 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1430 },
1431 inputMessage: &knownpb.Any{},
1432 inputText: `[pb2.Nested]: 123`,
1433 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001434 }, {
1435 desc: "Any expanded with unknown fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001436 umo: textpb.UnmarshalOptions{
1437 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1438 },
1439 inputMessage: &knownpb.Any{},
1440 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001441[pb2.Nested]: {}
1442unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001443`,
1444 wantErr: true,
1445 }, {
1446 desc: "Any contains expanded and unexpanded fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001447 umo: textpb.UnmarshalOptions{
1448 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1449 },
1450 inputMessage: &knownpb.Any{},
1451 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001452[pb2.Nested]: {}
1453type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001454`,
1455 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001456 }}
1457
1458 for _, tt := range tests {
1459 tt := tt
1460 t.Run(tt.desc, func(t *testing.T) {
1461 t.Parallel()
Herbie Ong66c365c2019-01-04 14:08:41 -08001462 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001463 if err != nil && !tt.wantErr {
1464 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1465 }
1466 if err == nil && tt.wantErr {
1467 t.Error("Unmarshal() got nil error, want error\n\n")
1468 }
Herbie Ong70651952018-12-13 14:19:50 -08001469 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001470 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1471 }
1472 })
1473 }
1474}