xref: /aosp_15_r20/external/golang-protobuf/encoding/prototext/encode_test.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2018 The Go Authors. All rights reserved.
2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style
3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file.
4*1c12ee1eSDan Willemsen
5*1c12ee1eSDan Willemsenpackage prototext_test
6*1c12ee1eSDan Willemsen
7*1c12ee1eSDan Willemsenimport (
8*1c12ee1eSDan Willemsen	"math"
9*1c12ee1eSDan Willemsen	"testing"
10*1c12ee1eSDan Willemsen
11*1c12ee1eSDan Willemsen	"github.com/google/go-cmp/cmp"
12*1c12ee1eSDan Willemsen
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/encoding/prototext"
14*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/detrand"
15*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/flags"
16*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/proto"
17*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoregistry"
18*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/testing/protopack"
19*1c12ee1eSDan Willemsen
20*1c12ee1eSDan Willemsen	pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
21*1c12ee1eSDan Willemsen	pb3 "google.golang.org/protobuf/internal/testprotos/textpb3"
22*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/anypb"
23*1c12ee1eSDan Willemsen)
24*1c12ee1eSDan Willemsen
25*1c12ee1eSDan Willemsenfunc init() {
26*1c12ee1eSDan Willemsen	// Disable detrand to enable direct comparisons on outputs.
27*1c12ee1eSDan Willemsen	detrand.Disable()
28*1c12ee1eSDan Willemsen}
29*1c12ee1eSDan Willemsen
30*1c12ee1eSDan Willemsenfunc TestMarshal(t *testing.T) {
31*1c12ee1eSDan Willemsen	tests := []struct {
32*1c12ee1eSDan Willemsen		desc    string
33*1c12ee1eSDan Willemsen		mo      prototext.MarshalOptions
34*1c12ee1eSDan Willemsen		input   proto.Message
35*1c12ee1eSDan Willemsen		want    string
36*1c12ee1eSDan Willemsen		wantErr bool // TODO: Verify error message content.
37*1c12ee1eSDan Willemsen		skip    bool
38*1c12ee1eSDan Willemsen	}{{
39*1c12ee1eSDan Willemsen		desc:  "proto2 optional scalars not set",
40*1c12ee1eSDan Willemsen		input: &pb2.Scalars{},
41*1c12ee1eSDan Willemsen		want:  "",
42*1c12ee1eSDan Willemsen	}, {
43*1c12ee1eSDan Willemsen		desc:  "proto3 scalars not set",
44*1c12ee1eSDan Willemsen		input: &pb3.Scalars{},
45*1c12ee1eSDan Willemsen		want:  "",
46*1c12ee1eSDan Willemsen	}, {
47*1c12ee1eSDan Willemsen		desc:  "proto3 optional not set",
48*1c12ee1eSDan Willemsen		input: &pb3.Proto3Optional{},
49*1c12ee1eSDan Willemsen		want:  "",
50*1c12ee1eSDan Willemsen	}, {
51*1c12ee1eSDan Willemsen		desc: "proto2 optional scalars set to zero values",
52*1c12ee1eSDan Willemsen		input: &pb2.Scalars{
53*1c12ee1eSDan Willemsen			OptBool:     proto.Bool(false),
54*1c12ee1eSDan Willemsen			OptInt32:    proto.Int32(0),
55*1c12ee1eSDan Willemsen			OptInt64:    proto.Int64(0),
56*1c12ee1eSDan Willemsen			OptUint32:   proto.Uint32(0),
57*1c12ee1eSDan Willemsen			OptUint64:   proto.Uint64(0),
58*1c12ee1eSDan Willemsen			OptSint32:   proto.Int32(0),
59*1c12ee1eSDan Willemsen			OptSint64:   proto.Int64(0),
60*1c12ee1eSDan Willemsen			OptFixed32:  proto.Uint32(0),
61*1c12ee1eSDan Willemsen			OptFixed64:  proto.Uint64(0),
62*1c12ee1eSDan Willemsen			OptSfixed32: proto.Int32(0),
63*1c12ee1eSDan Willemsen			OptSfixed64: proto.Int64(0),
64*1c12ee1eSDan Willemsen			OptFloat:    proto.Float32(0),
65*1c12ee1eSDan Willemsen			OptDouble:   proto.Float64(0),
66*1c12ee1eSDan Willemsen			OptBytes:    []byte{},
67*1c12ee1eSDan Willemsen			OptString:   proto.String(""),
68*1c12ee1eSDan Willemsen		},
69*1c12ee1eSDan Willemsen		want: `opt_bool: false
70*1c12ee1eSDan Willemsenopt_int32: 0
71*1c12ee1eSDan Willemsenopt_int64: 0
72*1c12ee1eSDan Willemsenopt_uint32: 0
73*1c12ee1eSDan Willemsenopt_uint64: 0
74*1c12ee1eSDan Willemsenopt_sint32: 0
75*1c12ee1eSDan Willemsenopt_sint64: 0
76*1c12ee1eSDan Willemsenopt_fixed32: 0
77*1c12ee1eSDan Willemsenopt_fixed64: 0
78*1c12ee1eSDan Willemsenopt_sfixed32: 0
79*1c12ee1eSDan Willemsenopt_sfixed64: 0
80*1c12ee1eSDan Willemsenopt_float: 0
81*1c12ee1eSDan Willemsenopt_double: 0
82*1c12ee1eSDan Willemsenopt_bytes: ""
83*1c12ee1eSDan Willemsenopt_string: ""
84*1c12ee1eSDan Willemsen`,
85*1c12ee1eSDan Willemsen	}, {
86*1c12ee1eSDan Willemsen		desc: "proto3 optional set to zero values",
87*1c12ee1eSDan Willemsen		input: &pb3.Proto3Optional{
88*1c12ee1eSDan Willemsen			OptBool:    proto.Bool(false),
89*1c12ee1eSDan Willemsen			OptInt32:   proto.Int32(0),
90*1c12ee1eSDan Willemsen			OptInt64:   proto.Int64(0),
91*1c12ee1eSDan Willemsen			OptUint32:  proto.Uint32(0),
92*1c12ee1eSDan Willemsen			OptUint64:  proto.Uint64(0),
93*1c12ee1eSDan Willemsen			OptFloat:   proto.Float32(0),
94*1c12ee1eSDan Willemsen			OptDouble:  proto.Float64(0),
95*1c12ee1eSDan Willemsen			OptString:  proto.String(""),
96*1c12ee1eSDan Willemsen			OptBytes:   []byte{},
97*1c12ee1eSDan Willemsen			OptEnum:    pb3.Enum_ZERO.Enum(),
98*1c12ee1eSDan Willemsen			OptMessage: &pb3.Nested{},
99*1c12ee1eSDan Willemsen		},
100*1c12ee1eSDan Willemsen		want: `opt_bool: false
101*1c12ee1eSDan Willemsenopt_int32: 0
102*1c12ee1eSDan Willemsenopt_int64: 0
103*1c12ee1eSDan Willemsenopt_uint32: 0
104*1c12ee1eSDan Willemsenopt_uint64: 0
105*1c12ee1eSDan Willemsenopt_float: 0
106*1c12ee1eSDan Willemsenopt_double: 0
107*1c12ee1eSDan Willemsenopt_string: ""
108*1c12ee1eSDan Willemsenopt_bytes: ""
109*1c12ee1eSDan Willemsenopt_enum: ZERO
110*1c12ee1eSDan Willemsenopt_message: {}
111*1c12ee1eSDan Willemsen`,
112*1c12ee1eSDan Willemsen	}, {
113*1c12ee1eSDan Willemsen		desc: "proto3 scalars set to zero values",
114*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
115*1c12ee1eSDan Willemsen			SBool:     false,
116*1c12ee1eSDan Willemsen			SInt32:    0,
117*1c12ee1eSDan Willemsen			SInt64:    0,
118*1c12ee1eSDan Willemsen			SUint32:   0,
119*1c12ee1eSDan Willemsen			SUint64:   0,
120*1c12ee1eSDan Willemsen			SSint32:   0,
121*1c12ee1eSDan Willemsen			SSint64:   0,
122*1c12ee1eSDan Willemsen			SFixed32:  0,
123*1c12ee1eSDan Willemsen			SFixed64:  0,
124*1c12ee1eSDan Willemsen			SSfixed32: 0,
125*1c12ee1eSDan Willemsen			SSfixed64: 0,
126*1c12ee1eSDan Willemsen			SFloat:    0,
127*1c12ee1eSDan Willemsen			SDouble:   0,
128*1c12ee1eSDan Willemsen			SBytes:    []byte{},
129*1c12ee1eSDan Willemsen			SString:   "",
130*1c12ee1eSDan Willemsen		},
131*1c12ee1eSDan Willemsen		want: "",
132*1c12ee1eSDan Willemsen	}, {
133*1c12ee1eSDan Willemsen		desc: "proto2 optional scalars set to some values",
134*1c12ee1eSDan Willemsen		input: &pb2.Scalars{
135*1c12ee1eSDan Willemsen			OptBool:     proto.Bool(true),
136*1c12ee1eSDan Willemsen			OptInt32:    proto.Int32(0xff),
137*1c12ee1eSDan Willemsen			OptInt64:    proto.Int64(0xdeadbeef),
138*1c12ee1eSDan Willemsen			OptUint32:   proto.Uint32(47),
139*1c12ee1eSDan Willemsen			OptUint64:   proto.Uint64(0xdeadbeef),
140*1c12ee1eSDan Willemsen			OptSint32:   proto.Int32(-1001),
141*1c12ee1eSDan Willemsen			OptSint64:   proto.Int64(-0xffff),
142*1c12ee1eSDan Willemsen			OptFixed64:  proto.Uint64(64),
143*1c12ee1eSDan Willemsen			OptSfixed32: proto.Int32(-32),
144*1c12ee1eSDan Willemsen			OptFloat:    proto.Float32(1.02),
145*1c12ee1eSDan Willemsen			OptDouble:   proto.Float64(1.0199999809265137),
146*1c12ee1eSDan Willemsen			OptBytes:    []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
147*1c12ee1eSDan Willemsen			OptString:   proto.String("谷歌"),
148*1c12ee1eSDan Willemsen		},
149*1c12ee1eSDan Willemsen		want: `opt_bool: true
150*1c12ee1eSDan Willemsenopt_int32: 255
151*1c12ee1eSDan Willemsenopt_int64: 3735928559
152*1c12ee1eSDan Willemsenopt_uint32: 47
153*1c12ee1eSDan Willemsenopt_uint64: 3735928559
154*1c12ee1eSDan Willemsenopt_sint32: -1001
155*1c12ee1eSDan Willemsenopt_sint64: -65535
156*1c12ee1eSDan Willemsenopt_fixed64: 64
157*1c12ee1eSDan Willemsenopt_sfixed32: -32
158*1c12ee1eSDan Willemsenopt_float: 1.02
159*1c12ee1eSDan Willemsenopt_double: 1.0199999809265137
160*1c12ee1eSDan Willemsenopt_bytes: "谷歌"
161*1c12ee1eSDan Willemsenopt_string: "谷歌"
162*1c12ee1eSDan Willemsen`,
163*1c12ee1eSDan Willemsen	}, {
164*1c12ee1eSDan Willemsen		desc: "proto2 string with invalid UTF-8",
165*1c12ee1eSDan Willemsen		input: &pb2.Scalars{
166*1c12ee1eSDan Willemsen			OptString: proto.String("abc\xff"),
167*1c12ee1eSDan Willemsen		},
168*1c12ee1eSDan Willemsen		want: `opt_string: "abc\xff"
169*1c12ee1eSDan Willemsen`,
170*1c12ee1eSDan Willemsen	}, {
171*1c12ee1eSDan Willemsen		desc: "proto3 string with invalid UTF-8",
172*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
173*1c12ee1eSDan Willemsen			SString: "abc\xff",
174*1c12ee1eSDan Willemsen		},
175*1c12ee1eSDan Willemsen		wantErr: true,
176*1c12ee1eSDan Willemsen	}, {
177*1c12ee1eSDan Willemsen		desc: "float nan",
178*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
179*1c12ee1eSDan Willemsen			SFloat: float32(math.NaN()),
180*1c12ee1eSDan Willemsen		},
181*1c12ee1eSDan Willemsen		want: "s_float: nan\n",
182*1c12ee1eSDan Willemsen	}, {
183*1c12ee1eSDan Willemsen		desc: "float positive infinity",
184*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
185*1c12ee1eSDan Willemsen			SFloat: float32(math.Inf(1)),
186*1c12ee1eSDan Willemsen		},
187*1c12ee1eSDan Willemsen		want: "s_float: inf\n",
188*1c12ee1eSDan Willemsen	}, {
189*1c12ee1eSDan Willemsen		desc: "float negative infinity",
190*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
191*1c12ee1eSDan Willemsen			SFloat: float32(math.Inf(-1)),
192*1c12ee1eSDan Willemsen		},
193*1c12ee1eSDan Willemsen		want: "s_float: -inf\n",
194*1c12ee1eSDan Willemsen	}, {
195*1c12ee1eSDan Willemsen		desc: "double nan",
196*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
197*1c12ee1eSDan Willemsen			SDouble: math.NaN(),
198*1c12ee1eSDan Willemsen		},
199*1c12ee1eSDan Willemsen		want: "s_double: nan\n",
200*1c12ee1eSDan Willemsen	}, {
201*1c12ee1eSDan Willemsen		desc: "double positive infinity",
202*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
203*1c12ee1eSDan Willemsen			SDouble: math.Inf(1),
204*1c12ee1eSDan Willemsen		},
205*1c12ee1eSDan Willemsen		want: "s_double: inf\n",
206*1c12ee1eSDan Willemsen	}, {
207*1c12ee1eSDan Willemsen		desc: "double negative infinity",
208*1c12ee1eSDan Willemsen		input: &pb3.Scalars{
209*1c12ee1eSDan Willemsen			SDouble: math.Inf(-1),
210*1c12ee1eSDan Willemsen		},
211*1c12ee1eSDan Willemsen		want: "s_double: -inf\n",
212*1c12ee1eSDan Willemsen	}, {
213*1c12ee1eSDan Willemsen		desc:  "proto2 enum not set",
214*1c12ee1eSDan Willemsen		input: &pb2.Enums{},
215*1c12ee1eSDan Willemsen		want:  "",
216*1c12ee1eSDan Willemsen	}, {
217*1c12ee1eSDan Willemsen		desc: "proto2 enum set to zero value",
218*1c12ee1eSDan Willemsen		input: &pb2.Enums{
219*1c12ee1eSDan Willemsen			OptEnum:       pb2.Enum(0).Enum(),
220*1c12ee1eSDan Willemsen			OptNestedEnum: pb2.Enums_NestedEnum(0).Enum(),
221*1c12ee1eSDan Willemsen		},
222*1c12ee1eSDan Willemsen		want: `opt_enum: 0
223*1c12ee1eSDan Willemsenopt_nested_enum: 0
224*1c12ee1eSDan Willemsen`,
225*1c12ee1eSDan Willemsen	}, {
226*1c12ee1eSDan Willemsen		desc: "proto2 enum",
227*1c12ee1eSDan Willemsen		input: &pb2.Enums{
228*1c12ee1eSDan Willemsen			OptEnum:       pb2.Enum_ONE.Enum(),
229*1c12ee1eSDan Willemsen			OptNestedEnum: pb2.Enums_UNO.Enum(),
230*1c12ee1eSDan Willemsen		},
231*1c12ee1eSDan Willemsen		want: `opt_enum: ONE
232*1c12ee1eSDan Willemsenopt_nested_enum: UNO
233*1c12ee1eSDan Willemsen`,
234*1c12ee1eSDan Willemsen	}, {
235*1c12ee1eSDan Willemsen		desc: "proto2 enum set to numeric values",
236*1c12ee1eSDan Willemsen		input: &pb2.Enums{
237*1c12ee1eSDan Willemsen			OptEnum:       pb2.Enum(2).Enum(),
238*1c12ee1eSDan Willemsen			OptNestedEnum: pb2.Enums_NestedEnum(2).Enum(),
239*1c12ee1eSDan Willemsen		},
240*1c12ee1eSDan Willemsen		want: `opt_enum: TWO
241*1c12ee1eSDan Willemsenopt_nested_enum: DOS
242*1c12ee1eSDan Willemsen`,
243*1c12ee1eSDan Willemsen	}, {
244*1c12ee1eSDan Willemsen		desc: "proto2 enum set to unnamed numeric values",
245*1c12ee1eSDan Willemsen		input: &pb2.Enums{
246*1c12ee1eSDan Willemsen			OptEnum:       pb2.Enum(101).Enum(),
247*1c12ee1eSDan Willemsen			OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
248*1c12ee1eSDan Willemsen		},
249*1c12ee1eSDan Willemsen		want: `opt_enum: 101
250*1c12ee1eSDan Willemsenopt_nested_enum: -101
251*1c12ee1eSDan Willemsen`,
252*1c12ee1eSDan Willemsen	}, {
253*1c12ee1eSDan Willemsen		desc:  "proto3 enum not set",
254*1c12ee1eSDan Willemsen		input: &pb3.Enums{},
255*1c12ee1eSDan Willemsen		want:  "",
256*1c12ee1eSDan Willemsen	}, {
257*1c12ee1eSDan Willemsen		desc: "proto3 enum set to zero value",
258*1c12ee1eSDan Willemsen		input: &pb3.Enums{
259*1c12ee1eSDan Willemsen			SEnum:       pb3.Enum_ZERO,
260*1c12ee1eSDan Willemsen			SNestedEnum: pb3.Enums_CERO,
261*1c12ee1eSDan Willemsen		},
262*1c12ee1eSDan Willemsen		want: "",
263*1c12ee1eSDan Willemsen	}, {
264*1c12ee1eSDan Willemsen		desc: "proto3 enum",
265*1c12ee1eSDan Willemsen		input: &pb3.Enums{
266*1c12ee1eSDan Willemsen			SEnum:       pb3.Enum_ONE,
267*1c12ee1eSDan Willemsen			SNestedEnum: pb3.Enums_UNO,
268*1c12ee1eSDan Willemsen		},
269*1c12ee1eSDan Willemsen		want: `s_enum: ONE
270*1c12ee1eSDan Willemsens_nested_enum: UNO
271*1c12ee1eSDan Willemsen`,
272*1c12ee1eSDan Willemsen	}, {
273*1c12ee1eSDan Willemsen		desc: "proto3 enum set to numeric values",
274*1c12ee1eSDan Willemsen		input: &pb3.Enums{
275*1c12ee1eSDan Willemsen			SEnum:       2,
276*1c12ee1eSDan Willemsen			SNestedEnum: 2,
277*1c12ee1eSDan Willemsen		},
278*1c12ee1eSDan Willemsen		want: `s_enum: TWO
279*1c12ee1eSDan Willemsens_nested_enum: DOS
280*1c12ee1eSDan Willemsen`,
281*1c12ee1eSDan Willemsen	}, {
282*1c12ee1eSDan Willemsen		desc: "proto3 enum set to unnamed numeric values",
283*1c12ee1eSDan Willemsen		input: &pb3.Enums{
284*1c12ee1eSDan Willemsen			SEnum:       -47,
285*1c12ee1eSDan Willemsen			SNestedEnum: 47,
286*1c12ee1eSDan Willemsen		},
287*1c12ee1eSDan Willemsen		want: `s_enum: -47
288*1c12ee1eSDan Willemsens_nested_enum: 47
289*1c12ee1eSDan Willemsen`,
290*1c12ee1eSDan Willemsen	}, {
291*1c12ee1eSDan Willemsen		desc:  "proto2 nested message not set",
292*1c12ee1eSDan Willemsen		input: &pb2.Nests{},
293*1c12ee1eSDan Willemsen		want:  "",
294*1c12ee1eSDan Willemsen	}, {
295*1c12ee1eSDan Willemsen		desc: "proto2 nested message set to empty",
296*1c12ee1eSDan Willemsen		input: &pb2.Nests{
297*1c12ee1eSDan Willemsen			OptNested: &pb2.Nested{},
298*1c12ee1eSDan Willemsen			Optgroup:  &pb2.Nests_OptGroup{},
299*1c12ee1eSDan Willemsen		},
300*1c12ee1eSDan Willemsen		want: `opt_nested: {}
301*1c12ee1eSDan WillemsenOptGroup: {}
302*1c12ee1eSDan Willemsen`,
303*1c12ee1eSDan Willemsen	}, {
304*1c12ee1eSDan Willemsen		desc: "proto2 nested messages",
305*1c12ee1eSDan Willemsen		input: &pb2.Nests{
306*1c12ee1eSDan Willemsen			OptNested: &pb2.Nested{
307*1c12ee1eSDan Willemsen				OptString: proto.String("nested message"),
308*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
309*1c12ee1eSDan Willemsen					OptString: proto.String("another nested message"),
310*1c12ee1eSDan Willemsen				},
311*1c12ee1eSDan Willemsen			},
312*1c12ee1eSDan Willemsen		},
313*1c12ee1eSDan Willemsen		want: `opt_nested: {
314*1c12ee1eSDan Willemsen  opt_string: "nested message"
315*1c12ee1eSDan Willemsen  opt_nested: {
316*1c12ee1eSDan Willemsen    opt_string: "another nested message"
317*1c12ee1eSDan Willemsen  }
318*1c12ee1eSDan Willemsen}
319*1c12ee1eSDan Willemsen`,
320*1c12ee1eSDan Willemsen	}, {
321*1c12ee1eSDan Willemsen		desc: "proto2 groups",
322*1c12ee1eSDan Willemsen		input: &pb2.Nests{
323*1c12ee1eSDan Willemsen			Optgroup: &pb2.Nests_OptGroup{
324*1c12ee1eSDan Willemsen				OptString: proto.String("inside a group"),
325*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
326*1c12ee1eSDan Willemsen					OptString: proto.String("nested message inside a group"),
327*1c12ee1eSDan Willemsen				},
328*1c12ee1eSDan Willemsen				Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
329*1c12ee1eSDan Willemsen					OptFixed32: proto.Uint32(47),
330*1c12ee1eSDan Willemsen				},
331*1c12ee1eSDan Willemsen			},
332*1c12ee1eSDan Willemsen		},
333*1c12ee1eSDan Willemsen		want: `OptGroup: {
334*1c12ee1eSDan Willemsen  opt_string: "inside a group"
335*1c12ee1eSDan Willemsen  opt_nested: {
336*1c12ee1eSDan Willemsen    opt_string: "nested message inside a group"
337*1c12ee1eSDan Willemsen  }
338*1c12ee1eSDan Willemsen  OptNestedGroup: {
339*1c12ee1eSDan Willemsen    opt_fixed32: 47
340*1c12ee1eSDan Willemsen  }
341*1c12ee1eSDan Willemsen}
342*1c12ee1eSDan Willemsen`,
343*1c12ee1eSDan Willemsen	}, {
344*1c12ee1eSDan Willemsen		desc:  "proto3 nested message not set",
345*1c12ee1eSDan Willemsen		input: &pb3.Nests{},
346*1c12ee1eSDan Willemsen		want:  "",
347*1c12ee1eSDan Willemsen	}, {
348*1c12ee1eSDan Willemsen		desc: "proto3 nested message set to empty",
349*1c12ee1eSDan Willemsen		input: &pb3.Nests{
350*1c12ee1eSDan Willemsen			SNested: &pb3.Nested{},
351*1c12ee1eSDan Willemsen		},
352*1c12ee1eSDan Willemsen		want: "s_nested: {}\n",
353*1c12ee1eSDan Willemsen	}, {
354*1c12ee1eSDan Willemsen		desc: "proto3 nested message",
355*1c12ee1eSDan Willemsen		input: &pb3.Nests{
356*1c12ee1eSDan Willemsen			SNested: &pb3.Nested{
357*1c12ee1eSDan Willemsen				SString: "nested message",
358*1c12ee1eSDan Willemsen				SNested: &pb3.Nested{
359*1c12ee1eSDan Willemsen					SString: "another nested message",
360*1c12ee1eSDan Willemsen				},
361*1c12ee1eSDan Willemsen			},
362*1c12ee1eSDan Willemsen		},
363*1c12ee1eSDan Willemsen		want: `s_nested: {
364*1c12ee1eSDan Willemsen  s_string: "nested message"
365*1c12ee1eSDan Willemsen  s_nested: {
366*1c12ee1eSDan Willemsen    s_string: "another nested message"
367*1c12ee1eSDan Willemsen  }
368*1c12ee1eSDan Willemsen}
369*1c12ee1eSDan Willemsen`,
370*1c12ee1eSDan Willemsen	}, {
371*1c12ee1eSDan Willemsen		desc: "proto3 nested message contains invalid UTF-8",
372*1c12ee1eSDan Willemsen		input: &pb3.Nests{
373*1c12ee1eSDan Willemsen			SNested: &pb3.Nested{
374*1c12ee1eSDan Willemsen				SString: "abc\xff",
375*1c12ee1eSDan Willemsen			},
376*1c12ee1eSDan Willemsen		},
377*1c12ee1eSDan Willemsen		wantErr: true,
378*1c12ee1eSDan Willemsen	}, {
379*1c12ee1eSDan Willemsen		desc:  "oneof not set",
380*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{},
381*1c12ee1eSDan Willemsen		want:  "",
382*1c12ee1eSDan Willemsen	}, {
383*1c12ee1eSDan Willemsen		desc: "oneof set to empty string",
384*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{
385*1c12ee1eSDan Willemsen			Union: &pb3.Oneofs_OneofString{},
386*1c12ee1eSDan Willemsen		},
387*1c12ee1eSDan Willemsen		want: `oneof_string: ""
388*1c12ee1eSDan Willemsen`,
389*1c12ee1eSDan Willemsen	}, {
390*1c12ee1eSDan Willemsen		desc: "oneof set to string",
391*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{
392*1c12ee1eSDan Willemsen			Union: &pb3.Oneofs_OneofString{
393*1c12ee1eSDan Willemsen				OneofString: "hello",
394*1c12ee1eSDan Willemsen			},
395*1c12ee1eSDan Willemsen		},
396*1c12ee1eSDan Willemsen		want: `oneof_string: "hello"
397*1c12ee1eSDan Willemsen`,
398*1c12ee1eSDan Willemsen	}, {
399*1c12ee1eSDan Willemsen		desc: "oneof set to enum",
400*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{
401*1c12ee1eSDan Willemsen			Union: &pb3.Oneofs_OneofEnum{
402*1c12ee1eSDan Willemsen				OneofEnum: pb3.Enum_ZERO,
403*1c12ee1eSDan Willemsen			},
404*1c12ee1eSDan Willemsen		},
405*1c12ee1eSDan Willemsen		want: `oneof_enum: ZERO
406*1c12ee1eSDan Willemsen`,
407*1c12ee1eSDan Willemsen	}, {
408*1c12ee1eSDan Willemsen		desc: "oneof set to empty message",
409*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{
410*1c12ee1eSDan Willemsen			Union: &pb3.Oneofs_OneofNested{
411*1c12ee1eSDan Willemsen				OneofNested: &pb3.Nested{},
412*1c12ee1eSDan Willemsen			},
413*1c12ee1eSDan Willemsen		},
414*1c12ee1eSDan Willemsen		want: "oneof_nested: {}\n",
415*1c12ee1eSDan Willemsen	}, {
416*1c12ee1eSDan Willemsen		desc: "oneof set to message",
417*1c12ee1eSDan Willemsen		input: &pb3.Oneofs{
418*1c12ee1eSDan Willemsen			Union: &pb3.Oneofs_OneofNested{
419*1c12ee1eSDan Willemsen				OneofNested: &pb3.Nested{
420*1c12ee1eSDan Willemsen					SString: "nested message",
421*1c12ee1eSDan Willemsen				},
422*1c12ee1eSDan Willemsen			},
423*1c12ee1eSDan Willemsen		},
424*1c12ee1eSDan Willemsen		want: `oneof_nested: {
425*1c12ee1eSDan Willemsen  s_string: "nested message"
426*1c12ee1eSDan Willemsen}
427*1c12ee1eSDan Willemsen`,
428*1c12ee1eSDan Willemsen	}, {
429*1c12ee1eSDan Willemsen		desc:  "repeated fields not set",
430*1c12ee1eSDan Willemsen		input: &pb2.Repeats{},
431*1c12ee1eSDan Willemsen		want:  "",
432*1c12ee1eSDan Willemsen	}, {
433*1c12ee1eSDan Willemsen		desc: "repeated fields set to empty slices",
434*1c12ee1eSDan Willemsen		input: &pb2.Repeats{
435*1c12ee1eSDan Willemsen			RptBool:   []bool{},
436*1c12ee1eSDan Willemsen			RptInt32:  []int32{},
437*1c12ee1eSDan Willemsen			RptInt64:  []int64{},
438*1c12ee1eSDan Willemsen			RptUint32: []uint32{},
439*1c12ee1eSDan Willemsen			RptUint64: []uint64{},
440*1c12ee1eSDan Willemsen			RptFloat:  []float32{},
441*1c12ee1eSDan Willemsen			RptDouble: []float64{},
442*1c12ee1eSDan Willemsen			RptBytes:  [][]byte{},
443*1c12ee1eSDan Willemsen		},
444*1c12ee1eSDan Willemsen		want: "",
445*1c12ee1eSDan Willemsen	}, {
446*1c12ee1eSDan Willemsen		desc: "repeated fields set to some values",
447*1c12ee1eSDan Willemsen		input: &pb2.Repeats{
448*1c12ee1eSDan Willemsen			RptBool:   []bool{true, false, true, true},
449*1c12ee1eSDan Willemsen			RptInt32:  []int32{1, 6, 0, 0},
450*1c12ee1eSDan Willemsen			RptInt64:  []int64{-64, 47},
451*1c12ee1eSDan Willemsen			RptUint32: []uint32{0xff, 0xffff},
452*1c12ee1eSDan Willemsen			RptUint64: []uint64{0xdeadbeef},
453*1c12ee1eSDan Willemsen			RptFloat:  []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
454*1c12ee1eSDan Willemsen			RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
455*1c12ee1eSDan Willemsen			RptString: []string{"hello", "世界"},
456*1c12ee1eSDan Willemsen			RptBytes: [][]byte{
457*1c12ee1eSDan Willemsen				[]byte("hello"),
458*1c12ee1eSDan Willemsen				[]byte("\xe4\xb8\x96\xe7\x95\x8c"),
459*1c12ee1eSDan Willemsen			},
460*1c12ee1eSDan Willemsen		},
461*1c12ee1eSDan Willemsen		want: `rpt_bool: true
462*1c12ee1eSDan Willemsenrpt_bool: false
463*1c12ee1eSDan Willemsenrpt_bool: true
464*1c12ee1eSDan Willemsenrpt_bool: true
465*1c12ee1eSDan Willemsenrpt_int32: 1
466*1c12ee1eSDan Willemsenrpt_int32: 6
467*1c12ee1eSDan Willemsenrpt_int32: 0
468*1c12ee1eSDan Willemsenrpt_int32: 0
469*1c12ee1eSDan Willemsenrpt_int64: -64
470*1c12ee1eSDan Willemsenrpt_int64: 47
471*1c12ee1eSDan Willemsenrpt_uint32: 255
472*1c12ee1eSDan Willemsenrpt_uint32: 65535
473*1c12ee1eSDan Willemsenrpt_uint64: 3735928559
474*1c12ee1eSDan Willemsenrpt_float: nan
475*1c12ee1eSDan Willemsenrpt_float: inf
476*1c12ee1eSDan Willemsenrpt_float: -inf
477*1c12ee1eSDan Willemsenrpt_float: 1.034
478*1c12ee1eSDan Willemsenrpt_double: nan
479*1c12ee1eSDan Willemsenrpt_double: inf
480*1c12ee1eSDan Willemsenrpt_double: -inf
481*1c12ee1eSDan Willemsenrpt_double: 1.23e-308
482*1c12ee1eSDan Willemsenrpt_string: "hello"
483*1c12ee1eSDan Willemsenrpt_string: "世界"
484*1c12ee1eSDan Willemsenrpt_bytes: "hello"
485*1c12ee1eSDan Willemsenrpt_bytes: "世界"
486*1c12ee1eSDan Willemsen`,
487*1c12ee1eSDan Willemsen	}, {
488*1c12ee1eSDan Willemsen		desc: "repeated proto2 contains invalid UTF-8",
489*1c12ee1eSDan Willemsen		input: &pb2.Repeats{
490*1c12ee1eSDan Willemsen			RptString: []string{"abc\xff"},
491*1c12ee1eSDan Willemsen		},
492*1c12ee1eSDan Willemsen		want: `rpt_string: "abc\xff"
493*1c12ee1eSDan Willemsen`,
494*1c12ee1eSDan Willemsen	}, {
495*1c12ee1eSDan Willemsen		desc: "repeated proto3 contains invalid UTF-8",
496*1c12ee1eSDan Willemsen		input: &pb3.Repeats{
497*1c12ee1eSDan Willemsen			RptString: []string{"abc\xff"},
498*1c12ee1eSDan Willemsen		},
499*1c12ee1eSDan Willemsen		wantErr: true,
500*1c12ee1eSDan Willemsen	}, {
501*1c12ee1eSDan Willemsen		desc: "repeated enums",
502*1c12ee1eSDan Willemsen		input: &pb2.Enums{
503*1c12ee1eSDan Willemsen			RptEnum:       []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
504*1c12ee1eSDan Willemsen			RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
505*1c12ee1eSDan Willemsen		},
506*1c12ee1eSDan Willemsen		want: `rpt_enum: ONE
507*1c12ee1eSDan Willemsenrpt_enum: TWO
508*1c12ee1eSDan Willemsenrpt_enum: TEN
509*1c12ee1eSDan Willemsenrpt_enum: 42
510*1c12ee1eSDan Willemsenrpt_nested_enum: DOS
511*1c12ee1eSDan Willemsenrpt_nested_enum: 47
512*1c12ee1eSDan Willemsenrpt_nested_enum: DIEZ
513*1c12ee1eSDan Willemsen`,
514*1c12ee1eSDan Willemsen	}, {
515*1c12ee1eSDan Willemsen		desc: "repeated messages set to empty",
516*1c12ee1eSDan Willemsen		input: &pb2.Nests{
517*1c12ee1eSDan Willemsen			RptNested: []*pb2.Nested{},
518*1c12ee1eSDan Willemsen			Rptgroup:  []*pb2.Nests_RptGroup{},
519*1c12ee1eSDan Willemsen		},
520*1c12ee1eSDan Willemsen		want: "",
521*1c12ee1eSDan Willemsen	}, {
522*1c12ee1eSDan Willemsen		desc: "repeated messages",
523*1c12ee1eSDan Willemsen		input: &pb2.Nests{
524*1c12ee1eSDan Willemsen			RptNested: []*pb2.Nested{
525*1c12ee1eSDan Willemsen				{
526*1c12ee1eSDan Willemsen					OptString: proto.String("repeat nested one"),
527*1c12ee1eSDan Willemsen				},
528*1c12ee1eSDan Willemsen				{
529*1c12ee1eSDan Willemsen					OptString: proto.String("repeat nested two"),
530*1c12ee1eSDan Willemsen					OptNested: &pb2.Nested{
531*1c12ee1eSDan Willemsen						OptString: proto.String("inside repeat nested two"),
532*1c12ee1eSDan Willemsen					},
533*1c12ee1eSDan Willemsen				},
534*1c12ee1eSDan Willemsen				{},
535*1c12ee1eSDan Willemsen			},
536*1c12ee1eSDan Willemsen		},
537*1c12ee1eSDan Willemsen		want: `rpt_nested: {
538*1c12ee1eSDan Willemsen  opt_string: "repeat nested one"
539*1c12ee1eSDan Willemsen}
540*1c12ee1eSDan Willemsenrpt_nested: {
541*1c12ee1eSDan Willemsen  opt_string: "repeat nested two"
542*1c12ee1eSDan Willemsen  opt_nested: {
543*1c12ee1eSDan Willemsen    opt_string: "inside repeat nested two"
544*1c12ee1eSDan Willemsen  }
545*1c12ee1eSDan Willemsen}
546*1c12ee1eSDan Willemsenrpt_nested: {}
547*1c12ee1eSDan Willemsen`,
548*1c12ee1eSDan Willemsen	}, {
549*1c12ee1eSDan Willemsen		desc: "repeated messages contains nil value",
550*1c12ee1eSDan Willemsen		input: &pb2.Nests{
551*1c12ee1eSDan Willemsen			RptNested: []*pb2.Nested{nil, {}},
552*1c12ee1eSDan Willemsen		},
553*1c12ee1eSDan Willemsen		want: `rpt_nested: {}
554*1c12ee1eSDan Willemsenrpt_nested: {}
555*1c12ee1eSDan Willemsen`,
556*1c12ee1eSDan Willemsen	}, {
557*1c12ee1eSDan Willemsen		desc: "repeated groups",
558*1c12ee1eSDan Willemsen		input: &pb2.Nests{
559*1c12ee1eSDan Willemsen			Rptgroup: []*pb2.Nests_RptGroup{
560*1c12ee1eSDan Willemsen				{
561*1c12ee1eSDan Willemsen					RptString: []string{"hello", "world"},
562*1c12ee1eSDan Willemsen				},
563*1c12ee1eSDan Willemsen				{},
564*1c12ee1eSDan Willemsen				nil,
565*1c12ee1eSDan Willemsen			},
566*1c12ee1eSDan Willemsen		},
567*1c12ee1eSDan Willemsen		want: `RptGroup: {
568*1c12ee1eSDan Willemsen  rpt_string: "hello"
569*1c12ee1eSDan Willemsen  rpt_string: "world"
570*1c12ee1eSDan Willemsen}
571*1c12ee1eSDan WillemsenRptGroup: {}
572*1c12ee1eSDan WillemsenRptGroup: {}
573*1c12ee1eSDan Willemsen`,
574*1c12ee1eSDan Willemsen	}, {
575*1c12ee1eSDan Willemsen		desc:  "map fields not set",
576*1c12ee1eSDan Willemsen		input: &pb3.Maps{},
577*1c12ee1eSDan Willemsen		want:  "",
578*1c12ee1eSDan Willemsen	}, {
579*1c12ee1eSDan Willemsen		desc: "map fields set to empty",
580*1c12ee1eSDan Willemsen		input: &pb3.Maps{
581*1c12ee1eSDan Willemsen			Int32ToStr:   map[int32]string{},
582*1c12ee1eSDan Willemsen			BoolToUint32: map[bool]uint32{},
583*1c12ee1eSDan Willemsen			Uint64ToEnum: map[uint64]pb3.Enum{},
584*1c12ee1eSDan Willemsen			StrToNested:  map[string]*pb3.Nested{},
585*1c12ee1eSDan Willemsen			StrToOneofs:  map[string]*pb3.Oneofs{},
586*1c12ee1eSDan Willemsen		},
587*1c12ee1eSDan Willemsen		want: "",
588*1c12ee1eSDan Willemsen	}, {
589*1c12ee1eSDan Willemsen		desc: "map fields 1",
590*1c12ee1eSDan Willemsen		input: &pb3.Maps{
591*1c12ee1eSDan Willemsen			Int32ToStr: map[int32]string{
592*1c12ee1eSDan Willemsen				-101: "-101",
593*1c12ee1eSDan Willemsen				0xff: "0xff",
594*1c12ee1eSDan Willemsen				0:    "zero",
595*1c12ee1eSDan Willemsen			},
596*1c12ee1eSDan Willemsen			BoolToUint32: map[bool]uint32{
597*1c12ee1eSDan Willemsen				true:  42,
598*1c12ee1eSDan Willemsen				false: 101,
599*1c12ee1eSDan Willemsen			},
600*1c12ee1eSDan Willemsen		},
601*1c12ee1eSDan Willemsen		want: `int32_to_str: {
602*1c12ee1eSDan Willemsen  key: -101
603*1c12ee1eSDan Willemsen  value: "-101"
604*1c12ee1eSDan Willemsen}
605*1c12ee1eSDan Willemsenint32_to_str: {
606*1c12ee1eSDan Willemsen  key: 0
607*1c12ee1eSDan Willemsen  value: "zero"
608*1c12ee1eSDan Willemsen}
609*1c12ee1eSDan Willemsenint32_to_str: {
610*1c12ee1eSDan Willemsen  key: 255
611*1c12ee1eSDan Willemsen  value: "0xff"
612*1c12ee1eSDan Willemsen}
613*1c12ee1eSDan Willemsenbool_to_uint32: {
614*1c12ee1eSDan Willemsen  key: false
615*1c12ee1eSDan Willemsen  value: 101
616*1c12ee1eSDan Willemsen}
617*1c12ee1eSDan Willemsenbool_to_uint32: {
618*1c12ee1eSDan Willemsen  key: true
619*1c12ee1eSDan Willemsen  value: 42
620*1c12ee1eSDan Willemsen}
621*1c12ee1eSDan Willemsen`,
622*1c12ee1eSDan Willemsen	}, {
623*1c12ee1eSDan Willemsen		desc: "map fields 2",
624*1c12ee1eSDan Willemsen		input: &pb3.Maps{
625*1c12ee1eSDan Willemsen			Uint64ToEnum: map[uint64]pb3.Enum{
626*1c12ee1eSDan Willemsen				1:  pb3.Enum_ONE,
627*1c12ee1eSDan Willemsen				2:  pb3.Enum_TWO,
628*1c12ee1eSDan Willemsen				10: pb3.Enum_TEN,
629*1c12ee1eSDan Willemsen				47: 47,
630*1c12ee1eSDan Willemsen			},
631*1c12ee1eSDan Willemsen		},
632*1c12ee1eSDan Willemsen		want: `uint64_to_enum: {
633*1c12ee1eSDan Willemsen  key: 1
634*1c12ee1eSDan Willemsen  value: ONE
635*1c12ee1eSDan Willemsen}
636*1c12ee1eSDan Willemsenuint64_to_enum: {
637*1c12ee1eSDan Willemsen  key: 2
638*1c12ee1eSDan Willemsen  value: TWO
639*1c12ee1eSDan Willemsen}
640*1c12ee1eSDan Willemsenuint64_to_enum: {
641*1c12ee1eSDan Willemsen  key: 10
642*1c12ee1eSDan Willemsen  value: TEN
643*1c12ee1eSDan Willemsen}
644*1c12ee1eSDan Willemsenuint64_to_enum: {
645*1c12ee1eSDan Willemsen  key: 47
646*1c12ee1eSDan Willemsen  value: 47
647*1c12ee1eSDan Willemsen}
648*1c12ee1eSDan Willemsen`,
649*1c12ee1eSDan Willemsen	}, {
650*1c12ee1eSDan Willemsen		desc: "map fields 3",
651*1c12ee1eSDan Willemsen		input: &pb3.Maps{
652*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb3.Nested{
653*1c12ee1eSDan Willemsen				"nested": &pb3.Nested{
654*1c12ee1eSDan Willemsen					SString: "nested in a map",
655*1c12ee1eSDan Willemsen				},
656*1c12ee1eSDan Willemsen			},
657*1c12ee1eSDan Willemsen		},
658*1c12ee1eSDan Willemsen		want: `str_to_nested: {
659*1c12ee1eSDan Willemsen  key: "nested"
660*1c12ee1eSDan Willemsen  value: {
661*1c12ee1eSDan Willemsen    s_string: "nested in a map"
662*1c12ee1eSDan Willemsen  }
663*1c12ee1eSDan Willemsen}
664*1c12ee1eSDan Willemsen`,
665*1c12ee1eSDan Willemsen	}, {
666*1c12ee1eSDan Willemsen		desc: "map fields 4",
667*1c12ee1eSDan Willemsen		input: &pb3.Maps{
668*1c12ee1eSDan Willemsen			StrToOneofs: map[string]*pb3.Oneofs{
669*1c12ee1eSDan Willemsen				"string": &pb3.Oneofs{
670*1c12ee1eSDan Willemsen					Union: &pb3.Oneofs_OneofString{
671*1c12ee1eSDan Willemsen						OneofString: "hello",
672*1c12ee1eSDan Willemsen					},
673*1c12ee1eSDan Willemsen				},
674*1c12ee1eSDan Willemsen				"nested": &pb3.Oneofs{
675*1c12ee1eSDan Willemsen					Union: &pb3.Oneofs_OneofNested{
676*1c12ee1eSDan Willemsen						OneofNested: &pb3.Nested{
677*1c12ee1eSDan Willemsen							SString: "nested oneof in map field value",
678*1c12ee1eSDan Willemsen						},
679*1c12ee1eSDan Willemsen					},
680*1c12ee1eSDan Willemsen				},
681*1c12ee1eSDan Willemsen			},
682*1c12ee1eSDan Willemsen		},
683*1c12ee1eSDan Willemsen		want: `str_to_oneofs: {
684*1c12ee1eSDan Willemsen  key: "nested"
685*1c12ee1eSDan Willemsen  value: {
686*1c12ee1eSDan Willemsen    oneof_nested: {
687*1c12ee1eSDan Willemsen      s_string: "nested oneof in map field value"
688*1c12ee1eSDan Willemsen    }
689*1c12ee1eSDan Willemsen  }
690*1c12ee1eSDan Willemsen}
691*1c12ee1eSDan Willemsenstr_to_oneofs: {
692*1c12ee1eSDan Willemsen  key: "string"
693*1c12ee1eSDan Willemsen  value: {
694*1c12ee1eSDan Willemsen    oneof_string: "hello"
695*1c12ee1eSDan Willemsen  }
696*1c12ee1eSDan Willemsen}
697*1c12ee1eSDan Willemsen`,
698*1c12ee1eSDan Willemsen	}, {
699*1c12ee1eSDan Willemsen		desc: "proto2 map field value contains invalid UTF-8",
700*1c12ee1eSDan Willemsen		input: &pb2.Maps{
701*1c12ee1eSDan Willemsen			Int32ToStr: map[int32]string{
702*1c12ee1eSDan Willemsen				101: "abc\xff",
703*1c12ee1eSDan Willemsen			},
704*1c12ee1eSDan Willemsen		},
705*1c12ee1eSDan Willemsen		want: `int32_to_str: {
706*1c12ee1eSDan Willemsen  key: 101
707*1c12ee1eSDan Willemsen  value: "abc\xff"
708*1c12ee1eSDan Willemsen}
709*1c12ee1eSDan Willemsen`,
710*1c12ee1eSDan Willemsen	}, {
711*1c12ee1eSDan Willemsen		desc: "proto2 map field key contains invalid UTF-8",
712*1c12ee1eSDan Willemsen		input: &pb2.Maps{
713*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb2.Nested{
714*1c12ee1eSDan Willemsen				"abc\xff": {},
715*1c12ee1eSDan Willemsen			},
716*1c12ee1eSDan Willemsen		},
717*1c12ee1eSDan Willemsen		want: `str_to_nested: {
718*1c12ee1eSDan Willemsen  key: "abc\xff"
719*1c12ee1eSDan Willemsen  value: {}
720*1c12ee1eSDan Willemsen}
721*1c12ee1eSDan Willemsen`,
722*1c12ee1eSDan Willemsen	}, {
723*1c12ee1eSDan Willemsen		desc: "proto3 map field value contains invalid UTF-8",
724*1c12ee1eSDan Willemsen		input: &pb3.Maps{
725*1c12ee1eSDan Willemsen			Int32ToStr: map[int32]string{
726*1c12ee1eSDan Willemsen				101: "abc\xff",
727*1c12ee1eSDan Willemsen			},
728*1c12ee1eSDan Willemsen		},
729*1c12ee1eSDan Willemsen		wantErr: true,
730*1c12ee1eSDan Willemsen	}, {
731*1c12ee1eSDan Willemsen		desc: "proto3 map field key contains invalid UTF-8",
732*1c12ee1eSDan Willemsen		input: &pb3.Maps{
733*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb3.Nested{
734*1c12ee1eSDan Willemsen				"abc\xff": {},
735*1c12ee1eSDan Willemsen			},
736*1c12ee1eSDan Willemsen		},
737*1c12ee1eSDan Willemsen		wantErr: true,
738*1c12ee1eSDan Willemsen	}, {
739*1c12ee1eSDan Willemsen		desc: "map field contains nil value",
740*1c12ee1eSDan Willemsen		input: &pb3.Maps{
741*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb3.Nested{
742*1c12ee1eSDan Willemsen				"nil": nil,
743*1c12ee1eSDan Willemsen			},
744*1c12ee1eSDan Willemsen		},
745*1c12ee1eSDan Willemsen		want: `str_to_nested: {
746*1c12ee1eSDan Willemsen  key: "nil"
747*1c12ee1eSDan Willemsen  value: {}
748*1c12ee1eSDan Willemsen}
749*1c12ee1eSDan Willemsen`,
750*1c12ee1eSDan Willemsen	}, {
751*1c12ee1eSDan Willemsen		desc:    "required fields not set",
752*1c12ee1eSDan Willemsen		input:   &pb2.Requireds{},
753*1c12ee1eSDan Willemsen		want:    "",
754*1c12ee1eSDan Willemsen		wantErr: true,
755*1c12ee1eSDan Willemsen	}, {
756*1c12ee1eSDan Willemsen		desc: "required fields partially set",
757*1c12ee1eSDan Willemsen		input: &pb2.Requireds{
758*1c12ee1eSDan Willemsen			ReqBool:     proto.Bool(false),
759*1c12ee1eSDan Willemsen			ReqSfixed64: proto.Int64(0xbeefcafe),
760*1c12ee1eSDan Willemsen			ReqDouble:   proto.Float64(math.NaN()),
761*1c12ee1eSDan Willemsen			ReqString:   proto.String("hello"),
762*1c12ee1eSDan Willemsen			ReqEnum:     pb2.Enum_ONE.Enum(),
763*1c12ee1eSDan Willemsen		},
764*1c12ee1eSDan Willemsen		want: `req_bool: false
765*1c12ee1eSDan Willemsenreq_sfixed64: 3203386110
766*1c12ee1eSDan Willemsenreq_double: nan
767*1c12ee1eSDan Willemsenreq_string: "hello"
768*1c12ee1eSDan Willemsenreq_enum: ONE
769*1c12ee1eSDan Willemsen`,
770*1c12ee1eSDan Willemsen		wantErr: true,
771*1c12ee1eSDan Willemsen	}, {
772*1c12ee1eSDan Willemsen		desc: "required fields not set with AllowPartial",
773*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
774*1c12ee1eSDan Willemsen		input: &pb2.Requireds{
775*1c12ee1eSDan Willemsen			ReqBool:     proto.Bool(false),
776*1c12ee1eSDan Willemsen			ReqSfixed64: proto.Int64(0xbeefcafe),
777*1c12ee1eSDan Willemsen			ReqDouble:   proto.Float64(math.NaN()),
778*1c12ee1eSDan Willemsen			ReqString:   proto.String("hello"),
779*1c12ee1eSDan Willemsen			ReqEnum:     pb2.Enum_ONE.Enum(),
780*1c12ee1eSDan Willemsen		},
781*1c12ee1eSDan Willemsen		want: `req_bool: false
782*1c12ee1eSDan Willemsenreq_sfixed64: 3203386110
783*1c12ee1eSDan Willemsenreq_double: nan
784*1c12ee1eSDan Willemsenreq_string: "hello"
785*1c12ee1eSDan Willemsenreq_enum: ONE
786*1c12ee1eSDan Willemsen`,
787*1c12ee1eSDan Willemsen	}, {
788*1c12ee1eSDan Willemsen		desc: "required fields all set",
789*1c12ee1eSDan Willemsen		input: &pb2.Requireds{
790*1c12ee1eSDan Willemsen			ReqBool:     proto.Bool(false),
791*1c12ee1eSDan Willemsen			ReqSfixed64: proto.Int64(0),
792*1c12ee1eSDan Willemsen			ReqDouble:   proto.Float64(1.23),
793*1c12ee1eSDan Willemsen			ReqString:   proto.String(""),
794*1c12ee1eSDan Willemsen			ReqEnum:     pb2.Enum_ONE.Enum(),
795*1c12ee1eSDan Willemsen			ReqNested:   &pb2.Nested{},
796*1c12ee1eSDan Willemsen		},
797*1c12ee1eSDan Willemsen		want: `req_bool: false
798*1c12ee1eSDan Willemsenreq_sfixed64: 0
799*1c12ee1eSDan Willemsenreq_double: 1.23
800*1c12ee1eSDan Willemsenreq_string: ""
801*1c12ee1eSDan Willemsenreq_enum: ONE
802*1c12ee1eSDan Willemsenreq_nested: {}
803*1c12ee1eSDan Willemsen`,
804*1c12ee1eSDan Willemsen	}, {
805*1c12ee1eSDan Willemsen		desc: "indirect required field",
806*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
807*1c12ee1eSDan Willemsen			OptNested: &pb2.NestedWithRequired{},
808*1c12ee1eSDan Willemsen		},
809*1c12ee1eSDan Willemsen		want:    "opt_nested: {}\n",
810*1c12ee1eSDan Willemsen		wantErr: true,
811*1c12ee1eSDan Willemsen	}, {
812*1c12ee1eSDan Willemsen		desc: "indirect required field with AllowPartial",
813*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
814*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
815*1c12ee1eSDan Willemsen			OptNested: &pb2.NestedWithRequired{},
816*1c12ee1eSDan Willemsen		},
817*1c12ee1eSDan Willemsen		want: "opt_nested: {}\n",
818*1c12ee1eSDan Willemsen	}, {
819*1c12ee1eSDan Willemsen		desc: "indirect required field in empty repeated",
820*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
821*1c12ee1eSDan Willemsen			RptNested: []*pb2.NestedWithRequired{},
822*1c12ee1eSDan Willemsen		},
823*1c12ee1eSDan Willemsen		want: "",
824*1c12ee1eSDan Willemsen	}, {
825*1c12ee1eSDan Willemsen		desc: "indirect required field in repeated",
826*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
827*1c12ee1eSDan Willemsen			RptNested: []*pb2.NestedWithRequired{
828*1c12ee1eSDan Willemsen				&pb2.NestedWithRequired{},
829*1c12ee1eSDan Willemsen			},
830*1c12ee1eSDan Willemsen		},
831*1c12ee1eSDan Willemsen		want:    "rpt_nested: {}\n",
832*1c12ee1eSDan Willemsen		wantErr: true,
833*1c12ee1eSDan Willemsen	}, {
834*1c12ee1eSDan Willemsen		desc: "indirect required field in repeated with AllowPartial",
835*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
836*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
837*1c12ee1eSDan Willemsen			RptNested: []*pb2.NestedWithRequired{
838*1c12ee1eSDan Willemsen				&pb2.NestedWithRequired{},
839*1c12ee1eSDan Willemsen			},
840*1c12ee1eSDan Willemsen		},
841*1c12ee1eSDan Willemsen		want: "rpt_nested: {}\n",
842*1c12ee1eSDan Willemsen	}, {
843*1c12ee1eSDan Willemsen		desc: "indirect required field in empty map",
844*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
845*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb2.NestedWithRequired{},
846*1c12ee1eSDan Willemsen		},
847*1c12ee1eSDan Willemsen		want: "",
848*1c12ee1eSDan Willemsen	}, {
849*1c12ee1eSDan Willemsen		desc: "indirect required field in map",
850*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
851*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb2.NestedWithRequired{
852*1c12ee1eSDan Willemsen				"fail": &pb2.NestedWithRequired{},
853*1c12ee1eSDan Willemsen			},
854*1c12ee1eSDan Willemsen		},
855*1c12ee1eSDan Willemsen		want: `str_to_nested: {
856*1c12ee1eSDan Willemsen  key: "fail"
857*1c12ee1eSDan Willemsen  value: {}
858*1c12ee1eSDan Willemsen}
859*1c12ee1eSDan Willemsen`,
860*1c12ee1eSDan Willemsen		wantErr: true,
861*1c12ee1eSDan Willemsen	}, {
862*1c12ee1eSDan Willemsen		desc: "indirect required field in map with AllowPartial",
863*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
864*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
865*1c12ee1eSDan Willemsen			StrToNested: map[string]*pb2.NestedWithRequired{
866*1c12ee1eSDan Willemsen				"fail": &pb2.NestedWithRequired{},
867*1c12ee1eSDan Willemsen			},
868*1c12ee1eSDan Willemsen		},
869*1c12ee1eSDan Willemsen		want: `str_to_nested: {
870*1c12ee1eSDan Willemsen  key: "fail"
871*1c12ee1eSDan Willemsen  value: {}
872*1c12ee1eSDan Willemsen}
873*1c12ee1eSDan Willemsen`,
874*1c12ee1eSDan Willemsen	}, {
875*1c12ee1eSDan Willemsen		desc: "indirect required field in oneof",
876*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
877*1c12ee1eSDan Willemsen			Union: &pb2.IndirectRequired_OneofNested{
878*1c12ee1eSDan Willemsen				OneofNested: &pb2.NestedWithRequired{},
879*1c12ee1eSDan Willemsen			},
880*1c12ee1eSDan Willemsen		},
881*1c12ee1eSDan Willemsen		want:    "oneof_nested: {}\n",
882*1c12ee1eSDan Willemsen		wantErr: true,
883*1c12ee1eSDan Willemsen	}, {
884*1c12ee1eSDan Willemsen		desc: "indirect required field in oneof with AllowPartial",
885*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
886*1c12ee1eSDan Willemsen		input: &pb2.IndirectRequired{
887*1c12ee1eSDan Willemsen			Union: &pb2.IndirectRequired_OneofNested{
888*1c12ee1eSDan Willemsen				OneofNested: &pb2.NestedWithRequired{},
889*1c12ee1eSDan Willemsen			},
890*1c12ee1eSDan Willemsen		},
891*1c12ee1eSDan Willemsen		want: "oneof_nested: {}\n",
892*1c12ee1eSDan Willemsen	}, {
893*1c12ee1eSDan Willemsen		desc: "unknown fields not printed",
894*1c12ee1eSDan Willemsen		input: func() proto.Message {
895*1c12ee1eSDan Willemsen			m := &pb2.Scalars{
896*1c12ee1eSDan Willemsen				OptString: proto.String("this message contains unknown fields"),
897*1c12ee1eSDan Willemsen			}
898*1c12ee1eSDan Willemsen			m.ProtoReflect().SetUnknown(protopack.Message{
899*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.VarintType}, protopack.Bool(true),
900*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.VarintType}, protopack.Varint(0xff),
901*1c12ee1eSDan Willemsen				protopack.Tag{103, protopack.Fixed32Type}, protopack.Uint32(47),
902*1c12ee1eSDan Willemsen				protopack.Tag{104, protopack.Fixed64Type}, protopack.Int64(0xdeadbeef),
903*1c12ee1eSDan Willemsen			}.Marshal())
904*1c12ee1eSDan Willemsen			return m
905*1c12ee1eSDan Willemsen		}(),
906*1c12ee1eSDan Willemsen		want: `opt_string: "this message contains unknown fields"
907*1c12ee1eSDan Willemsen`,
908*1c12ee1eSDan Willemsen	}, {
909*1c12ee1eSDan Willemsen		desc: "unknown varint and fixed types",
910*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitUnknown: true},
911*1c12ee1eSDan Willemsen		input: func() proto.Message {
912*1c12ee1eSDan Willemsen			m := &pb2.Scalars{
913*1c12ee1eSDan Willemsen				OptString: proto.String("this message contains unknown fields"),
914*1c12ee1eSDan Willemsen			}
915*1c12ee1eSDan Willemsen			m.ProtoReflect().SetUnknown(protopack.Message{
916*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.VarintType}, protopack.Bool(true),
917*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.VarintType}, protopack.Varint(0xff),
918*1c12ee1eSDan Willemsen				protopack.Tag{103, protopack.Fixed32Type}, protopack.Uint32(0x47),
919*1c12ee1eSDan Willemsen				protopack.Tag{104, protopack.Fixed64Type}, protopack.Int64(0xdeadbeef),
920*1c12ee1eSDan Willemsen			}.Marshal())
921*1c12ee1eSDan Willemsen			return m
922*1c12ee1eSDan Willemsen		}(),
923*1c12ee1eSDan Willemsen		want: `opt_string: "this message contains unknown fields"
924*1c12ee1eSDan Willemsen101: 1
925*1c12ee1eSDan Willemsen102: 255
926*1c12ee1eSDan Willemsen103: 0x47
927*1c12ee1eSDan Willemsen104: 0xdeadbeef
928*1c12ee1eSDan Willemsen`,
929*1c12ee1eSDan Willemsen	}, {
930*1c12ee1eSDan Willemsen		desc: "unknown length-delimited",
931*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitUnknown: true},
932*1c12ee1eSDan Willemsen		input: func() proto.Message {
933*1c12ee1eSDan Willemsen			m := new(pb2.Scalars)
934*1c12ee1eSDan Willemsen			m.ProtoReflect().SetUnknown(protopack.Message{
935*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.BytesType}, protopack.LengthPrefix{protopack.Bool(true), protopack.Bool(false)},
936*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.BytesType}, protopack.String("hello world"),
937*1c12ee1eSDan Willemsen				protopack.Tag{103, protopack.BytesType}, protopack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
938*1c12ee1eSDan Willemsen			}.Marshal())
939*1c12ee1eSDan Willemsen			return m
940*1c12ee1eSDan Willemsen		}(),
941*1c12ee1eSDan Willemsen		want: `101: "\x01\x00"
942*1c12ee1eSDan Willemsen102: "hello world"
943*1c12ee1eSDan Willemsen103: "世界"
944*1c12ee1eSDan Willemsen`,
945*1c12ee1eSDan Willemsen	}, {
946*1c12ee1eSDan Willemsen		desc: "unknown group type",
947*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitUnknown: true},
948*1c12ee1eSDan Willemsen		input: func() proto.Message {
949*1c12ee1eSDan Willemsen			m := new(pb2.Scalars)
950*1c12ee1eSDan Willemsen			m.ProtoReflect().SetUnknown(protopack.Message{
951*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.StartGroupType}, protopack.Tag{101, protopack.EndGroupType},
952*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.StartGroupType},
953*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.VarintType}, protopack.Bool(false),
954*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.BytesType}, protopack.String("inside a group"),
955*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.EndGroupType},
956*1c12ee1eSDan Willemsen			}.Marshal())
957*1c12ee1eSDan Willemsen			return m
958*1c12ee1eSDan Willemsen		}(),
959*1c12ee1eSDan Willemsen		want: `101: {}
960*1c12ee1eSDan Willemsen102: {
961*1c12ee1eSDan Willemsen  101: 0
962*1c12ee1eSDan Willemsen  102: "inside a group"
963*1c12ee1eSDan Willemsen}
964*1c12ee1eSDan Willemsen`,
965*1c12ee1eSDan Willemsen	}, {
966*1c12ee1eSDan Willemsen		desc: "unknown unpack repeated field",
967*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitUnknown: true},
968*1c12ee1eSDan Willemsen		input: func() proto.Message {
969*1c12ee1eSDan Willemsen			m := new(pb2.Scalars)
970*1c12ee1eSDan Willemsen			m.ProtoReflect().SetUnknown(protopack.Message{
971*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.BytesType}, protopack.LengthPrefix{protopack.Bool(true), protopack.Bool(false), protopack.Bool(true)},
972*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.BytesType}, protopack.String("hello"),
973*1c12ee1eSDan Willemsen				protopack.Tag{101, protopack.VarintType}, protopack.Bool(true),
974*1c12ee1eSDan Willemsen				protopack.Tag{102, protopack.BytesType}, protopack.String("世界"),
975*1c12ee1eSDan Willemsen			}.Marshal())
976*1c12ee1eSDan Willemsen			return m
977*1c12ee1eSDan Willemsen		}(),
978*1c12ee1eSDan Willemsen		want: `101: "\x01\x00\x01"
979*1c12ee1eSDan Willemsen102: "hello"
980*1c12ee1eSDan Willemsen101: 1
981*1c12ee1eSDan Willemsen102: "世界"
982*1c12ee1eSDan Willemsen`,
983*1c12ee1eSDan Willemsen	}, {
984*1c12ee1eSDan Willemsen		desc: "extensions of non-repeated fields",
985*1c12ee1eSDan Willemsen		input: func() proto.Message {
986*1c12ee1eSDan Willemsen			m := &pb2.Extensions{
987*1c12ee1eSDan Willemsen				OptString: proto.String("non-extension field"),
988*1c12ee1eSDan Willemsen				OptBool:   proto.Bool(true),
989*1c12ee1eSDan Willemsen				OptInt32:  proto.Int32(42),
990*1c12ee1eSDan Willemsen			}
991*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtBool, true)
992*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtString, "extension field")
993*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
994*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
995*1c12ee1eSDan Willemsen				OptString: proto.String("nested in an extension"),
996*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
997*1c12ee1eSDan Willemsen					OptString: proto.String("another nested in an extension"),
998*1c12ee1eSDan Willemsen				},
999*1c12ee1eSDan Willemsen			})
1000*1c12ee1eSDan Willemsen			return m
1001*1c12ee1eSDan Willemsen		}(),
1002*1c12ee1eSDan Willemsen		want: `opt_string: "non-extension field"
1003*1c12ee1eSDan Willemsenopt_bool: true
1004*1c12ee1eSDan Willemsenopt_int32: 42
1005*1c12ee1eSDan Willemsen[pb2.opt_ext_bool]: true
1006*1c12ee1eSDan Willemsen[pb2.opt_ext_enum]: TEN
1007*1c12ee1eSDan Willemsen[pb2.opt_ext_nested]: {
1008*1c12ee1eSDan Willemsen  opt_string: "nested in an extension"
1009*1c12ee1eSDan Willemsen  opt_nested: {
1010*1c12ee1eSDan Willemsen    opt_string: "another nested in an extension"
1011*1c12ee1eSDan Willemsen  }
1012*1c12ee1eSDan Willemsen}
1013*1c12ee1eSDan Willemsen[pb2.opt_ext_string]: "extension field"
1014*1c12ee1eSDan Willemsen`,
1015*1c12ee1eSDan Willemsen	}, {
1016*1c12ee1eSDan Willemsen		desc: "proto2 extension field contains invalid UTF-8",
1017*1c12ee1eSDan Willemsen		input: func() proto.Message {
1018*1c12ee1eSDan Willemsen			m := &pb2.Extensions{}
1019*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
1020*1c12ee1eSDan Willemsen			return m
1021*1c12ee1eSDan Willemsen		}(),
1022*1c12ee1eSDan Willemsen		want: `[pb2.opt_ext_string]: "abc\xff"
1023*1c12ee1eSDan Willemsen`,
1024*1c12ee1eSDan Willemsen	}, {
1025*1c12ee1eSDan Willemsen		desc: "extension partial returns error",
1026*1c12ee1eSDan Willemsen		input: func() proto.Message {
1027*1c12ee1eSDan Willemsen			m := &pb2.Extensions{}
1028*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
1029*1c12ee1eSDan Willemsen				OptString: proto.String("partial1"),
1030*1c12ee1eSDan Willemsen			})
1031*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
1032*1c12ee1eSDan Willemsen				OptString: proto.String("partial2"),
1033*1c12ee1eSDan Willemsen			})
1034*1c12ee1eSDan Willemsen			return m
1035*1c12ee1eSDan Willemsen		}(),
1036*1c12ee1eSDan Willemsen		want: `[pb2.ExtensionsContainer.opt_ext_partial]: {
1037*1c12ee1eSDan Willemsen  opt_string: "partial2"
1038*1c12ee1eSDan Willemsen}
1039*1c12ee1eSDan Willemsen[pb2.opt_ext_partial]: {
1040*1c12ee1eSDan Willemsen  opt_string: "partial1"
1041*1c12ee1eSDan Willemsen}
1042*1c12ee1eSDan Willemsen`,
1043*1c12ee1eSDan Willemsen		wantErr: true,
1044*1c12ee1eSDan Willemsen	}, {
1045*1c12ee1eSDan Willemsen		desc: "extension partial with AllowPartial",
1046*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{AllowPartial: true},
1047*1c12ee1eSDan Willemsen		input: func() proto.Message {
1048*1c12ee1eSDan Willemsen			m := &pb2.Extensions{}
1049*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
1050*1c12ee1eSDan Willemsen				OptString: proto.String("partial1"),
1051*1c12ee1eSDan Willemsen			})
1052*1c12ee1eSDan Willemsen			return m
1053*1c12ee1eSDan Willemsen		}(),
1054*1c12ee1eSDan Willemsen		want: `[pb2.opt_ext_partial]: {
1055*1c12ee1eSDan Willemsen  opt_string: "partial1"
1056*1c12ee1eSDan Willemsen}
1057*1c12ee1eSDan Willemsen`,
1058*1c12ee1eSDan Willemsen	}, {
1059*1c12ee1eSDan Willemsen		desc: "extensions of repeated fields",
1060*1c12ee1eSDan Willemsen		input: func() proto.Message {
1061*1c12ee1eSDan Willemsen			m := &pb2.Extensions{}
1062*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1063*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
1064*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
1065*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("one")},
1066*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("two")},
1067*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("three")},
1068*1c12ee1eSDan Willemsen			})
1069*1c12ee1eSDan Willemsen			return m
1070*1c12ee1eSDan Willemsen		}(),
1071*1c12ee1eSDan Willemsen		want: `[pb2.rpt_ext_enum]: TEN
1072*1c12ee1eSDan Willemsen[pb2.rpt_ext_enum]: 101
1073*1c12ee1eSDan Willemsen[pb2.rpt_ext_enum]: ONE
1074*1c12ee1eSDan Willemsen[pb2.rpt_ext_fixed32]: 42
1075*1c12ee1eSDan Willemsen[pb2.rpt_ext_fixed32]: 47
1076*1c12ee1eSDan Willemsen[pb2.rpt_ext_nested]: {
1077*1c12ee1eSDan Willemsen  opt_string: "one"
1078*1c12ee1eSDan Willemsen}
1079*1c12ee1eSDan Willemsen[pb2.rpt_ext_nested]: {
1080*1c12ee1eSDan Willemsen  opt_string: "two"
1081*1c12ee1eSDan Willemsen}
1082*1c12ee1eSDan Willemsen[pb2.rpt_ext_nested]: {
1083*1c12ee1eSDan Willemsen  opt_string: "three"
1084*1c12ee1eSDan Willemsen}
1085*1c12ee1eSDan Willemsen`,
1086*1c12ee1eSDan Willemsen	}, {
1087*1c12ee1eSDan Willemsen		desc: "extensions of non-repeated fields in another message",
1088*1c12ee1eSDan Willemsen		input: func() proto.Message {
1089*1c12ee1eSDan Willemsen			m := &pb2.Extensions{}
1090*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1091*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1092*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1093*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1094*1c12ee1eSDan Willemsen				OptString: proto.String("nested in an extension"),
1095*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
1096*1c12ee1eSDan Willemsen					OptString: proto.String("another nested in an extension"),
1097*1c12ee1eSDan Willemsen				},
1098*1c12ee1eSDan Willemsen			})
1099*1c12ee1eSDan Willemsen			return m
1100*1c12ee1eSDan Willemsen		}(),
1101*1c12ee1eSDan Willemsen		want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
1102*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.opt_ext_enum]: TEN
1103*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.opt_ext_nested]: {
1104*1c12ee1eSDan Willemsen  opt_string: "nested in an extension"
1105*1c12ee1eSDan Willemsen  opt_nested: {
1106*1c12ee1eSDan Willemsen    opt_string: "another nested in an extension"
1107*1c12ee1eSDan Willemsen  }
1108*1c12ee1eSDan Willemsen}
1109*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1110*1c12ee1eSDan Willemsen`,
1111*1c12ee1eSDan Willemsen	}, {
1112*1c12ee1eSDan Willemsen		desc: "extensions of repeated fields in another message",
1113*1c12ee1eSDan Willemsen		input: func() proto.Message {
1114*1c12ee1eSDan Willemsen			m := &pb2.Extensions{
1115*1c12ee1eSDan Willemsen				OptString: proto.String("non-extension field"),
1116*1c12ee1eSDan Willemsen				OptBool:   proto.Bool(true),
1117*1c12ee1eSDan Willemsen				OptInt32:  proto.Int32(42),
1118*1c12ee1eSDan Willemsen			}
1119*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1120*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1121*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
1122*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("one")},
1123*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("two")},
1124*1c12ee1eSDan Willemsen				&pb2.Nested{OptString: proto.String("three")},
1125*1c12ee1eSDan Willemsen			})
1126*1c12ee1eSDan Willemsen			return m
1127*1c12ee1eSDan Willemsen		}(),
1128*1c12ee1eSDan Willemsen		want: `opt_string: "non-extension field"
1129*1c12ee1eSDan Willemsenopt_bool: true
1130*1c12ee1eSDan Willemsenopt_int32: 42
1131*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
1132*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1133*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
1134*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_nested]: {
1135*1c12ee1eSDan Willemsen  opt_string: "one"
1136*1c12ee1eSDan Willemsen}
1137*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_nested]: {
1138*1c12ee1eSDan Willemsen  opt_string: "two"
1139*1c12ee1eSDan Willemsen}
1140*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_nested]: {
1141*1c12ee1eSDan Willemsen  opt_string: "three"
1142*1c12ee1eSDan Willemsen}
1143*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
1144*1c12ee1eSDan Willemsen[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1145*1c12ee1eSDan Willemsen`,
1146*1c12ee1eSDan Willemsen	}, {
1147*1c12ee1eSDan Willemsen		desc: "MessageSet",
1148*1c12ee1eSDan Willemsen		input: func() proto.Message {
1149*1c12ee1eSDan Willemsen			m := &pb2.MessageSet{}
1150*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1151*1c12ee1eSDan Willemsen				OptString: proto.String("a messageset extension"),
1152*1c12ee1eSDan Willemsen			})
1153*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1154*1c12ee1eSDan Willemsen				OptString: proto.String("not a messageset extension"),
1155*1c12ee1eSDan Willemsen			})
1156*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1157*1c12ee1eSDan Willemsen				OptString: proto.String("just a regular extension"),
1158*1c12ee1eSDan Willemsen			})
1159*1c12ee1eSDan Willemsen			return m
1160*1c12ee1eSDan Willemsen		}(),
1161*1c12ee1eSDan Willemsen		want: `[pb2.MessageSetExtension.ext_nested]: {
1162*1c12ee1eSDan Willemsen  opt_string: "just a regular extension"
1163*1c12ee1eSDan Willemsen}
1164*1c12ee1eSDan Willemsen[pb2.MessageSetExtension]: {
1165*1c12ee1eSDan Willemsen  opt_string: "a messageset extension"
1166*1c12ee1eSDan Willemsen}
1167*1c12ee1eSDan Willemsen[pb2.MessageSetExtension.not_message_set_extension]: {
1168*1c12ee1eSDan Willemsen  opt_string: "not a messageset extension"
1169*1c12ee1eSDan Willemsen}
1170*1c12ee1eSDan Willemsen`,
1171*1c12ee1eSDan Willemsen		skip: !flags.ProtoLegacy,
1172*1c12ee1eSDan Willemsen	}, {
1173*1c12ee1eSDan Willemsen		desc: "not real MessageSet 1",
1174*1c12ee1eSDan Willemsen		input: func() proto.Message {
1175*1c12ee1eSDan Willemsen			m := &pb2.FakeMessageSet{}
1176*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1177*1c12ee1eSDan Willemsen				OptString: proto.String("not a messageset extension"),
1178*1c12ee1eSDan Willemsen			})
1179*1c12ee1eSDan Willemsen			return m
1180*1c12ee1eSDan Willemsen		}(),
1181*1c12ee1eSDan Willemsen		want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1182*1c12ee1eSDan Willemsen  opt_string: "not a messageset extension"
1183*1c12ee1eSDan Willemsen}
1184*1c12ee1eSDan Willemsen`,
1185*1c12ee1eSDan Willemsen		skip: !flags.ProtoLegacy,
1186*1c12ee1eSDan Willemsen	}, {
1187*1c12ee1eSDan Willemsen		desc: "not real MessageSet 2",
1188*1c12ee1eSDan Willemsen		input: func() proto.Message {
1189*1c12ee1eSDan Willemsen			m := &pb2.MessageSet{}
1190*1c12ee1eSDan Willemsen			proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1191*1c12ee1eSDan Willemsen				OptString: proto.String("another not a messageset extension"),
1192*1c12ee1eSDan Willemsen			})
1193*1c12ee1eSDan Willemsen			return m
1194*1c12ee1eSDan Willemsen		}(),
1195*1c12ee1eSDan Willemsen		want: `[pb2.message_set_extension]: {
1196*1c12ee1eSDan Willemsen  opt_string: "another not a messageset extension"
1197*1c12ee1eSDan Willemsen}
1198*1c12ee1eSDan Willemsen`,
1199*1c12ee1eSDan Willemsen		skip: !flags.ProtoLegacy,
1200*1c12ee1eSDan Willemsen	}, {
1201*1c12ee1eSDan Willemsen		desc: "Any not expanded",
1202*1c12ee1eSDan Willemsen		mo: prototext.MarshalOptions{
1203*1c12ee1eSDan Willemsen			Resolver: new(protoregistry.Types),
1204*1c12ee1eSDan Willemsen		},
1205*1c12ee1eSDan Willemsen		input: func() proto.Message {
1206*1c12ee1eSDan Willemsen			m := &pb2.Nested{
1207*1c12ee1eSDan Willemsen				OptString: proto.String("embedded inside Any"),
1208*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
1209*1c12ee1eSDan Willemsen					OptString: proto.String("inception"),
1210*1c12ee1eSDan Willemsen				},
1211*1c12ee1eSDan Willemsen			}
1212*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1213*1c12ee1eSDan Willemsen			if err != nil {
1214*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1215*1c12ee1eSDan Willemsen			}
1216*1c12ee1eSDan Willemsen			return &anypb.Any{
1217*1c12ee1eSDan Willemsen				TypeUrl: "pb2.Nested",
1218*1c12ee1eSDan Willemsen				Value:   b,
1219*1c12ee1eSDan Willemsen			}
1220*1c12ee1eSDan Willemsen		}(),
1221*1c12ee1eSDan Willemsen		want: `type_url: "pb2.Nested"
1222*1c12ee1eSDan Willemsenvalue: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1223*1c12ee1eSDan Willemsen`,
1224*1c12ee1eSDan Willemsen	}, {
1225*1c12ee1eSDan Willemsen		desc: "Any expanded",
1226*1c12ee1eSDan Willemsen		input: func() proto.Message {
1227*1c12ee1eSDan Willemsen			m := &pb2.Nested{
1228*1c12ee1eSDan Willemsen				OptString: proto.String("embedded inside Any"),
1229*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
1230*1c12ee1eSDan Willemsen					OptString: proto.String("inception"),
1231*1c12ee1eSDan Willemsen				},
1232*1c12ee1eSDan Willemsen			}
1233*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1234*1c12ee1eSDan Willemsen			if err != nil {
1235*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1236*1c12ee1eSDan Willemsen			}
1237*1c12ee1eSDan Willemsen			return &anypb.Any{
1238*1c12ee1eSDan Willemsen				TypeUrl: "foo/pb2.Nested",
1239*1c12ee1eSDan Willemsen				Value:   b,
1240*1c12ee1eSDan Willemsen			}
1241*1c12ee1eSDan Willemsen		}(),
1242*1c12ee1eSDan Willemsen		want: `[foo/pb2.Nested]: {
1243*1c12ee1eSDan Willemsen  opt_string: "embedded inside Any"
1244*1c12ee1eSDan Willemsen  opt_nested: {
1245*1c12ee1eSDan Willemsen    opt_string: "inception"
1246*1c12ee1eSDan Willemsen  }
1247*1c12ee1eSDan Willemsen}
1248*1c12ee1eSDan Willemsen`,
1249*1c12ee1eSDan Willemsen	}, {
1250*1c12ee1eSDan Willemsen		desc: "Any expanded with missing required",
1251*1c12ee1eSDan Willemsen		input: func() proto.Message {
1252*1c12ee1eSDan Willemsen			m := &pb2.PartialRequired{
1253*1c12ee1eSDan Willemsen				OptString: proto.String("embedded inside Any"),
1254*1c12ee1eSDan Willemsen			}
1255*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{
1256*1c12ee1eSDan Willemsen				AllowPartial:  true,
1257*1c12ee1eSDan Willemsen				Deterministic: true,
1258*1c12ee1eSDan Willemsen			}.Marshal(m)
1259*1c12ee1eSDan Willemsen			if err != nil {
1260*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1261*1c12ee1eSDan Willemsen			}
1262*1c12ee1eSDan Willemsen			return &anypb.Any{
1263*1c12ee1eSDan Willemsen				TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
1264*1c12ee1eSDan Willemsen				Value:   b,
1265*1c12ee1eSDan Willemsen			}
1266*1c12ee1eSDan Willemsen		}(),
1267*1c12ee1eSDan Willemsen		want: `[pb2.PartialRequired]: {
1268*1c12ee1eSDan Willemsen  opt_string: "embedded inside Any"
1269*1c12ee1eSDan Willemsen}
1270*1c12ee1eSDan Willemsen`,
1271*1c12ee1eSDan Willemsen	}, {
1272*1c12ee1eSDan Willemsen		desc: "Any with invalid value",
1273*1c12ee1eSDan Willemsen		input: &anypb.Any{
1274*1c12ee1eSDan Willemsen			TypeUrl: "foo/pb2.Nested",
1275*1c12ee1eSDan Willemsen			Value:   []byte("\x80"),
1276*1c12ee1eSDan Willemsen		},
1277*1c12ee1eSDan Willemsen		want: `type_url: "foo/pb2.Nested"
1278*1c12ee1eSDan Willemsenvalue: "\x80"
1279*1c12ee1eSDan Willemsen`,
1280*1c12ee1eSDan Willemsen	}, {
1281*1c12ee1eSDan Willemsen		desc: "Any expanded in another message",
1282*1c12ee1eSDan Willemsen		input: func() *pb2.KnownTypes {
1283*1c12ee1eSDan Willemsen			m1 := &pb2.Nested{
1284*1c12ee1eSDan Willemsen				OptString: proto.String("message inside Any of another Any field"),
1285*1c12ee1eSDan Willemsen			}
1286*1c12ee1eSDan Willemsen			b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
1287*1c12ee1eSDan Willemsen			if err != nil {
1288*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1289*1c12ee1eSDan Willemsen			}
1290*1c12ee1eSDan Willemsen			m2 := &anypb.Any{
1291*1c12ee1eSDan Willemsen				TypeUrl: "pb2.Nested",
1292*1c12ee1eSDan Willemsen				Value:   b1,
1293*1c12ee1eSDan Willemsen			}
1294*1c12ee1eSDan Willemsen			b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
1295*1c12ee1eSDan Willemsen			if err != nil {
1296*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1297*1c12ee1eSDan Willemsen			}
1298*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
1299*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
1300*1c12ee1eSDan Willemsen					TypeUrl: "google.protobuf.Any",
1301*1c12ee1eSDan Willemsen					Value:   b2,
1302*1c12ee1eSDan Willemsen				},
1303*1c12ee1eSDan Willemsen			}
1304*1c12ee1eSDan Willemsen		}(),
1305*1c12ee1eSDan Willemsen		want: `opt_any: {
1306*1c12ee1eSDan Willemsen  [google.protobuf.Any]: {
1307*1c12ee1eSDan Willemsen    [pb2.Nested]: {
1308*1c12ee1eSDan Willemsen      opt_string: "message inside Any of another Any field"
1309*1c12ee1eSDan Willemsen    }
1310*1c12ee1eSDan Willemsen  }
1311*1c12ee1eSDan Willemsen}
1312*1c12ee1eSDan Willemsen`,
1313*1c12ee1eSDan Willemsen	}, {
1314*1c12ee1eSDan Willemsen		desc: "Any expanded with invalid UTF-8 in proto2",
1315*1c12ee1eSDan Willemsen		input: func() *pb2.KnownTypes {
1316*1c12ee1eSDan Willemsen			m := &pb2.Nested{
1317*1c12ee1eSDan Willemsen				OptString: proto.String("invalid UTF-8 abc\xff"),
1318*1c12ee1eSDan Willemsen			}
1319*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1320*1c12ee1eSDan Willemsen			if err != nil {
1321*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1322*1c12ee1eSDan Willemsen			}
1323*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
1324*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
1325*1c12ee1eSDan Willemsen					TypeUrl: "pb2.Nested",
1326*1c12ee1eSDan Willemsen					Value:   b,
1327*1c12ee1eSDan Willemsen				},
1328*1c12ee1eSDan Willemsen			}
1329*1c12ee1eSDan Willemsen		}(),
1330*1c12ee1eSDan Willemsen		want: `opt_any: {
1331*1c12ee1eSDan Willemsen  [pb2.Nested]: {
1332*1c12ee1eSDan Willemsen    opt_string: "invalid UTF-8 abc\xff"
1333*1c12ee1eSDan Willemsen  }
1334*1c12ee1eSDan Willemsen}
1335*1c12ee1eSDan Willemsen`,
1336*1c12ee1eSDan Willemsen	}, {
1337*1c12ee1eSDan Willemsen		desc: "Any not expanded due to invalid data",
1338*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitASCII: true},
1339*1c12ee1eSDan Willemsen		input: func() *pb2.KnownTypes {
1340*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
1341*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
1342*1c12ee1eSDan Willemsen					TypeUrl: "pb3.Scalar",
1343*1c12ee1eSDan Willemsen					Value:   []byte("\xde\xad\xbe\xef"),
1344*1c12ee1eSDan Willemsen				},
1345*1c12ee1eSDan Willemsen			}
1346*1c12ee1eSDan Willemsen		}(),
1347*1c12ee1eSDan Willemsen		want: `opt_any: {
1348*1c12ee1eSDan Willemsen  type_url: "pb3.Scalar"
1349*1c12ee1eSDan Willemsen  value: "\u07ad\xbe\xef"
1350*1c12ee1eSDan Willemsen}
1351*1c12ee1eSDan Willemsen`,
1352*1c12ee1eSDan Willemsen	}, {
1353*1c12ee1eSDan Willemsen		desc: "Any inside Any expanded",
1354*1c12ee1eSDan Willemsen		input: func() *pb2.KnownTypes {
1355*1c12ee1eSDan Willemsen			m1 := &pb2.Nested{
1356*1c12ee1eSDan Willemsen				OptString: proto.String("invalid UTF-8 abc\xff"),
1357*1c12ee1eSDan Willemsen			}
1358*1c12ee1eSDan Willemsen			b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
1359*1c12ee1eSDan Willemsen			if err != nil {
1360*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1361*1c12ee1eSDan Willemsen			}
1362*1c12ee1eSDan Willemsen			m2 := &anypb.Any{
1363*1c12ee1eSDan Willemsen				TypeUrl: "pb2.Nested",
1364*1c12ee1eSDan Willemsen				Value:   b1,
1365*1c12ee1eSDan Willemsen			}
1366*1c12ee1eSDan Willemsen			b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
1367*1c12ee1eSDan Willemsen			if err != nil {
1368*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1369*1c12ee1eSDan Willemsen			}
1370*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
1371*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
1372*1c12ee1eSDan Willemsen					TypeUrl: "google.protobuf.Any",
1373*1c12ee1eSDan Willemsen					Value:   b2,
1374*1c12ee1eSDan Willemsen				},
1375*1c12ee1eSDan Willemsen			}
1376*1c12ee1eSDan Willemsen		}(),
1377*1c12ee1eSDan Willemsen		want: `opt_any: {
1378*1c12ee1eSDan Willemsen  [google.protobuf.Any]: {
1379*1c12ee1eSDan Willemsen    [pb2.Nested]: {
1380*1c12ee1eSDan Willemsen      opt_string: "invalid UTF-8 abc\xff"
1381*1c12ee1eSDan Willemsen    }
1382*1c12ee1eSDan Willemsen  }
1383*1c12ee1eSDan Willemsen}
1384*1c12ee1eSDan Willemsen`,
1385*1c12ee1eSDan Willemsen	}, {
1386*1c12ee1eSDan Willemsen		desc: "Any inside Any not expanded due to invalid data",
1387*1c12ee1eSDan Willemsen		mo:   prototext.MarshalOptions{EmitASCII: true},
1388*1c12ee1eSDan Willemsen		input: func() *pb2.KnownTypes {
1389*1c12ee1eSDan Willemsen			m := &anypb.Any{
1390*1c12ee1eSDan Willemsen				TypeUrl: "pb2.Nested",
1391*1c12ee1eSDan Willemsen				Value:   []byte("\xde\xad\xbe\xef"),
1392*1c12ee1eSDan Willemsen			}
1393*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1394*1c12ee1eSDan Willemsen			if err != nil {
1395*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1396*1c12ee1eSDan Willemsen			}
1397*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
1398*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
1399*1c12ee1eSDan Willemsen					TypeUrl: "google.protobuf.Any",
1400*1c12ee1eSDan Willemsen					Value:   b,
1401*1c12ee1eSDan Willemsen				},
1402*1c12ee1eSDan Willemsen			}
1403*1c12ee1eSDan Willemsen		}(),
1404*1c12ee1eSDan Willemsen		want: `opt_any: {
1405*1c12ee1eSDan Willemsen  [google.protobuf.Any]: {
1406*1c12ee1eSDan Willemsen    type_url: "pb2.Nested"
1407*1c12ee1eSDan Willemsen    value: "\u07ad\xbe\xef"
1408*1c12ee1eSDan Willemsen  }
1409*1c12ee1eSDan Willemsen}
1410*1c12ee1eSDan Willemsen`,
1411*1c12ee1eSDan Willemsen	}}
1412*1c12ee1eSDan Willemsen
1413*1c12ee1eSDan Willemsen	for _, tt := range tests {
1414*1c12ee1eSDan Willemsen		tt := tt
1415*1c12ee1eSDan Willemsen		if tt.skip {
1416*1c12ee1eSDan Willemsen			continue
1417*1c12ee1eSDan Willemsen		}
1418*1c12ee1eSDan Willemsen		t.Run(tt.desc, func(t *testing.T) {
1419*1c12ee1eSDan Willemsen			// Use 2-space indentation on all MarshalOptions.
1420*1c12ee1eSDan Willemsen			tt.mo.Indent = "  "
1421*1c12ee1eSDan Willemsen			b, err := tt.mo.Marshal(tt.input)
1422*1c12ee1eSDan Willemsen			if err != nil && !tt.wantErr {
1423*1c12ee1eSDan Willemsen				t.Errorf("Marshal() returned error: %v\n", err)
1424*1c12ee1eSDan Willemsen			}
1425*1c12ee1eSDan Willemsen			if err == nil && tt.wantErr {
1426*1c12ee1eSDan Willemsen				t.Error("Marshal() got nil error, want error\n")
1427*1c12ee1eSDan Willemsen			}
1428*1c12ee1eSDan Willemsen			got := string(b)
1429*1c12ee1eSDan Willemsen			if tt.want != "" && got != tt.want {
1430*1c12ee1eSDan Willemsen				t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
1431*1c12ee1eSDan Willemsen				if diff := cmp.Diff(tt.want, got); diff != "" {
1432*1c12ee1eSDan Willemsen					t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1433*1c12ee1eSDan Willemsen				}
1434*1c12ee1eSDan Willemsen			}
1435*1c12ee1eSDan Willemsen		})
1436*1c12ee1eSDan Willemsen	}
1437*1c12ee1eSDan Willemsen}
1438