1// Copyright 2019 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 proto_test
6
7import (
8	"google.golang.org/protobuf/encoding/protowire"
9	"google.golang.org/protobuf/internal/impl"
10	"google.golang.org/protobuf/internal/protobuild"
11	"google.golang.org/protobuf/proto"
12	"google.golang.org/protobuf/reflect/protoreflect"
13	"google.golang.org/protobuf/reflect/protoregistry"
14	"google.golang.org/protobuf/testing/protopack"
15
16	legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
17	requiredpb "google.golang.org/protobuf/internal/testprotos/required"
18	testpb "google.golang.org/protobuf/internal/testprotos/test"
19	test3pb "google.golang.org/protobuf/internal/testprotos/test3"
20)
21
22type testProto struct {
23	desc             string
24	decodeTo         []proto.Message
25	wire             []byte
26	partial          bool
27	noEncode         bool
28	checkFastInit    bool
29	unmarshalOptions proto.UnmarshalOptions
30	validationStatus impl.ValidationStatus
31	nocheckValidInit bool
32}
33
34func makeMessages(in protobuild.Message, messages ...proto.Message) []proto.Message {
35	if len(messages) == 0 {
36		messages = []proto.Message{
37			&testpb.TestAllTypes{},
38			&test3pb.TestAllTypes{},
39			&testpb.TestAllExtensions{},
40		}
41	}
42	for _, m := range messages {
43		in.Build(m.ProtoReflect())
44	}
45	return messages
46}
47
48func templateMessages(messages ...proto.Message) []protoreflect.MessageType {
49	if len(messages) == 0 {
50		messages = []proto.Message{
51			(*testpb.TestAllTypes)(nil),
52			(*test3pb.TestAllTypes)(nil),
53			(*testpb.TestAllExtensions)(nil),
54		}
55	}
56	var out []protoreflect.MessageType
57	for _, m := range messages {
58		out = append(out, m.ProtoReflect().Type())
59	}
60	return out
61
62}
63
64var testValidMessages = []testProto{
65	{
66		desc:          "basic scalar types",
67		checkFastInit: true,
68		decodeTo: makeMessages(protobuild.Message{
69			"optional_int32":       1001,
70			"optional_int64":       1002,
71			"optional_uint32":      1003,
72			"optional_uint64":      1004,
73			"optional_sint32":      1005,
74			"optional_sint64":      1006,
75			"optional_fixed32":     1007,
76			"optional_fixed64":     1008,
77			"optional_sfixed32":    1009,
78			"optional_sfixed64":    1010,
79			"optional_float":       1011.5,
80			"optional_double":      1012.5,
81			"optional_bool":        true,
82			"optional_string":      "string",
83			"optional_bytes":       []byte("bytes"),
84			"optional_nested_enum": "BAR",
85		}),
86		wire: protopack.Message{
87			protopack.Tag{1, protopack.VarintType}, protopack.Varint(1001),
88			protopack.Tag{2, protopack.VarintType}, protopack.Varint(1002),
89			protopack.Tag{3, protopack.VarintType}, protopack.Uvarint(1003),
90			protopack.Tag{4, protopack.VarintType}, protopack.Uvarint(1004),
91			protopack.Tag{5, protopack.VarintType}, protopack.Svarint(1005),
92			protopack.Tag{6, protopack.VarintType}, protopack.Svarint(1006),
93			protopack.Tag{7, protopack.Fixed32Type}, protopack.Uint32(1007),
94			protopack.Tag{8, protopack.Fixed64Type}, protopack.Uint64(1008),
95			protopack.Tag{9, protopack.Fixed32Type}, protopack.Int32(1009),
96			protopack.Tag{10, protopack.Fixed64Type}, protopack.Int64(1010),
97			protopack.Tag{11, protopack.Fixed32Type}, protopack.Float32(1011.5),
98			protopack.Tag{12, protopack.Fixed64Type}, protopack.Float64(1012.5),
99			protopack.Tag{13, protopack.VarintType}, protopack.Bool(true),
100			protopack.Tag{14, protopack.BytesType}, protopack.String("string"),
101			protopack.Tag{15, protopack.BytesType}, protopack.Bytes([]byte("bytes")),
102			protopack.Tag{21, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_BAR)),
103		}.Marshal(),
104	},
105	{
106		desc: "zero values",
107		decodeTo: makeMessages(protobuild.Message{
108			"optional_int32":    0,
109			"optional_int64":    0,
110			"optional_uint32":   0,
111			"optional_uint64":   0,
112			"optional_sint32":   0,
113			"optional_sint64":   0,
114			"optional_fixed32":  0,
115			"optional_fixed64":  0,
116			"optional_sfixed32": 0,
117			"optional_sfixed64": 0,
118			"optional_float":    0,
119			"optional_double":   0,
120			"optional_bool":     false,
121			"optional_string":   "",
122			"optional_bytes":    []byte{},
123		}),
124		wire: protopack.Message{
125			protopack.Tag{1, protopack.VarintType}, protopack.Varint(0),
126			protopack.Tag{2, protopack.VarintType}, protopack.Varint(0),
127			protopack.Tag{3, protopack.VarintType}, protopack.Uvarint(0),
128			protopack.Tag{4, protopack.VarintType}, protopack.Uvarint(0),
129			protopack.Tag{5, protopack.VarintType}, protopack.Svarint(0),
130			protopack.Tag{6, protopack.VarintType}, protopack.Svarint(0),
131			protopack.Tag{7, protopack.Fixed32Type}, protopack.Uint32(0),
132			protopack.Tag{8, protopack.Fixed64Type}, protopack.Uint64(0),
133			protopack.Tag{9, protopack.Fixed32Type}, protopack.Int32(0),
134			protopack.Tag{10, protopack.Fixed64Type}, protopack.Int64(0),
135			protopack.Tag{11, protopack.Fixed32Type}, protopack.Float32(0),
136			protopack.Tag{12, protopack.Fixed64Type}, protopack.Float64(0),
137			protopack.Tag{13, protopack.VarintType}, protopack.Bool(false),
138			protopack.Tag{14, protopack.BytesType}, protopack.String(""),
139			protopack.Tag{15, protopack.BytesType}, protopack.Bytes(nil),
140		}.Marshal(),
141	},
142	{
143		desc: "proto3 zero values",
144		decodeTo: makeMessages(protobuild.Message{
145			"singular_int32":    0,
146			"singular_int64":    0,
147			"singular_uint32":   0,
148			"singular_uint64":   0,
149			"singular_sint32":   0,
150			"singular_sint64":   0,
151			"singular_fixed32":  0,
152			"singular_fixed64":  0,
153			"singular_sfixed32": 0,
154			"singular_sfixed64": 0,
155			"singular_float":    0,
156			"singular_double":   0,
157			"singular_bool":     false,
158			"singular_string":   "",
159			"singular_bytes":    []byte{},
160		}, &test3pb.TestAllTypes{}),
161		wire: protopack.Message{
162			protopack.Tag{81, protopack.VarintType}, protopack.Varint(0),
163			protopack.Tag{82, protopack.VarintType}, protopack.Varint(0),
164			protopack.Tag{83, protopack.VarintType}, protopack.Uvarint(0),
165			protopack.Tag{84, protopack.VarintType}, protopack.Uvarint(0),
166			protopack.Tag{85, protopack.VarintType}, protopack.Svarint(0),
167			protopack.Tag{86, protopack.VarintType}, protopack.Svarint(0),
168			protopack.Tag{87, protopack.Fixed32Type}, protopack.Uint32(0),
169			protopack.Tag{88, protopack.Fixed64Type}, protopack.Uint64(0),
170			protopack.Tag{89, protopack.Fixed32Type}, protopack.Int32(0),
171			protopack.Tag{90, protopack.Fixed64Type}, protopack.Int64(0),
172			protopack.Tag{91, protopack.Fixed32Type}, protopack.Float32(0),
173			protopack.Tag{92, protopack.Fixed64Type}, protopack.Float64(0),
174			protopack.Tag{93, protopack.VarintType}, protopack.Bool(false),
175			protopack.Tag{94, protopack.BytesType}, protopack.String(""),
176			protopack.Tag{95, protopack.BytesType}, protopack.Bytes(nil),
177		}.Marshal(),
178	},
179	{
180		desc: "groups",
181		decodeTo: makeMessages(protobuild.Message{
182			"optionalgroup": protobuild.Message{
183				"a":                 1017,
184				"same_field_number": 1016,
185			},
186		}, &testpb.TestAllTypes{}, &testpb.TestAllExtensions{}),
187		wire: protopack.Message{
188			protopack.Tag{16, protopack.StartGroupType},
189			protopack.Tag{17, protopack.VarintType}, protopack.Varint(1017),
190			protopack.Tag{16, protopack.VarintType}, protopack.Varint(1016),
191			protopack.Tag{16, protopack.EndGroupType},
192		}.Marshal(),
193	},
194	{
195		desc: "groups (field overridden)",
196		decodeTo: makeMessages(protobuild.Message{
197			"optionalgroup": protobuild.Message{
198				"a": 2,
199			},
200		}, &testpb.TestAllTypes{}, &testpb.TestAllExtensions{}),
201		wire: protopack.Message{
202			protopack.Tag{16, protopack.StartGroupType},
203			protopack.Tag{17, protopack.VarintType}, protopack.Varint(1),
204			protopack.Tag{16, protopack.EndGroupType},
205			protopack.Tag{16, protopack.StartGroupType},
206			protopack.Tag{17, protopack.VarintType}, protopack.Varint(2),
207			protopack.Tag{16, protopack.EndGroupType},
208		}.Marshal(),
209	},
210	{
211		desc: "messages",
212		decodeTo: makeMessages(protobuild.Message{
213			"optional_nested_message": protobuild.Message{
214				"a": 42,
215				"corecursive": protobuild.Message{
216					"optional_int32": 43,
217				},
218			},
219		}),
220		wire: protopack.Message{
221			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
222				protopack.Tag{1, protopack.VarintType}, protopack.Varint(42),
223				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
224					protopack.Tag{1, protopack.VarintType}, protopack.Varint(43),
225				}),
226			}),
227		}.Marshal(),
228	},
229	{
230		desc: "messages (split across multiple tags)",
231		decodeTo: makeMessages(protobuild.Message{
232			"optional_nested_message": protobuild.Message{
233				"a": 42,
234				"corecursive": protobuild.Message{
235					"optional_int32": 43,
236				},
237			},
238		}),
239		wire: protopack.Message{
240			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
241				protopack.Tag{1, protopack.VarintType}, protopack.Varint(42),
242			}),
243			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
244				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
245					protopack.Tag{1, protopack.VarintType}, protopack.Varint(43),
246				}),
247			}),
248		}.Marshal(),
249	},
250	{
251		desc: "messages (field overridden)",
252		decodeTo: makeMessages(protobuild.Message{
253			"optional_nested_message": protobuild.Message{
254				"a": 2,
255			},
256		}),
257		wire: protopack.Message{
258			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
259				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
260			}),
261			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
262				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
263			}),
264		}.Marshal(),
265	},
266	{
267		desc: "basic repeated types",
268		decodeTo: makeMessages(protobuild.Message{
269			"repeated_int32":       []int32{1001, 2001},
270			"repeated_int64":       []int64{1002, 2002},
271			"repeated_uint32":      []uint32{1003, 2003},
272			"repeated_uint64":      []uint64{1004, 2004},
273			"repeated_sint32":      []int32{1005, 2005},
274			"repeated_sint64":      []int64{1006, 2006},
275			"repeated_fixed32":     []uint32{1007, 2007},
276			"repeated_fixed64":     []uint64{1008, 2008},
277			"repeated_sfixed32":    []int32{1009, 2009},
278			"repeated_sfixed64":    []int64{1010, 2010},
279			"repeated_float":       []float32{1011.5, 2011.5},
280			"repeated_double":      []float64{1012.5, 2012.5},
281			"repeated_bool":        []bool{true, false},
282			"repeated_string":      []string{"foo", "bar"},
283			"repeated_bytes":       []string{"FOO", "BAR"},
284			"repeated_nested_enum": []string{"FOO", "BAR"},
285		}),
286		wire: protopack.Message{
287			protopack.Tag{31, protopack.VarintType}, protopack.Varint(1001),
288			protopack.Tag{31, protopack.VarintType}, protopack.Varint(2001),
289			protopack.Tag{32, protopack.VarintType}, protopack.Varint(1002),
290			protopack.Tag{32, protopack.VarintType}, protopack.Varint(2002),
291			protopack.Tag{33, protopack.VarintType}, protopack.Uvarint(1003),
292			protopack.Tag{33, protopack.VarintType}, protopack.Uvarint(2003),
293			protopack.Tag{34, protopack.VarintType}, protopack.Uvarint(1004),
294			protopack.Tag{34, protopack.VarintType}, protopack.Uvarint(2004),
295			protopack.Tag{35, protopack.VarintType}, protopack.Svarint(1005),
296			protopack.Tag{35, protopack.VarintType}, protopack.Svarint(2005),
297			protopack.Tag{36, protopack.VarintType}, protopack.Svarint(1006),
298			protopack.Tag{36, protopack.VarintType}, protopack.Svarint(2006),
299			protopack.Tag{37, protopack.Fixed32Type}, protopack.Uint32(1007),
300			protopack.Tag{37, protopack.Fixed32Type}, protopack.Uint32(2007),
301			protopack.Tag{38, protopack.Fixed64Type}, protopack.Uint64(1008),
302			protopack.Tag{38, protopack.Fixed64Type}, protopack.Uint64(2008),
303			protopack.Tag{39, protopack.Fixed32Type}, protopack.Int32(1009),
304			protopack.Tag{39, protopack.Fixed32Type}, protopack.Int32(2009),
305			protopack.Tag{40, protopack.Fixed64Type}, protopack.Int64(1010),
306			protopack.Tag{40, protopack.Fixed64Type}, protopack.Int64(2010),
307			protopack.Tag{41, protopack.Fixed32Type}, protopack.Float32(1011.5),
308			protopack.Tag{41, protopack.Fixed32Type}, protopack.Float32(2011.5),
309			protopack.Tag{42, protopack.Fixed64Type}, protopack.Float64(1012.5),
310			protopack.Tag{42, protopack.Fixed64Type}, protopack.Float64(2012.5),
311			protopack.Tag{43, protopack.VarintType}, protopack.Bool(true),
312			protopack.Tag{43, protopack.VarintType}, protopack.Bool(false),
313			protopack.Tag{44, protopack.BytesType}, protopack.String("foo"),
314			protopack.Tag{44, protopack.BytesType}, protopack.String("bar"),
315			protopack.Tag{45, protopack.BytesType}, protopack.Bytes([]byte("FOO")),
316			protopack.Tag{45, protopack.BytesType}, protopack.Bytes([]byte("BAR")),
317			protopack.Tag{51, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_FOO)),
318			protopack.Tag{51, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_BAR)),
319		}.Marshal(),
320	},
321	{
322		desc: "basic repeated types (packed encoding)",
323		decodeTo: makeMessages(protobuild.Message{
324			"repeated_int32":       []int32{1001, 2001},
325			"repeated_int64":       []int64{1002, 2002},
326			"repeated_uint32":      []uint32{1003, 2003},
327			"repeated_uint64":      []uint64{1004, 2004},
328			"repeated_sint32":      []int32{1005, 2005},
329			"repeated_sint64":      []int64{1006, 2006},
330			"repeated_fixed32":     []uint32{1007, 2007},
331			"repeated_fixed64":     []uint64{1008, 2008},
332			"repeated_sfixed32":    []int32{1009, 2009},
333			"repeated_sfixed64":    []int64{1010, 2010},
334			"repeated_float":       []float32{1011.5, 2011.5},
335			"repeated_double":      []float64{1012.5, 2012.5},
336			"repeated_bool":        []bool{true, false},
337			"repeated_nested_enum": []string{"FOO", "BAR"},
338		}),
339		wire: protopack.Message{
340			protopack.Tag{31, protopack.BytesType}, protopack.LengthPrefix{
341				protopack.Varint(1001), protopack.Varint(2001),
342			},
343			protopack.Tag{32, protopack.BytesType}, protopack.LengthPrefix{
344				protopack.Varint(1002), protopack.Varint(2002),
345			},
346			protopack.Tag{33, protopack.BytesType}, protopack.LengthPrefix{
347				protopack.Uvarint(1003), protopack.Uvarint(2003),
348			},
349			protopack.Tag{34, protopack.BytesType}, protopack.LengthPrefix{
350				protopack.Uvarint(1004), protopack.Uvarint(2004),
351			},
352			protopack.Tag{35, protopack.BytesType}, protopack.LengthPrefix{
353				protopack.Svarint(1005), protopack.Svarint(2005),
354			},
355			protopack.Tag{36, protopack.BytesType}, protopack.LengthPrefix{
356				protopack.Svarint(1006), protopack.Svarint(2006),
357			},
358			protopack.Tag{37, protopack.BytesType}, protopack.LengthPrefix{
359				protopack.Uint32(1007), protopack.Uint32(2007),
360			},
361			protopack.Tag{38, protopack.BytesType}, protopack.LengthPrefix{
362				protopack.Uint64(1008), protopack.Uint64(2008),
363			},
364			protopack.Tag{39, protopack.BytesType}, protopack.LengthPrefix{
365				protopack.Int32(1009), protopack.Int32(2009),
366			},
367			protopack.Tag{40, protopack.BytesType}, protopack.LengthPrefix{
368				protopack.Int64(1010), protopack.Int64(2010),
369			},
370			protopack.Tag{41, protopack.BytesType}, protopack.LengthPrefix{
371				protopack.Float32(1011.5), protopack.Float32(2011.5),
372			},
373			protopack.Tag{42, protopack.BytesType}, protopack.LengthPrefix{
374				protopack.Float64(1012.5), protopack.Float64(2012.5),
375			},
376			protopack.Tag{43, protopack.BytesType}, protopack.LengthPrefix{
377				protopack.Bool(true), protopack.Bool(false),
378			},
379			protopack.Tag{51, protopack.BytesType}, protopack.LengthPrefix{
380				protopack.Varint(int(testpb.TestAllTypes_FOO)),
381				protopack.Varint(int(testpb.TestAllTypes_BAR)),
382			},
383		}.Marshal(),
384	},
385	{
386		desc: "basic repeated types (zero-length packed encoding)",
387		decodeTo: makeMessages(protobuild.Message{
388			"repeated_int32":       []int32{},
389			"repeated_int64":       []int64{},
390			"repeated_uint32":      []uint32{},
391			"repeated_uint64":      []uint64{},
392			"repeated_sint32":      []int32{},
393			"repeated_sint64":      []int64{},
394			"repeated_fixed32":     []uint32{},
395			"repeated_fixed64":     []uint64{},
396			"repeated_sfixed32":    []int32{},
397			"repeated_sfixed64":    []int64{},
398			"repeated_float":       []float32{},
399			"repeated_double":      []float64{},
400			"repeated_bool":        []bool{},
401			"repeated_nested_enum": []string{},
402		}),
403		wire: protopack.Message{
404			protopack.Tag{31, protopack.BytesType}, protopack.LengthPrefix{},
405			protopack.Tag{32, protopack.BytesType}, protopack.LengthPrefix{},
406			protopack.Tag{33, protopack.BytesType}, protopack.LengthPrefix{},
407			protopack.Tag{34, protopack.BytesType}, protopack.LengthPrefix{},
408			protopack.Tag{35, protopack.BytesType}, protopack.LengthPrefix{},
409			protopack.Tag{36, protopack.BytesType}, protopack.LengthPrefix{},
410			protopack.Tag{37, protopack.BytesType}, protopack.LengthPrefix{},
411			protopack.Tag{38, protopack.BytesType}, protopack.LengthPrefix{},
412			protopack.Tag{39, protopack.BytesType}, protopack.LengthPrefix{},
413			protopack.Tag{40, protopack.BytesType}, protopack.LengthPrefix{},
414			protopack.Tag{41, protopack.BytesType}, protopack.LengthPrefix{},
415			protopack.Tag{42, protopack.BytesType}, protopack.LengthPrefix{},
416			protopack.Tag{43, protopack.BytesType}, protopack.LengthPrefix{},
417			protopack.Tag{51, protopack.BytesType}, protopack.LengthPrefix{},
418		}.Marshal(),
419	},
420	{
421		desc: "packed repeated types",
422		decodeTo: makeMessages(protobuild.Message{
423			"packed_int32":    []int32{1001, 2001},
424			"packed_int64":    []int64{1002, 2002},
425			"packed_uint32":   []uint32{1003, 2003},
426			"packed_uint64":   []uint64{1004, 2004},
427			"packed_sint32":   []int32{1005, 2005},
428			"packed_sint64":   []int64{1006, 2006},
429			"packed_fixed32":  []uint32{1007, 2007},
430			"packed_fixed64":  []uint64{1008, 2008},
431			"packed_sfixed32": []int32{1009, 2009},
432			"packed_sfixed64": []int64{1010, 2010},
433			"packed_float":    []float32{1011.5, 2011.5},
434			"packed_double":   []float64{1012.5, 2012.5},
435			"packed_bool":     []bool{true, false},
436			"packed_enum":     []string{"FOREIGN_FOO", "FOREIGN_BAR"},
437		}, &testpb.TestPackedTypes{}, &testpb.TestPackedExtensions{}),
438		wire: protopack.Message{
439			protopack.Tag{90, protopack.BytesType}, protopack.LengthPrefix{
440				protopack.Varint(1001), protopack.Varint(2001),
441			},
442			protopack.Tag{91, protopack.BytesType}, protopack.LengthPrefix{
443				protopack.Varint(1002), protopack.Varint(2002),
444			},
445			protopack.Tag{92, protopack.BytesType}, protopack.LengthPrefix{
446				protopack.Uvarint(1003), protopack.Uvarint(2003),
447			},
448			protopack.Tag{93, protopack.BytesType}, protopack.LengthPrefix{
449				protopack.Uvarint(1004), protopack.Uvarint(2004),
450			},
451			protopack.Tag{94, protopack.BytesType}, protopack.LengthPrefix{
452				protopack.Svarint(1005), protopack.Svarint(2005),
453			},
454			protopack.Tag{95, protopack.BytesType}, protopack.LengthPrefix{
455				protopack.Svarint(1006), protopack.Svarint(2006),
456			},
457			protopack.Tag{96, protopack.BytesType}, protopack.LengthPrefix{
458				protopack.Uint32(1007), protopack.Uint32(2007),
459			},
460			protopack.Tag{97, protopack.BytesType}, protopack.LengthPrefix{
461				protopack.Uint64(1008), protopack.Uint64(2008),
462			},
463			protopack.Tag{98, protopack.BytesType}, protopack.LengthPrefix{
464				protopack.Int32(1009), protopack.Int32(2009),
465			},
466			protopack.Tag{99, protopack.BytesType}, protopack.LengthPrefix{
467				protopack.Int64(1010), protopack.Int64(2010),
468			},
469			protopack.Tag{100, protopack.BytesType}, protopack.LengthPrefix{
470				protopack.Float32(1011.5), protopack.Float32(2011.5),
471			},
472			protopack.Tag{101, protopack.BytesType}, protopack.LengthPrefix{
473				protopack.Float64(1012.5), protopack.Float64(2012.5),
474			},
475			protopack.Tag{102, protopack.BytesType}, protopack.LengthPrefix{
476				protopack.Bool(true), protopack.Bool(false),
477			},
478			protopack.Tag{103, protopack.BytesType}, protopack.LengthPrefix{
479				protopack.Varint(int(testpb.ForeignEnum_FOREIGN_FOO)),
480				protopack.Varint(int(testpb.ForeignEnum_FOREIGN_BAR)),
481			},
482		}.Marshal(),
483	},
484	{
485		desc: "packed repeated types (zero length)",
486		decodeTo: makeMessages(protobuild.Message{
487			"packed_int32":    []int32{},
488			"packed_int64":    []int64{},
489			"packed_uint32":   []uint32{},
490			"packed_uint64":   []uint64{},
491			"packed_sint32":   []int32{},
492			"packed_sint64":   []int64{},
493			"packed_fixed32":  []uint32{},
494			"packed_fixed64":  []uint64{},
495			"packed_sfixed32": []int32{},
496			"packed_sfixed64": []int64{},
497			"packed_float":    []float32{},
498			"packed_double":   []float64{},
499			"packed_bool":     []bool{},
500			"packed_enum":     []string{},
501		}, &testpb.TestPackedTypes{}, &testpb.TestPackedExtensions{}),
502		wire: protopack.Message{
503			protopack.Tag{90, protopack.BytesType}, protopack.LengthPrefix{},
504			protopack.Tag{91, protopack.BytesType}, protopack.LengthPrefix{},
505			protopack.Tag{92, protopack.BytesType}, protopack.LengthPrefix{},
506			protopack.Tag{93, protopack.BytesType}, protopack.LengthPrefix{},
507			protopack.Tag{94, protopack.BytesType}, protopack.LengthPrefix{},
508			protopack.Tag{95, protopack.BytesType}, protopack.LengthPrefix{},
509			protopack.Tag{96, protopack.BytesType}, protopack.LengthPrefix{},
510			protopack.Tag{97, protopack.BytesType}, protopack.LengthPrefix{},
511			protopack.Tag{98, protopack.BytesType}, protopack.LengthPrefix{},
512			protopack.Tag{99, protopack.BytesType}, protopack.LengthPrefix{},
513			protopack.Tag{100, protopack.BytesType}, protopack.LengthPrefix{},
514			protopack.Tag{101, protopack.BytesType}, protopack.LengthPrefix{},
515			protopack.Tag{102, protopack.BytesType}, protopack.LengthPrefix{},
516			protopack.Tag{103, protopack.BytesType}, protopack.LengthPrefix{},
517		}.Marshal(),
518	},
519	{
520		desc: "repeated messages",
521		decodeTo: makeMessages(protobuild.Message{
522			"repeated_nested_message": []protobuild.Message{
523				{"a": 1},
524				{},
525				{"a": 2},
526			},
527		}),
528		wire: protopack.Message{
529			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
530				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
531			}),
532			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
533			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
534				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
535			}),
536		}.Marshal(),
537	},
538	{
539		desc: "repeated nil messages",
540		decodeTo: []proto.Message{&testpb.TestAllTypes{
541			RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{
542				{A: proto.Int32(1)},
543				nil,
544				{A: proto.Int32(2)},
545			},
546		}, &test3pb.TestAllTypes{
547			RepeatedNestedMessage: []*test3pb.TestAllTypes_NestedMessage{
548				{A: 1},
549				nil,
550				{A: 2},
551			},
552		}, build(
553			&testpb.TestAllExtensions{},
554			extend(testpb.E_RepeatedNestedMessage, []*testpb.TestAllExtensions_NestedMessage{
555				{A: proto.Int32(1)},
556				nil,
557				{A: proto.Int32(2)},
558			}),
559		)},
560		wire: protopack.Message{
561			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
562				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
563			}),
564			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
565			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
566				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
567			}),
568		}.Marshal(),
569	},
570	{
571		desc: "repeated groups",
572		decodeTo: makeMessages(protobuild.Message{
573			"repeatedgroup": []protobuild.Message{
574				{"a": 1017},
575				{},
576				{"a": 2017},
577			},
578		}, &testpb.TestAllTypes{}, &testpb.TestAllExtensions{}),
579		wire: protopack.Message{
580			protopack.Tag{46, protopack.StartGroupType},
581			protopack.Tag{47, protopack.VarintType}, protopack.Varint(1017),
582			protopack.Tag{46, protopack.EndGroupType},
583			protopack.Tag{46, protopack.StartGroupType},
584			protopack.Tag{46, protopack.EndGroupType},
585			protopack.Tag{46, protopack.StartGroupType},
586			protopack.Tag{47, protopack.VarintType}, protopack.Varint(2017),
587			protopack.Tag{46, protopack.EndGroupType},
588		}.Marshal(),
589	},
590	{
591		desc: "repeated nil groups",
592		decodeTo: []proto.Message{&testpb.TestAllTypes{
593			Repeatedgroup: []*testpb.TestAllTypes_RepeatedGroup{
594				{A: proto.Int32(1017)},
595				nil,
596				{A: proto.Int32(2017)},
597			},
598		}, build(
599			&testpb.TestAllExtensions{},
600			extend(testpb.E_Repeatedgroup, []*testpb.RepeatedGroup{
601				{A: proto.Int32(1017)},
602				nil,
603				{A: proto.Int32(2017)},
604			}),
605		)},
606		wire: protopack.Message{
607			protopack.Tag{46, protopack.StartGroupType},
608			protopack.Tag{47, protopack.VarintType}, protopack.Varint(1017),
609			protopack.Tag{46, protopack.EndGroupType},
610			protopack.Tag{46, protopack.StartGroupType},
611			protopack.Tag{46, protopack.EndGroupType},
612			protopack.Tag{46, protopack.StartGroupType},
613			protopack.Tag{47, protopack.VarintType}, protopack.Varint(2017),
614			protopack.Tag{46, protopack.EndGroupType},
615		}.Marshal(),
616	},
617	{
618		desc: "maps",
619		decodeTo: makeMessages(protobuild.Message{
620			"map_int32_int32":       map[int32]int32{1056: 1156, 2056: 2156},
621			"map_int64_int64":       map[int64]int64{1057: 1157, 2057: 2157},
622			"map_uint32_uint32":     map[uint32]uint32{1058: 1158, 2058: 2158},
623			"map_uint64_uint64":     map[uint64]uint64{1059: 1159, 2059: 2159},
624			"map_sint32_sint32":     map[int32]int32{1060: 1160, 2060: 2160},
625			"map_sint64_sint64":     map[int64]int64{1061: 1161, 2061: 2161},
626			"map_fixed32_fixed32":   map[uint32]uint32{1062: 1162, 2062: 2162},
627			"map_fixed64_fixed64":   map[uint64]uint64{1063: 1163, 2063: 2163},
628			"map_sfixed32_sfixed32": map[int32]int32{1064: 1164, 2064: 2164},
629			"map_sfixed64_sfixed64": map[int64]int64{1065: 1165, 2065: 2165},
630			"map_int32_float":       map[int32]float32{1066: 1166.5, 2066: 2166.5},
631			"map_int32_double":      map[int32]float64{1067: 1167.5, 2067: 2167.5},
632			"map_bool_bool":         map[bool]bool{true: false, false: true},
633			"map_string_string":     map[string]string{"69.1.key": "69.1.val", "69.2.key": "69.2.val"},
634			"map_string_bytes":      map[string][]byte{"70.1.key": []byte("70.1.val"), "70.2.key": []byte("70.2.val")},
635			"map_string_nested_message": map[string]protobuild.Message{
636				"71.1.key": {"a": 1171},
637				"71.2.key": {"a": 2171},
638			},
639			"map_string_nested_enum": map[string]string{"73.1.key": "FOO", "73.2.key": "BAR"},
640		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
641		wire: protopack.Message{
642			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
643				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1056),
644				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1156),
645			}),
646			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
647				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2056),
648				protopack.Tag{2, protopack.VarintType}, protopack.Varint(2156),
649			}),
650			protopack.Tag{57, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
651				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1057),
652				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1157),
653			}),
654			protopack.Tag{57, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
655				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2057),
656				protopack.Tag{2, protopack.VarintType}, protopack.Varint(2157),
657			}),
658			protopack.Tag{58, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
659				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1058),
660				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1158),
661			}),
662			protopack.Tag{58, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
663				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2058),
664				protopack.Tag{2, protopack.VarintType}, protopack.Varint(2158),
665			}),
666			protopack.Tag{59, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
667				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1059),
668				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1159),
669			}),
670			protopack.Tag{59, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
671				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2059),
672				protopack.Tag{2, protopack.VarintType}, protopack.Varint(2159),
673			}),
674			protopack.Tag{60, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
675				protopack.Tag{1, protopack.VarintType}, protopack.Svarint(1060),
676				protopack.Tag{2, protopack.VarintType}, protopack.Svarint(1160),
677			}),
678			protopack.Tag{60, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
679				protopack.Tag{1, protopack.VarintType}, protopack.Svarint(2060),
680				protopack.Tag{2, protopack.VarintType}, protopack.Svarint(2160),
681			}),
682			protopack.Tag{61, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
683				protopack.Tag{1, protopack.VarintType}, protopack.Svarint(1061),
684				protopack.Tag{2, protopack.VarintType}, protopack.Svarint(1161),
685			}),
686			protopack.Tag{61, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
687				protopack.Tag{1, protopack.VarintType}, protopack.Svarint(2061),
688				protopack.Tag{2, protopack.VarintType}, protopack.Svarint(2161),
689			}),
690			protopack.Tag{62, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
691				protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(1062),
692				protopack.Tag{2, protopack.Fixed32Type}, protopack.Int32(1162),
693			}),
694			protopack.Tag{62, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
695				protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(2062),
696				protopack.Tag{2, protopack.Fixed32Type}, protopack.Int32(2162),
697			}),
698			protopack.Tag{63, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
699				protopack.Tag{1, protopack.Fixed64Type}, protopack.Int64(1063),
700				protopack.Tag{2, protopack.Fixed64Type}, protopack.Int64(1163),
701			}),
702			protopack.Tag{63, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
703				protopack.Tag{1, protopack.Fixed64Type}, protopack.Int64(2063),
704				protopack.Tag{2, protopack.Fixed64Type}, protopack.Int64(2163),
705			}),
706			protopack.Tag{64, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
707				protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(1064),
708				protopack.Tag{2, protopack.Fixed32Type}, protopack.Int32(1164),
709			}),
710			protopack.Tag{64, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
711				protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(2064),
712				protopack.Tag{2, protopack.Fixed32Type}, protopack.Int32(2164),
713			}),
714			protopack.Tag{65, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
715				protopack.Tag{1, protopack.Fixed64Type}, protopack.Int64(1065),
716				protopack.Tag{2, protopack.Fixed64Type}, protopack.Int64(1165),
717			}),
718			protopack.Tag{65, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
719				protopack.Tag{1, protopack.Fixed64Type}, protopack.Int64(2065),
720				protopack.Tag{2, protopack.Fixed64Type}, protopack.Int64(2165),
721			}),
722			protopack.Tag{66, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
723				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1066),
724				protopack.Tag{2, protopack.Fixed32Type}, protopack.Float32(1166.5),
725			}),
726			protopack.Tag{66, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
727				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2066),
728				protopack.Tag{2, protopack.Fixed32Type}, protopack.Float32(2166.5),
729			}),
730			protopack.Tag{67, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
731				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1067),
732				protopack.Tag{2, protopack.Fixed64Type}, protopack.Float64(1167.5),
733			}),
734			protopack.Tag{67, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
735				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2067),
736				protopack.Tag{2, protopack.Fixed64Type}, protopack.Float64(2167.5),
737			}),
738			protopack.Tag{68, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
739				protopack.Tag{1, protopack.VarintType}, protopack.Bool(true),
740				protopack.Tag{2, protopack.VarintType}, protopack.Bool(false),
741			}),
742			protopack.Tag{68, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
743				protopack.Tag{1, protopack.VarintType}, protopack.Bool(false),
744				protopack.Tag{2, protopack.VarintType}, protopack.Bool(true),
745			}),
746			protopack.Tag{69, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
747				protopack.Tag{1, protopack.BytesType}, protopack.String("69.1.key"),
748				protopack.Tag{2, protopack.BytesType}, protopack.String("69.1.val"),
749			}),
750			protopack.Tag{69, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
751				protopack.Tag{1, protopack.BytesType}, protopack.String("69.2.key"),
752				protopack.Tag{2, protopack.BytesType}, protopack.String("69.2.val"),
753			}),
754			protopack.Tag{70, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
755				protopack.Tag{1, protopack.BytesType}, protopack.String("70.1.key"),
756				protopack.Tag{2, protopack.BytesType}, protopack.String("70.1.val"),
757			}),
758			protopack.Tag{70, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
759				protopack.Tag{1, protopack.BytesType}, protopack.String("70.2.key"),
760				protopack.Tag{2, protopack.BytesType}, protopack.String("70.2.val"),
761			}),
762			protopack.Tag{71, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
763				protopack.Tag{1, protopack.BytesType}, protopack.String("71.1.key"),
764				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
765					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1171),
766				}),
767			}),
768			protopack.Tag{71, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
769				protopack.Tag{1, protopack.BytesType}, protopack.String("71.2.key"),
770				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
771					protopack.Tag{1, protopack.VarintType}, protopack.Varint(2171),
772				}),
773			}),
774			protopack.Tag{73, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
775				protopack.Tag{1, protopack.BytesType}, protopack.String("73.1.key"),
776				protopack.Tag{2, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_FOO)),
777			}),
778			protopack.Tag{73, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
779				protopack.Tag{1, protopack.BytesType}, protopack.String("73.2.key"),
780				protopack.Tag{2, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_BAR)),
781			}),
782		}.Marshal(),
783	},
784	{
785		desc: "map with value before key",
786		decodeTo: makeMessages(protobuild.Message{
787			"map_int32_int32": map[int32]int32{1056: 1156},
788			"map_string_nested_message": map[string]protobuild.Message{
789				"71.1.key": {"a": 1171},
790			},
791		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
792		wire: protopack.Message{
793			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
794				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1156),
795				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1056),
796			}),
797			protopack.Tag{71, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
798				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
799					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1171),
800				}),
801				protopack.Tag{1, protopack.BytesType}, protopack.String("71.1.key"),
802			}),
803		}.Marshal(),
804	},
805	{
806		desc: "map with repeated key and value",
807		decodeTo: makeMessages(protobuild.Message{
808			"map_int32_int32": map[int32]int32{1056: 1156},
809			"map_string_nested_message": map[string]protobuild.Message{
810				"71.1.key": {"a": 1171},
811			},
812		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
813		wire: protopack.Message{
814			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
815				protopack.Tag{1, protopack.VarintType}, protopack.Varint(0),
816				protopack.Tag{2, protopack.VarintType}, protopack.Varint(0),
817				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1056),
818				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1156),
819			}),
820			protopack.Tag{71, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
821				protopack.Tag{1, protopack.BytesType}, protopack.String(""),
822				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
823				protopack.Tag{1, protopack.BytesType}, protopack.String("71.1.key"),
824				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
825					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1171),
826				}),
827			}),
828		}.Marshal(),
829	},
830	{
831		desc: "oneof (uint32)",
832		decodeTo: makeMessages(protobuild.Message{
833			"oneof_uint32": 1111,
834		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
835		wire: protopack.Message{protopack.Tag{111, protopack.VarintType}, protopack.Varint(1111)}.Marshal(),
836	},
837	{
838		desc: "oneof (message)",
839		decodeTo: makeMessages(protobuild.Message{
840			"oneof_nested_message": protobuild.Message{
841				"a": 1112,
842			},
843		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
844		wire: protopack.Message{protopack.Tag{112, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
845			protopack.Message{protopack.Tag{1, protopack.VarintType}, protopack.Varint(1112)},
846		})}.Marshal(),
847	},
848	{
849		desc: "oneof (empty message)",
850		decodeTo: makeMessages(protobuild.Message{
851			"oneof_nested_message": protobuild.Message{},
852		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
853		wire: protopack.Message{protopack.Tag{112, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{})}.Marshal(),
854	},
855	{
856		desc: "oneof (merged message)",
857		decodeTo: makeMessages(protobuild.Message{
858			"oneof_nested_message": protobuild.Message{
859				"a": 1,
860				"corecursive": protobuild.Message{
861					"optional_int32": 43,
862				},
863			},
864		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
865		wire: protopack.Message{
866			protopack.Tag{112, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
867				protopack.Message{protopack.Tag{1, protopack.VarintType}, protopack.Varint(1)},
868			}),
869			protopack.Tag{112, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
870				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
871					protopack.Tag{1, protopack.VarintType}, protopack.Varint(43),
872				}),
873			}),
874		}.Marshal(),
875	},
876	{
877		desc: "oneof (group)",
878		decodeTo: makeMessages(protobuild.Message{
879			"oneofgroup": protobuild.Message{
880				"a": 1,
881			},
882		}, &testpb.TestAllTypes{}),
883		wire: protopack.Message{
884			protopack.Tag{121, protopack.StartGroupType},
885			protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
886			protopack.Tag{121, protopack.EndGroupType},
887		}.Marshal(),
888	},
889	{
890		desc: "oneof (empty group)",
891		decodeTo: makeMessages(protobuild.Message{
892			"oneofgroup": protobuild.Message{},
893		}, &testpb.TestAllTypes{}),
894		wire: protopack.Message{
895			protopack.Tag{121, protopack.StartGroupType},
896			protopack.Tag{121, protopack.EndGroupType},
897		}.Marshal(),
898	},
899	{
900		desc: "oneof (merged group)",
901		decodeTo: makeMessages(protobuild.Message{
902			"oneofgroup": protobuild.Message{
903				"a": 1,
904				"b": 2,
905			},
906		}, &testpb.TestAllTypes{}),
907		wire: protopack.Message{
908			protopack.Tag{121, protopack.StartGroupType},
909			protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
910			protopack.Tag{121, protopack.EndGroupType},
911			protopack.Tag{121, protopack.StartGroupType},
912			protopack.Tag{2, protopack.VarintType}, protopack.Varint(2),
913			protopack.Tag{121, protopack.EndGroupType},
914		}.Marshal(),
915	},
916	{
917		desc: "oneof (string)",
918		decodeTo: makeMessages(protobuild.Message{
919			"oneof_string": "1113",
920		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
921		wire: protopack.Message{protopack.Tag{113, protopack.BytesType}, protopack.String("1113")}.Marshal(),
922	},
923	{
924		desc: "oneof (bytes)",
925		decodeTo: makeMessages(protobuild.Message{
926			"oneof_bytes": "1114",
927		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
928		wire: protopack.Message{protopack.Tag{114, protopack.BytesType}, protopack.String("1114")}.Marshal(),
929	},
930	{
931		desc: "oneof (bool)",
932		decodeTo: makeMessages(protobuild.Message{
933			"oneof_bool": true,
934		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
935		wire: protopack.Message{protopack.Tag{115, protopack.VarintType}, protopack.Bool(true)}.Marshal(),
936	},
937	{
938		desc: "oneof (uint64)",
939		decodeTo: makeMessages(protobuild.Message{
940			"oneof_uint64": 116,
941		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
942		wire: protopack.Message{protopack.Tag{116, protopack.VarintType}, protopack.Varint(116)}.Marshal(),
943	},
944	{
945		desc: "oneof (float)",
946		decodeTo: makeMessages(protobuild.Message{
947			"oneof_float": 117.5,
948		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
949		wire: protopack.Message{protopack.Tag{117, protopack.Fixed32Type}, protopack.Float32(117.5)}.Marshal(),
950	},
951	{
952		desc: "oneof (double)",
953		decodeTo: makeMessages(protobuild.Message{
954			"oneof_double": 118.5,
955		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
956		wire: protopack.Message{protopack.Tag{118, protopack.Fixed64Type}, protopack.Float64(118.5)}.Marshal(),
957	},
958	{
959		desc: "oneof (enum)",
960		decodeTo: makeMessages(protobuild.Message{
961			"oneof_enum": "BAR",
962		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
963		wire: protopack.Message{protopack.Tag{119, protopack.VarintType}, protopack.Varint(int(testpb.TestAllTypes_BAR))}.Marshal(),
964	},
965	{
966		desc: "oneof (zero)",
967		decodeTo: makeMessages(protobuild.Message{
968			"oneof_uint64": 0,
969		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
970		wire: protopack.Message{protopack.Tag{116, protopack.VarintType}, protopack.Varint(0)}.Marshal(),
971	},
972	{
973		desc: "oneof (overridden value)",
974		decodeTo: makeMessages(protobuild.Message{
975			"oneof_uint64": 2,
976		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
977		wire: protopack.Message{
978			protopack.Tag{111, protopack.VarintType}, protopack.Varint(1),
979			protopack.Tag{116, protopack.VarintType}, protopack.Varint(2),
980		}.Marshal(),
981	},
982	// TODO: More unknown field tests for ordering, repeated fields, etc.
983	//
984	// It is currently impossible to produce results that the v1 Equal
985	// considers equivalent to those of the v1 decoder. Figure out if
986	// that's a problem or not.
987	{
988		desc:          "unknown fields",
989		checkFastInit: true,
990		decodeTo: makeMessages(protobuild.Message{
991			protobuild.Unknown: protopack.Message{
992				protopack.Tag{100000, protopack.VarintType}, protopack.Varint(1),
993			}.Marshal(),
994		}),
995		wire: protopack.Message{
996			protopack.Tag{100000, protopack.VarintType}, protopack.Varint(1),
997		}.Marshal(),
998	},
999	{
1000		desc: "discarded unknown fields",
1001		unmarshalOptions: proto.UnmarshalOptions{
1002			DiscardUnknown: true,
1003		},
1004		decodeTo: makeMessages(protobuild.Message{}),
1005		wire: protopack.Message{
1006			protopack.Tag{100000, protopack.VarintType}, protopack.Varint(1),
1007		}.Marshal(),
1008	},
1009	{
1010		desc: "field type mismatch",
1011		decodeTo: makeMessages(protobuild.Message{
1012			protobuild.Unknown: protopack.Message{
1013				protopack.Tag{1, protopack.BytesType}, protopack.String("string"),
1014			}.Marshal(),
1015		}),
1016		wire: protopack.Message{
1017			protopack.Tag{1, protopack.BytesType}, protopack.String("string"),
1018		}.Marshal(),
1019	},
1020	{
1021		desc: "map field element mismatch",
1022		decodeTo: makeMessages(protobuild.Message{
1023			"map_int32_int32": map[int32]int32{1: 0},
1024		}, &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}),
1025		wire: protopack.Message{
1026			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1027				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1028				protopack.Tag{2, protopack.BytesType}, protopack.String("string"),
1029			}),
1030		}.Marshal(),
1031	},
1032	{
1033		desc:          "required field in nil message unset",
1034		checkFastInit: true,
1035		partial:       true,
1036		decodeTo:      []proto.Message{(*testpb.TestRequired)(nil)},
1037	},
1038	{
1039		desc:          "required int32 unset",
1040		checkFastInit: true,
1041		partial:       true,
1042		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Int32{}),
1043	},
1044	{
1045		desc:          "required int32 set",
1046		checkFastInit: true,
1047		decodeTo: makeMessages(protobuild.Message{
1048			"v": 1,
1049		}, &requiredpb.Int32{}),
1050		wire: protopack.Message{
1051			protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1052		}.Marshal(),
1053	},
1054	{
1055		desc:          "required fixed32 unset",
1056		checkFastInit: true,
1057		partial:       true,
1058		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Fixed32{}),
1059	},
1060	{
1061		desc:          "required fixed32 set",
1062		checkFastInit: true,
1063		decodeTo: makeMessages(protobuild.Message{
1064			"v": 1,
1065		}, &requiredpb.Fixed32{}),
1066		wire: protopack.Message{
1067			protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(1),
1068		}.Marshal(),
1069	},
1070	{
1071		desc:          "required fixed64 unset",
1072		checkFastInit: true,
1073		partial:       true,
1074		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Fixed64{}),
1075	},
1076	{
1077		desc:          "required fixed64 set",
1078		checkFastInit: true,
1079		decodeTo: makeMessages(protobuild.Message{
1080			"v": 1,
1081		}, &requiredpb.Fixed64{}),
1082		wire: protopack.Message{
1083			protopack.Tag{1, protopack.Fixed64Type}, protopack.Int64(1),
1084		}.Marshal(),
1085	},
1086	{
1087		desc:          "required bytes unset",
1088		checkFastInit: true,
1089		partial:       true,
1090		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Bytes{}),
1091	},
1092	{
1093		desc:          "required bytes set",
1094		checkFastInit: true,
1095		decodeTo: makeMessages(protobuild.Message{
1096			"v": "",
1097		}, &requiredpb.Bytes{}),
1098		wire: protopack.Message{
1099			protopack.Tag{1, protopack.BytesType}, protopack.Bytes(nil),
1100		}.Marshal(),
1101	},
1102	{
1103		desc:          "required message unset",
1104		checkFastInit: true,
1105		partial:       true,
1106		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Message{}),
1107	},
1108	{
1109		desc:          "required message set",
1110		checkFastInit: true,
1111		decodeTo: makeMessages(protobuild.Message{
1112			"v": protobuild.Message{},
1113		}, &requiredpb.Message{}),
1114		wire: protopack.Message{
1115			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1116		}.Marshal(),
1117	},
1118	{
1119		desc:          "required group unset",
1120		checkFastInit: true,
1121		partial:       true,
1122		decodeTo:      makeMessages(protobuild.Message{}, &requiredpb.Group{}),
1123	},
1124	{
1125		desc:          "required group set",
1126		checkFastInit: true,
1127		decodeTo: makeMessages(protobuild.Message{
1128			"group": protobuild.Message{},
1129		}, &requiredpb.Group{}),
1130		wire: protopack.Message{
1131			protopack.Tag{1, protopack.StartGroupType},
1132			protopack.Tag{1, protopack.EndGroupType},
1133		}.Marshal(),
1134	},
1135	{
1136		desc:          "required field with incompatible wire type",
1137		checkFastInit: true,
1138		partial:       true,
1139		decodeTo: []proto.Message{build(
1140			&testpb.TestRequired{},
1141			unknown(protopack.Message{
1142				protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(2),
1143			}.Marshal()),
1144		)},
1145		wire: protopack.Message{
1146			protopack.Tag{1, protopack.Fixed32Type}, protopack.Int32(2),
1147		}.Marshal(),
1148	},
1149	{
1150		desc:          "required field in optional message unset",
1151		checkFastInit: true,
1152		partial:       true,
1153		decodeTo: makeMessages(protobuild.Message{
1154			"optional_message": protobuild.Message{},
1155		}, &testpb.TestRequiredForeign{}),
1156		wire: protopack.Message{
1157			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1158		}.Marshal(),
1159	},
1160	{
1161		desc:          "required field in optional message set",
1162		checkFastInit: true,
1163		decodeTo: makeMessages(protobuild.Message{
1164			"optional_message": protobuild.Message{
1165				"required_field": 1,
1166			},
1167		}, &testpb.TestRequiredForeign{}),
1168		wire: protopack.Message{
1169			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1170				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1171			}),
1172		}.Marshal(),
1173	},
1174	{
1175		desc:             "required field in optional message set (split across multiple tags)",
1176		checkFastInit:    false, // fast init checks don't handle split messages
1177		nocheckValidInit: true,  // validation doesn't either
1178		decodeTo: makeMessages(protobuild.Message{
1179			"optional_message": protobuild.Message{
1180				"required_field": 1,
1181			},
1182		}, &testpb.TestRequiredForeign{}),
1183		wire: protopack.Message{
1184			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1185			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1186				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1187			}),
1188		}.Marshal(),
1189	},
1190	{
1191		desc:          "required field in repeated message unset",
1192		checkFastInit: true,
1193		partial:       true,
1194		decodeTo: makeMessages(protobuild.Message{
1195			"repeated_message": []protobuild.Message{
1196				{"required_field": 1},
1197				{},
1198			},
1199		}, &testpb.TestRequiredForeign{}),
1200		wire: protopack.Message{
1201			protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1202				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1203			}),
1204			protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1205		}.Marshal(),
1206	},
1207	{
1208		desc:          "required field in repeated message set",
1209		checkFastInit: true,
1210		decodeTo: makeMessages(protobuild.Message{
1211			"repeated_message": []protobuild.Message{
1212				{"required_field": 1},
1213				{"required_field": 2},
1214			},
1215		}, &testpb.TestRequiredForeign{}),
1216		wire: protopack.Message{
1217			protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1218				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1219			}),
1220			protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1221				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1222			}),
1223		}.Marshal(),
1224	},
1225	{
1226		desc:          "required field in map message unset",
1227		checkFastInit: true,
1228		partial:       true,
1229		decodeTo: makeMessages(protobuild.Message{
1230			"map_message": map[int32]protobuild.Message{
1231				1: {"required_field": 1},
1232				2: {},
1233			},
1234		}, &testpb.TestRequiredForeign{}),
1235		wire: protopack.Message{
1236			protopack.Tag{3, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1237				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1238				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1239					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1240				}),
1241			}),
1242			protopack.Tag{3, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1243				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1244				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1245			}),
1246		}.Marshal(),
1247	},
1248	{
1249		desc:          "required field in absent map message value",
1250		checkFastInit: true,
1251		partial:       true,
1252		decodeTo: makeMessages(protobuild.Message{
1253			"map_message": map[int32]protobuild.Message{
1254				2: {},
1255			},
1256		}, &testpb.TestRequiredForeign{}),
1257		wire: protopack.Message{
1258			protopack.Tag{3, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1259				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1260			}),
1261		}.Marshal(),
1262	},
1263	{
1264		desc:          "required field in map message set",
1265		checkFastInit: true,
1266		decodeTo: makeMessages(protobuild.Message{
1267			"map_message": map[int32]protobuild.Message{
1268				1: {"required_field": 1},
1269				2: {"required_field": 2},
1270			},
1271		}, &testpb.TestRequiredForeign{}),
1272		wire: protopack.Message{
1273			protopack.Tag{3, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1274				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1275				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1276					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1277				}),
1278			}),
1279			protopack.Tag{3, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1280				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1281				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1282					protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1283				}),
1284			}),
1285		}.Marshal(),
1286	},
1287	{
1288		desc:          "required field in optional group unset",
1289		checkFastInit: true,
1290		partial:       true,
1291		decodeTo: makeMessages(protobuild.Message{
1292			"optionalgroup": protobuild.Message{},
1293		}, &testpb.TestRequiredGroupFields{}),
1294		wire: protopack.Message{
1295			protopack.Tag{1, protopack.StartGroupType},
1296			protopack.Tag{1, protopack.EndGroupType},
1297		}.Marshal(),
1298	},
1299	{
1300		desc:          "required field in optional group set",
1301		checkFastInit: true,
1302		decodeTo: makeMessages(protobuild.Message{
1303			"optionalgroup": protobuild.Message{
1304				"a": 1,
1305			},
1306		}, &testpb.TestRequiredGroupFields{}),
1307		wire: protopack.Message{
1308			protopack.Tag{1, protopack.StartGroupType},
1309			protopack.Tag{2, protopack.VarintType}, protopack.Varint(1),
1310			protopack.Tag{1, protopack.EndGroupType},
1311		}.Marshal(),
1312	},
1313	{
1314		desc:          "required field in repeated group unset",
1315		checkFastInit: true,
1316		partial:       true,
1317		decodeTo: makeMessages(protobuild.Message{
1318			"repeatedgroup": []protobuild.Message{
1319				{"a": 1},
1320				{},
1321			},
1322		}, &testpb.TestRequiredGroupFields{}),
1323		wire: protopack.Message{
1324			protopack.Tag{3, protopack.StartGroupType},
1325			protopack.Tag{4, protopack.VarintType}, protopack.Varint(1),
1326			protopack.Tag{3, protopack.EndGroupType},
1327			protopack.Tag{3, protopack.StartGroupType},
1328			protopack.Tag{3, protopack.EndGroupType},
1329		}.Marshal(),
1330	},
1331	{
1332		desc:          "required field in repeated group set",
1333		checkFastInit: true,
1334		decodeTo: makeMessages(protobuild.Message{
1335			"repeatedgroup": []protobuild.Message{
1336				{"a": 1},
1337				{"a": 2},
1338			},
1339		}, &testpb.TestRequiredGroupFields{}),
1340		wire: protopack.Message{
1341			protopack.Tag{3, protopack.StartGroupType},
1342			protopack.Tag{4, protopack.VarintType}, protopack.Varint(1),
1343			protopack.Tag{3, protopack.EndGroupType},
1344			protopack.Tag{3, protopack.StartGroupType},
1345			protopack.Tag{4, protopack.VarintType}, protopack.Varint(2),
1346			protopack.Tag{3, protopack.EndGroupType},
1347		}.Marshal(),
1348	},
1349	{
1350		desc:          "required field in oneof message unset",
1351		checkFastInit: true,
1352		partial:       true,
1353		decodeTo: makeMessages(protobuild.Message{
1354			"oneof_message": protobuild.Message{},
1355		}, &testpb.TestRequiredForeign{}),
1356		wire: protopack.Message{protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{})}.Marshal(),
1357	},
1358	{
1359		desc:          "required field in oneof message set",
1360		checkFastInit: true,
1361		decodeTo: makeMessages(protobuild.Message{
1362			"oneof_message": protobuild.Message{
1363				"required_field": 1,
1364			},
1365		}, &testpb.TestRequiredForeign{}),
1366		wire: protopack.Message{protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1367			protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1368		})}.Marshal(),
1369	},
1370	{
1371		desc:          "required field in extension message unset",
1372		checkFastInit: true,
1373		partial:       true,
1374		decodeTo: makeMessages(protobuild.Message{
1375			"single": protobuild.Message{},
1376		}, &testpb.TestAllExtensions{}),
1377		wire: protopack.Message{
1378			protopack.Tag{1000, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1379		}.Marshal(),
1380	},
1381	{
1382		desc:          "required field in extension message set",
1383		checkFastInit: true,
1384		decodeTo: makeMessages(protobuild.Message{
1385			"single": protobuild.Message{
1386				"required_field": 1,
1387			},
1388		}, &testpb.TestAllExtensions{}),
1389		wire: protopack.Message{
1390			protopack.Tag{1000, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1391				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1392			}),
1393		}.Marshal(),
1394	},
1395	{
1396		desc:          "required field in repeated extension message unset",
1397		checkFastInit: true,
1398		partial:       true,
1399		decodeTo: makeMessages(protobuild.Message{
1400			"multi": []protobuild.Message{
1401				{"required_field": 1},
1402				{},
1403			},
1404		}, &testpb.TestAllExtensions{}),
1405		wire: protopack.Message{
1406			protopack.Tag{1001, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1407				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1408			}),
1409			protopack.Tag{1001, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{}),
1410		}.Marshal(),
1411	},
1412	{
1413		desc:          "required field in repeated extension message set",
1414		checkFastInit: true,
1415		decodeTo: makeMessages(protobuild.Message{
1416			"multi": []protobuild.Message{
1417				{"required_field": 1},
1418				{"required_field": 2},
1419			},
1420		}, &testpb.TestAllExtensions{}),
1421		wire: protopack.Message{
1422			protopack.Tag{1001, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1423				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1424			}),
1425			protopack.Tag{1001, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1426				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2),
1427			}),
1428		}.Marshal(),
1429	},
1430	{
1431		desc: "nil messages",
1432		decodeTo: []proto.Message{
1433			(*testpb.TestAllTypes)(nil),
1434			(*test3pb.TestAllTypes)(nil),
1435			(*testpb.TestAllExtensions)(nil),
1436		},
1437	},
1438	{
1439		desc:    "legacy",
1440		partial: true,
1441		decodeTo: makeMessages(protobuild.Message{
1442			"f1": protobuild.Message{
1443				"optional_int32":      1,
1444				"optional_child_enum": "ALPHA",
1445				"optional_child_message": protobuild.Message{
1446					"f1": "x",
1447				},
1448				"optionalgroup": protobuild.Message{
1449					"f1": "x",
1450				},
1451				"repeated_child_message": []protobuild.Message{
1452					{"f1": "x"},
1453				},
1454				"repeatedgroup": []protobuild.Message{
1455					{"f1": "x"},
1456				},
1457				"map_bool_child_message": map[bool]protobuild.Message{
1458					true: {"f1": "x"},
1459				},
1460				"oneof_child_message": protobuild.Message{
1461					"f1": "x",
1462				},
1463			},
1464		}, &legacypb.Legacy{}),
1465		wire: protopack.Message{
1466			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1467				protopack.Tag{101, protopack.VarintType}, protopack.Varint(1),
1468				protopack.Tag{115, protopack.VarintType}, protopack.Varint(0),
1469				protopack.Tag{116, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1470					protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1471				}),
1472				protopack.Tag{120, protopack.StartGroupType},
1473				protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1474				protopack.Tag{120, protopack.EndGroupType},
1475				protopack.Tag{516, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1476					protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1477				}),
1478				protopack.Tag{520, protopack.StartGroupType},
1479				protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1480				protopack.Tag{520, protopack.EndGroupType},
1481				protopack.Tag{616, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1482					protopack.Tag{1, protopack.VarintType}, protopack.Varint(1),
1483					protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1484						protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1485					}),
1486				}),
1487				protopack.Tag{716, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1488					protopack.Tag{1, protopack.BytesType}, protopack.String("x"),
1489				}),
1490			}),
1491		}.Marshal(),
1492		validationStatus: impl.ValidationUnknown,
1493	},
1494	{
1495		desc: "first reserved field number",
1496		decodeTo: makeMessages(protobuild.Message{
1497			protobuild.Unknown: protopack.Message{
1498				protopack.Tag{protopack.FirstReservedNumber, protopack.VarintType}, protopack.Varint(1004),
1499			}.Marshal(),
1500		}),
1501		wire: protopack.Message{
1502			protopack.Tag{protopack.FirstReservedNumber, protopack.VarintType}, protopack.Varint(1004),
1503		}.Marshal(),
1504	},
1505	{
1506		desc: "last reserved field number",
1507		decodeTo: makeMessages(protobuild.Message{
1508			protobuild.Unknown: protopack.Message{
1509				protopack.Tag{protopack.LastReservedNumber, protopack.VarintType}, protopack.Varint(1005),
1510			}.Marshal(),
1511		}),
1512		wire: protopack.Message{
1513			protopack.Tag{protopack.LastReservedNumber, protopack.VarintType}, protopack.Varint(1005),
1514		}.Marshal(),
1515	},
1516	{
1517		desc: "nested unknown extension",
1518		unmarshalOptions: proto.UnmarshalOptions{
1519			DiscardUnknown: true,
1520			Resolver: filterResolver{
1521				filter: func(name protoreflect.FullName) bool {
1522					switch name.Name() {
1523					case "optional_nested_message",
1524						"optional_int32":
1525						return true
1526					}
1527					return false
1528				},
1529				resolver: protoregistry.GlobalTypes,
1530			},
1531		},
1532		decodeTo: makeMessages(protobuild.Message{
1533			"optional_nested_message": protobuild.Message{
1534				"corecursive": protobuild.Message{
1535					"optional_nested_message": protobuild.Message{
1536						"corecursive": protobuild.Message{
1537							"optional_int32": 42,
1538						},
1539					},
1540				},
1541			},
1542		}, &testpb.TestAllExtensions{}),
1543		wire: protopack.Message{
1544			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1545				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1546					protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1547						protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1548							protopack.Tag{1, protopack.VarintType}, protopack.Varint(42),
1549							protopack.Tag{2, protopack.VarintType}, protopack.Varint(43),
1550						}),
1551					}),
1552				}),
1553			}),
1554		}.Marshal(),
1555	},
1556}
1557
1558var testInvalidMessages = []testProto{
1559	{
1560		desc: "invalid UTF-8 in optional string field",
1561		decodeTo: makeMessages(protobuild.Message{
1562			"optional_string": "abc\xff",
1563		}, &test3pb.TestAllTypes{}),
1564		wire: protopack.Message{
1565			protopack.Tag{14, protopack.BytesType}, protopack.String("abc\xff"),
1566		}.Marshal(),
1567	},
1568	{
1569		desc: "invalid UTF-8 in singular string field",
1570		decodeTo: makeMessages(protobuild.Message{
1571			"singular_string": "abc\xff",
1572		}, &test3pb.TestAllTypes{}),
1573		wire: protopack.Message{
1574			protopack.Tag{94, protopack.BytesType}, protopack.String("abc\xff"),
1575		}.Marshal(),
1576	},
1577	{
1578		desc: "invalid UTF-8 in repeated string field",
1579		decodeTo: makeMessages(protobuild.Message{
1580			"repeated_string": []string{"foo", "abc\xff"},
1581		}, &test3pb.TestAllTypes{}),
1582		wire: protopack.Message{
1583			protopack.Tag{44, protopack.BytesType}, protopack.String("foo"),
1584			protopack.Tag{44, protopack.BytesType}, protopack.String("abc\xff"),
1585		}.Marshal(),
1586	},
1587	{
1588		desc: "invalid UTF-8 in nested message",
1589		decodeTo: makeMessages(protobuild.Message{
1590			"optional_nested_message": protobuild.Message{
1591				"corecursive": protobuild.Message{
1592					"singular_string": "abc\xff",
1593				},
1594			},
1595		}, &test3pb.TestAllTypes{}),
1596		wire: protopack.Message{
1597			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1598				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1599					protopack.Tag{94, protopack.BytesType}, protopack.String("abc\xff"),
1600				}),
1601			}),
1602		}.Marshal(),
1603	},
1604	{
1605		desc: "invalid UTF-8 in oneof field",
1606		decodeTo: makeMessages(protobuild.Message{
1607			"oneof_string": "abc\xff",
1608		}, &test3pb.TestAllTypes{}),
1609		wire: protopack.Message{protopack.Tag{113, protopack.BytesType}, protopack.String("abc\xff")}.Marshal(),
1610	},
1611	{
1612		desc: "invalid UTF-8 in map key",
1613		decodeTo: makeMessages(protobuild.Message{
1614			"map_string_string": map[string]string{"key\xff": "val"},
1615		}, &test3pb.TestAllTypes{}),
1616		wire: protopack.Message{
1617			protopack.Tag{69, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1618				protopack.Tag{1, protopack.BytesType}, protopack.String("key\xff"),
1619				protopack.Tag{2, protopack.BytesType}, protopack.String("val"),
1620			}),
1621		}.Marshal(),
1622	},
1623	{
1624		desc: "invalid UTF-8 in map value",
1625		decodeTo: makeMessages(protobuild.Message{
1626			"map_string_string": map[string]string{"key": "val\xff"},
1627		}, &test3pb.TestAllTypes{}),
1628		wire: protopack.Message{
1629			protopack.Tag{69, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1630				protopack.Tag{1, protopack.BytesType}, protopack.String("key"),
1631				protopack.Tag{2, protopack.BytesType}, protopack.String("val\xff"),
1632			}),
1633		}.Marshal(),
1634	},
1635	{
1636		desc: "invalid field number zero",
1637		decodeTo: []proto.Message{
1638			(*testpb.TestAllTypes)(nil),
1639			(*testpb.TestAllExtensions)(nil),
1640		},
1641		wire: protopack.Message{
1642			protopack.Tag{protopack.MinValidNumber - 1, protopack.VarintType}, protopack.Varint(1001),
1643		}.Marshal(),
1644	},
1645	{
1646		desc: "invalid field numbers zero and one",
1647		decodeTo: []proto.Message{
1648			(*testpb.TestAllTypes)(nil),
1649			(*testpb.TestAllExtensions)(nil),
1650		},
1651		wire: protopack.Message{
1652			protopack.Tag{protopack.MinValidNumber - 1, protopack.VarintType}, protopack.Varint(1002),
1653			protopack.Tag{protopack.MinValidNumber, protopack.VarintType}, protopack.Varint(1003),
1654		}.Marshal(),
1655	},
1656	{
1657		desc: "invalid field numbers max and max+1",
1658		decodeTo: []proto.Message{
1659			(*testpb.TestAllTypes)(nil),
1660			(*testpb.TestAllExtensions)(nil),
1661		},
1662		wire: protopack.Message{
1663			protopack.Tag{protopack.MaxValidNumber, protopack.VarintType}, protopack.Varint(1006),
1664			protopack.Tag{protopack.MaxValidNumber + 1, protopack.VarintType}, protopack.Varint(1007),
1665		}.Marshal(),
1666	},
1667	{
1668		desc: "invalid field number max+1",
1669		decodeTo: []proto.Message{
1670			(*testpb.TestAllTypes)(nil),
1671			(*testpb.TestAllExtensions)(nil),
1672		},
1673		wire: protopack.Message{
1674			protopack.Tag{protopack.MaxValidNumber + 1, protopack.VarintType}, protopack.Varint(1008),
1675		}.Marshal(),
1676	},
1677	{
1678		desc: "invalid field number wraps int32",
1679		decodeTo: []proto.Message{
1680			(*testpb.TestAllTypes)(nil),
1681			(*testpb.TestAllExtensions)(nil),
1682		},
1683		wire: protopack.Message{
1684			protopack.Varint(2234993595104), protopack.Varint(0),
1685		}.Marshal(),
1686	},
1687	{
1688		desc:     "invalid field number in map",
1689		decodeTo: []proto.Message{(*testpb.TestAllTypes)(nil)},
1690		wire: protopack.Message{
1691			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1692				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1056),
1693				protopack.Tag{2, protopack.VarintType}, protopack.Varint(1156),
1694				protopack.Tag{protopack.MaxValidNumber + 1, protopack.VarintType}, protopack.Varint(0),
1695			}),
1696		}.Marshal(),
1697	},
1698	{
1699		desc: "invalid tag varint",
1700		decodeTo: []proto.Message{
1701			(*testpb.TestAllTypes)(nil),
1702			(*testpb.TestAllExtensions)(nil),
1703		},
1704		wire: []byte{0xff},
1705	},
1706	{
1707		desc: "field number too small",
1708		decodeTo: []proto.Message{
1709			(*testpb.TestAllTypes)(nil),
1710			(*testpb.TestAllExtensions)(nil),
1711		},
1712		wire: protopack.Message{
1713			protopack.Tag{0, protopack.VarintType}, protopack.Varint(0),
1714		}.Marshal(),
1715	},
1716	{
1717		desc: "field number too large",
1718		decodeTo: []proto.Message{
1719			(*testpb.TestAllTypes)(nil),
1720			(*testpb.TestAllExtensions)(nil),
1721		},
1722		wire: protopack.Message{
1723			protopack.Tag{protowire.MaxValidNumber + 1, protopack.VarintType}, protopack.Varint(0),
1724		}.Marshal(),
1725	},
1726	{
1727		desc: "invalid tag varint in message field",
1728		decodeTo: []proto.Message{
1729			(*testpb.TestAllTypes)(nil),
1730			(*testpb.TestAllExtensions)(nil),
1731		},
1732		wire: protopack.Message{
1733			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1734				protopack.Raw{0xff},
1735			}),
1736		}.Marshal(),
1737	},
1738	{
1739		desc: "invalid tag varint in repeated message field",
1740		decodeTo: []proto.Message{
1741			(*testpb.TestAllTypes)(nil),
1742			(*testpb.TestAllExtensions)(nil),
1743		},
1744		wire: protopack.Message{
1745			protopack.Tag{48, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1746				protopack.Raw{0xff},
1747			}),
1748		}.Marshal(),
1749	},
1750	{
1751		desc: "invalid varint in group field",
1752		decodeTo: []proto.Message{
1753			(*testpb.TestAllTypes)(nil),
1754			(*testpb.TestAllExtensions)(nil),
1755		},
1756		wire: protopack.Message{
1757			protopack.Tag{16, protopack.StartGroupType},
1758			protopack.Tag{1000, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1759				protopack.Raw{0xff},
1760			}),
1761			protopack.Tag{16, protopack.EndGroupType},
1762		}.Marshal(),
1763	},
1764	{
1765		desc: "invalid varint in repeated group field",
1766		decodeTo: []proto.Message{
1767			(*testpb.TestAllTypes)(nil),
1768			(*testpb.TestAllExtensions)(nil),
1769		},
1770		wire: protopack.Message{
1771			protopack.Tag{46, protopack.StartGroupType},
1772			protopack.Tag{1001, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1773				protopack.Raw{0xff},
1774			}),
1775			protopack.Tag{46, protopack.EndGroupType},
1776		}.Marshal(),
1777	},
1778	{
1779		desc: "unterminated repeated group field",
1780		decodeTo: []proto.Message{
1781			(*testpb.TestAllTypes)(nil),
1782			(*testpb.TestAllExtensions)(nil),
1783		},
1784		wire: protopack.Message{
1785			protopack.Tag{46, protopack.StartGroupType},
1786		}.Marshal(),
1787	},
1788	{
1789		desc: "invalid tag varint in map item",
1790		decodeTo: []proto.Message{
1791			(*testpb.TestAllTypes)(nil),
1792		},
1793		wire: protopack.Message{
1794			protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1795				protopack.Tag{1, protopack.VarintType}, protopack.Varint(0),
1796				protopack.Tag{2, protopack.VarintType}, protopack.Varint(0),
1797				protopack.Raw{0xff},
1798			}),
1799		}.Marshal(),
1800	},
1801	{
1802		desc: "invalid tag varint in map message value",
1803		decodeTo: []proto.Message{
1804			(*testpb.TestAllTypes)(nil),
1805		},
1806		wire: protopack.Message{
1807			protopack.Tag{71, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1808				protopack.Tag{1, protopack.VarintType}, protopack.Varint(0),
1809				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
1810					protopack.Raw{0xff},
1811				}),
1812			}),
1813		}.Marshal(),
1814	},
1815	{
1816		desc: "invalid packed int32 field",
1817		decodeTo: []proto.Message{
1818			(*testpb.TestAllTypes)(nil),
1819			(*testpb.TestAllExtensions)(nil),
1820		},
1821		wire: protopack.Message{
1822			protopack.Tag{31, protopack.BytesType}, protopack.Bytes{0xff},
1823		}.Marshal(),
1824	},
1825	{
1826		desc: "invalid packed int64 field",
1827		decodeTo: []proto.Message{
1828			(*testpb.TestAllTypes)(nil),
1829			(*testpb.TestAllExtensions)(nil),
1830		},
1831		wire: protopack.Message{
1832			protopack.Tag{32, protopack.BytesType}, protopack.Bytes{0xff},
1833		}.Marshal(),
1834	},
1835	{
1836		desc: "invalid packed uint32 field",
1837		decodeTo: []proto.Message{
1838			(*testpb.TestAllTypes)(nil),
1839			(*testpb.TestAllExtensions)(nil),
1840		},
1841		wire: protopack.Message{
1842			protopack.Tag{33, protopack.BytesType}, protopack.Bytes{0xff},
1843		}.Marshal(),
1844	},
1845	{
1846		desc: "invalid packed uint64 field",
1847		decodeTo: []proto.Message{
1848			(*testpb.TestAllTypes)(nil),
1849			(*testpb.TestAllExtensions)(nil),
1850		},
1851		wire: protopack.Message{
1852			protopack.Tag{34, protopack.BytesType}, protopack.Bytes{0xff},
1853		}.Marshal(),
1854	},
1855	{
1856		desc: "invalid packed sint32 field",
1857		decodeTo: []proto.Message{
1858			(*testpb.TestAllTypes)(nil),
1859			(*testpb.TestAllExtensions)(nil),
1860		},
1861		wire: protopack.Message{
1862			protopack.Tag{35, protopack.BytesType}, protopack.Bytes{0xff},
1863		}.Marshal(),
1864	},
1865	{
1866		desc: "invalid packed sint64 field",
1867		decodeTo: []proto.Message{
1868			(*testpb.TestAllTypes)(nil),
1869			(*testpb.TestAllExtensions)(nil),
1870		},
1871		wire: protopack.Message{
1872			protopack.Tag{36, protopack.BytesType}, protopack.Bytes{0xff},
1873		}.Marshal(),
1874	},
1875	{
1876		desc: "invalid packed fixed32 field",
1877		decodeTo: []proto.Message{
1878			(*testpb.TestAllTypes)(nil),
1879			(*testpb.TestAllExtensions)(nil),
1880		},
1881		wire: protopack.Message{
1882			protopack.Tag{37, protopack.BytesType}, protopack.Bytes{0x00},
1883		}.Marshal(),
1884	},
1885	{
1886		desc: "invalid packed fixed64 field",
1887		decodeTo: []proto.Message{
1888			(*testpb.TestAllTypes)(nil),
1889			(*testpb.TestAllExtensions)(nil),
1890		},
1891		wire: protopack.Message{
1892			protopack.Tag{38, protopack.BytesType}, protopack.Bytes{0x00},
1893		}.Marshal(),
1894	},
1895	{
1896		desc: "invalid packed sfixed32 field",
1897		decodeTo: []proto.Message{
1898			(*testpb.TestAllTypes)(nil),
1899			(*testpb.TestAllExtensions)(nil),
1900		},
1901		wire: protopack.Message{
1902			protopack.Tag{39, protopack.BytesType}, protopack.Bytes{0x00},
1903		}.Marshal(),
1904	},
1905	{
1906		desc: "invalid packed sfixed64 field",
1907		decodeTo: []proto.Message{
1908			(*testpb.TestAllTypes)(nil),
1909			(*testpb.TestAllExtensions)(nil),
1910		},
1911		wire: protopack.Message{
1912			protopack.Tag{40, protopack.BytesType}, protopack.Bytes{0x00},
1913		}.Marshal(),
1914	},
1915	{
1916		desc: "invalid packed float field",
1917		decodeTo: []proto.Message{
1918			(*testpb.TestAllTypes)(nil),
1919			(*testpb.TestAllExtensions)(nil),
1920		},
1921		wire: protopack.Message{
1922			protopack.Tag{41, protopack.BytesType}, protopack.Bytes{0x00},
1923		}.Marshal(),
1924	},
1925	{
1926		desc: "invalid packed double field",
1927		decodeTo: []proto.Message{
1928			(*testpb.TestAllTypes)(nil),
1929			(*testpb.TestAllExtensions)(nil),
1930		},
1931		wire: protopack.Message{
1932			protopack.Tag{42, protopack.BytesType}, protopack.Bytes{0x00},
1933		}.Marshal(),
1934	},
1935	{
1936		desc: "invalid packed bool field",
1937		decodeTo: []proto.Message{
1938			(*testpb.TestAllTypes)(nil),
1939			(*testpb.TestAllExtensions)(nil),
1940		},
1941		wire: protopack.Message{
1942			protopack.Tag{43, protopack.BytesType}, protopack.Bytes{0xff},
1943		}.Marshal(),
1944	},
1945	{
1946		desc: "bytes field overruns message",
1947		decodeTo: []proto.Message{
1948			(*testpb.TestAllTypes)(nil),
1949			(*testpb.TestAllExtensions)(nil),
1950		},
1951		wire: protopack.Message{
1952			protopack.Tag{18, protopack.BytesType}, protopack.LengthPrefix{protopack.Message{
1953				protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix{protopack.Message{
1954					protopack.Tag{15, protopack.BytesType}, protopack.Varint(2),
1955				}},
1956				protopack.Tag{1, protopack.VarintType}, protopack.Varint(0),
1957			}},
1958		}.Marshal(),
1959	},
1960	{
1961		desc: "varint field overruns message",
1962		decodeTo: []proto.Message{
1963			(*testpb.TestAllTypes)(nil),
1964			(*testpb.TestAllExtensions)(nil),
1965		},
1966		wire: protopack.Message{
1967			protopack.Tag{1, protopack.VarintType},
1968		}.Marshal(),
1969	},
1970	{
1971		desc: "bytes field lacks size",
1972		decodeTo: []proto.Message{
1973			(*testpb.TestAllTypes)(nil),
1974			(*testpb.TestAllExtensions)(nil),
1975		},
1976		wire: protopack.Message{
1977			protopack.Tag{18, protopack.BytesType},
1978		}.Marshal(),
1979	},
1980	{
1981		desc: "varint overflow",
1982		decodeTo: []proto.Message{
1983			(*testpb.TestAllTypes)(nil),
1984			(*testpb.TestAllExtensions)(nil),
1985		},
1986		wire: protopack.Message{
1987			protopack.Tag{1, protopack.VarintType},
1988			protopack.Raw("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02"),
1989		}.Marshal(),
1990	},
1991	{
1992		desc: "varint length overrun",
1993		decodeTo: []proto.Message{
1994			(*testpb.TestAllTypes)(nil),
1995			(*testpb.TestAllExtensions)(nil),
1996		},
1997		wire: protopack.Message{
1998			protopack.Tag{1, protopack.VarintType},
1999			protopack.Raw("\xff\xff\xff\xff\xff\xff\xff\xff\xff"),
2000		}.Marshal(),
2001	},
2002}
2003
2004type filterResolver struct {
2005	filter   func(name protoreflect.FullName) bool
2006	resolver protoregistry.ExtensionTypeResolver
2007}
2008
2009func (f filterResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
2010	if !f.filter(field) {
2011		return nil, protoregistry.NotFound
2012	}
2013	return f.resolver.FindExtensionByName(field)
2014}
2015
2016func (f filterResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
2017	xt, err := f.resolver.FindExtensionByNumber(message, field)
2018	if err != nil {
2019		return nil, err
2020	}
2021	if !f.filter(xt.TypeDescriptor().FullName()) {
2022		return nil, protoregistry.NotFound
2023	}
2024	return xt, nil
2025}
2026