blob: 68ceb453c0120181e02b995a59d6fc4421df8c3a [file] [log] [blame]
Herbie Ongcddf8192018-11-28 18:25:20 -08001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package prototext_test
Herbie Ongcddf8192018-11-28 18:25:20 -08006
7import (
8 "math"
Herbie Ongcddf8192018-11-28 18:25:20 -08009 "testing"
10
Herbie Ongcddf8192018-11-28 18:25:20 -080011 "github.com/google/go-cmp/cmp"
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/internal/detrand"
14 "google.golang.org/protobuf/internal/encoding/pack"
Joe Tsai5ae10aa2019-07-11 18:23:08 -070015 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070016 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070017 "google.golang.org/protobuf/proto"
18 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ongcddf8192018-11-28 18:25:20 -080019
Damien Neile89e6242019-05-13 23:55:40 -070020 "google.golang.org/protobuf/encoding/testprotos/pb2"
21 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070022 "google.golang.org/protobuf/types/known/anypb"
Herbie Ongcddf8192018-11-28 18:25:20 -080023)
24
25func init() {
26 // Disable detrand to enable direct comparisons on outputs.
27 detrand.Disable()
28}
29
Herbie Ongcddf8192018-11-28 18:25:20 -080030func TestMarshal(t *testing.T) {
31 tests := []struct {
32 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070033 mo prototext.MarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080034 input proto.Message
Herbie Ongcddf8192018-11-28 18:25:20 -080035 want string
Herbie Ong300cff02019-03-20 18:05:16 -070036 wantErr bool // TODO: Verify error message content.
Joe Tsai5ae10aa2019-07-11 18:23:08 -070037 skip bool
Herbie Ongcddf8192018-11-28 18:25:20 -080038 }{{
Herbie Ong8170d692019-02-13 14:13:21 -080039 desc: "proto2 optional scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080040 input: &pb2.Scalars{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -070041 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -080042 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080043 desc: "proto3 scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080044 input: &pb3.Scalars{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -070045 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -080046 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080047 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080048 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070049 OptBool: proto.Bool(false),
50 OptInt32: proto.Int32(0),
51 OptInt64: proto.Int64(0),
52 OptUint32: proto.Uint32(0),
53 OptUint64: proto.Uint64(0),
54 OptSint32: proto.Int32(0),
55 OptSint64: proto.Int64(0),
56 OptFixed32: proto.Uint32(0),
57 OptFixed64: proto.Uint64(0),
58 OptSfixed32: proto.Int32(0),
59 OptSfixed64: proto.Int64(0),
60 OptFloat: proto.Float32(0),
61 OptDouble: proto.Float64(0),
Herbie Ongcddf8192018-11-28 18:25:20 -080062 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070063 OptString: proto.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -080064 },
Herbie Ongcddf8192018-11-28 18:25:20 -080065 want: `opt_bool: false
66opt_int32: 0
67opt_int64: 0
68opt_uint32: 0
69opt_uint64: 0
70opt_sint32: 0
71opt_sint64: 0
72opt_fixed32: 0
73opt_fixed64: 0
74opt_sfixed32: 0
75opt_sfixed64: 0
76opt_float: 0
77opt_double: 0
78opt_bytes: ""
79opt_string: ""
80`,
81 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080082 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080083 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -080084 SBool: false,
85 SInt32: 0,
86 SInt64: 0,
87 SUint32: 0,
88 SUint64: 0,
89 SSint32: 0,
90 SSint64: 0,
91 SFixed32: 0,
92 SFixed64: 0,
93 SSfixed32: 0,
94 SSfixed64: 0,
95 SFloat: 0,
96 SDouble: 0,
97 SBytes: []byte{},
98 SString: "",
Herbie Ong800c9902018-12-06 15:28:53 -080099 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700100 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800101 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800102 desc: "proto2 optional scalars set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800103 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700104 OptBool: proto.Bool(true),
105 OptInt32: proto.Int32(0xff),
106 OptInt64: proto.Int64(0xdeadbeef),
107 OptUint32: proto.Uint32(47),
108 OptUint64: proto.Uint64(0xdeadbeef),
109 OptSint32: proto.Int32(-1001),
110 OptSint64: proto.Int64(-0xffff),
111 OptFixed64: proto.Uint64(64),
112 OptSfixed32: proto.Int32(-32),
113 OptFloat: proto.Float32(1.02),
114 OptDouble: proto.Float64(1.0199999809265137),
Herbie Ong8170d692019-02-13 14:13:21 -0800115 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
Damien Neila8a2cea2019-07-10 16:17:16 -0700116 OptString: proto.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800117 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800118 want: `opt_bool: true
119opt_int32: 255
120opt_int64: 3735928559
121opt_uint32: 47
122opt_uint64: 3735928559
123opt_sint32: -1001
124opt_sint64: -65535
125opt_fixed64: 64
126opt_sfixed32: -32
Herbie Ong84f09602019-01-17 19:31:47 -0800127opt_float: 1.02
128opt_double: 1.0199999809265137
Herbie Ongcddf8192018-11-28 18:25:20 -0800129opt_bytes: "谷歌"
130opt_string: "谷歌"
131`,
132 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700133 desc: "string with invalid UTF-8",
134 input: &pb3.Scalars{
135 SString: "abc\xff",
136 },
Herbie Ong21a39742019-04-08 17:32:44 -0700137 wantErr: true,
138 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800139 desc: "float nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800140 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800141 SFloat: float32(math.NaN()),
Herbie Ong800c9902018-12-06 15:28:53 -0800142 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800143 want: "s_float: nan\n",
144 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800145 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800146 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800147 SFloat: float32(math.Inf(1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800148 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800149 want: "s_float: inf\n",
150 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800151 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800152 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800153 SFloat: float32(math.Inf(-1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800154 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800155 want: "s_float: -inf\n",
156 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800157 desc: "double nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800158 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800159 SDouble: math.NaN(),
Herbie Ong800c9902018-12-06 15:28:53 -0800160 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800161 want: "s_double: nan\n",
162 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800163 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800164 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800165 SDouble: math.Inf(1),
Herbie Ong800c9902018-12-06 15:28:53 -0800166 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800167 want: "s_double: inf\n",
168 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800169 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800170 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800171 SDouble: math.Inf(-1),
Herbie Ong800c9902018-12-06 15:28:53 -0800172 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800173 want: "s_double: -inf\n",
174 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800175 desc: "proto2 enum not set",
176 input: &pb2.Enums{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700177 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800178 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800179 desc: "proto2 enum set to zero value",
180 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700181 OptEnum: pb2.Enum(0).Enum(),
182 OptNestedEnum: pb2.Enums_NestedEnum(0).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800183 },
Herbie Ong8170d692019-02-13 14:13:21 -0800184 want: `opt_enum: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800185opt_nested_enum: 0
186`,
187 }, {
188 desc: "proto2 enum",
189 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800190 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800191 OptNestedEnum: pb2.Enums_UNO.Enum(),
192 },
Herbie Ong8170d692019-02-13 14:13:21 -0800193 want: `opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800194opt_nested_enum: UNO
195`,
196 }, {
197 desc: "proto2 enum set to numeric values",
198 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700199 OptEnum: pb2.Enum(2).Enum(),
200 OptNestedEnum: pb2.Enums_NestedEnum(2).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800201 },
Herbie Ong8170d692019-02-13 14:13:21 -0800202 want: `opt_enum: TWO
Herbie Ong800c9902018-12-06 15:28:53 -0800203opt_nested_enum: DOS
204`,
205 }, {
206 desc: "proto2 enum set to unnamed numeric values",
207 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700208 OptEnum: pb2.Enum(101).Enum(),
209 OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800210 },
211 want: `opt_enum: 101
212opt_nested_enum: -101
213`,
214 }, {
215 desc: "proto3 enum not set",
216 input: &pb3.Enums{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700217 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800218 }, {
219 desc: "proto3 enum set to zero value",
220 input: &pb3.Enums{
221 SEnum: pb3.Enum_ZERO,
222 SNestedEnum: pb3.Enums_CERO,
223 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700224 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800225 }, {
226 desc: "proto3 enum",
227 input: &pb3.Enums{
228 SEnum: pb3.Enum_ONE,
Herbie Ong8170d692019-02-13 14:13:21 -0800229 SNestedEnum: pb3.Enums_UNO,
Herbie Ong800c9902018-12-06 15:28:53 -0800230 },
231 want: `s_enum: ONE
Herbie Ong8170d692019-02-13 14:13:21 -0800232s_nested_enum: UNO
Herbie Ong800c9902018-12-06 15:28:53 -0800233`,
234 }, {
235 desc: "proto3 enum set to numeric values",
236 input: &pb3.Enums{
237 SEnum: 2,
Herbie Ong8170d692019-02-13 14:13:21 -0800238 SNestedEnum: 2,
Herbie Ong800c9902018-12-06 15:28:53 -0800239 },
240 want: `s_enum: TWO
Herbie Ong8170d692019-02-13 14:13:21 -0800241s_nested_enum: DOS
Herbie Ong800c9902018-12-06 15:28:53 -0800242`,
243 }, {
244 desc: "proto3 enum set to unnamed numeric values",
245 input: &pb3.Enums{
246 SEnum: -47,
247 SNestedEnum: 47,
248 },
249 want: `s_enum: -47
250s_nested_enum: 47
251`,
252 }, {
253 desc: "proto2 nested message not set",
254 input: &pb2.Nests{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700255 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800256 }, {
257 desc: "proto2 nested message set to empty",
258 input: &pb2.Nests{
259 OptNested: &pb2.Nested{},
260 Optgroup: &pb2.Nests_OptGroup{},
261 },
262 want: `opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800263OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800264`,
265 }, {
266 desc: "proto2 nested messages",
267 input: &pb2.Nests{
268 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700269 OptString: proto.String("nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800270 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700271 OptString: proto.String("another nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800272 },
273 },
274 },
275 want: `opt_nested: {
276 opt_string: "nested message"
277 opt_nested: {
278 opt_string: "another nested message"
279 }
280}
281`,
282 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800283 desc: "proto2 groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800284 input: &pb2.Nests{
285 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700286 OptString: proto.String("inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800287 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700288 OptString: proto.String("nested message inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800289 },
290 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700291 OptFixed32: proto.Uint32(47),
Herbie Ong800c9902018-12-06 15:28:53 -0800292 },
293 },
294 },
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800295 want: `OptGroup: {
Herbie Ong800c9902018-12-06 15:28:53 -0800296 opt_string: "inside a group"
297 opt_nested: {
298 opt_string: "nested message inside a group"
299 }
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800300 OptNestedGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800301 opt_fixed32: 47
Herbie Ong800c9902018-12-06 15:28:53 -0800302 }
303}
304`,
305 }, {
306 desc: "proto3 nested message not set",
307 input: &pb3.Nests{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700308 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800309 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800310 desc: "proto3 nested message set to empty",
311 input: &pb3.Nests{
312 SNested: &pb3.Nested{},
313 },
314 want: "s_nested: {}\n",
315 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800316 desc: "proto3 nested message",
317 input: &pb3.Nests{
318 SNested: &pb3.Nested{
319 SString: "nested message",
320 SNested: &pb3.Nested{
321 SString: "another nested message",
322 },
323 },
324 },
325 want: `s_nested: {
326 s_string: "nested message"
327 s_nested: {
328 s_string: "another nested message"
329 }
330}
331`,
332 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700333 desc: "proto3 nested message contains invalid UTF-8",
334 input: &pb3.Nests{
335 SNested: &pb3.Nested{
336 SString: "abc\xff",
337 },
338 },
Herbie Ong21a39742019-04-08 17:32:44 -0700339 wantErr: true,
340 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800341 desc: "oneof not set",
342 input: &pb3.Oneofs{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700343 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800344 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800345 desc: "oneof set to empty string",
346 input: &pb3.Oneofs{
347 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800348 },
Herbie Ong8170d692019-02-13 14:13:21 -0800349 want: `oneof_string: ""
350`,
Herbie Ong800c9902018-12-06 15:28:53 -0800351 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800352 desc: "oneof set to string",
353 input: &pb3.Oneofs{
354 Union: &pb3.Oneofs_OneofString{
355 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800356 },
357 },
Herbie Ong8170d692019-02-13 14:13:21 -0800358 want: `oneof_string: "hello"
359`,
Herbie Ong800c9902018-12-06 15:28:53 -0800360 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800361 desc: "oneof set to enum",
362 input: &pb3.Oneofs{
363 Union: &pb3.Oneofs_OneofEnum{
364 OneofEnum: pb3.Enum_ZERO,
Herbie Ong800c9902018-12-06 15:28:53 -0800365 },
366 },
Herbie Ong8170d692019-02-13 14:13:21 -0800367 want: `oneof_enum: ZERO
368`,
Herbie Ong800c9902018-12-06 15:28:53 -0800369 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800370 desc: "oneof set to empty message",
371 input: &pb3.Oneofs{
372 Union: &pb3.Oneofs_OneofNested{
373 OneofNested: &pb3.Nested{},
374 },
375 },
376 want: "oneof_nested: {}\n",
377 }, {
378 desc: "oneof set to message",
379 input: &pb3.Oneofs{
380 Union: &pb3.Oneofs_OneofNested{
381 OneofNested: &pb3.Nested{
382 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800383 },
384 },
385 },
Herbie Ong8170d692019-02-13 14:13:21 -0800386 want: `oneof_nested: {
387 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800388}
389`,
390 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800391 desc: "repeated fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800392 input: &pb2.Repeats{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700393 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800394 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800395 desc: "repeated fields set to empty slices",
Herbie Ong800c9902018-12-06 15:28:53 -0800396 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800397 RptBool: []bool{},
398 RptInt32: []int32{},
399 RptInt64: []int64{},
400 RptUint32: []uint32{},
401 RptUint64: []uint64{},
402 RptFloat: []float32{},
403 RptDouble: []float64{},
404 RptBytes: [][]byte{},
Herbie Ong800c9902018-12-06 15:28:53 -0800405 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700406 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800407 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800408 desc: "repeated fields set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800409 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800410 RptBool: []bool{true, false, true, true},
411 RptInt32: []int32{1, 6, 0, 0},
412 RptInt64: []int64{-64, 47},
413 RptUint32: []uint32{0xff, 0xffff},
414 RptUint64: []uint64{0xdeadbeef},
Herbie Ong84f09602019-01-17 19:31:47 -0800415 RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
Herbie Ongcddf8192018-11-28 18:25:20 -0800416 RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
417 RptString: []string{"hello", "世界"},
418 RptBytes: [][]byte{
419 []byte("hello"),
420 []byte("\xe4\xb8\x96\xe7\x95\x8c"),
421 },
Herbie Ong800c9902018-12-06 15:28:53 -0800422 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800423 want: `rpt_bool: true
424rpt_bool: false
425rpt_bool: true
426rpt_bool: true
427rpt_int32: 1
428rpt_int32: 6
429rpt_int32: 0
430rpt_int32: 0
431rpt_int64: -64
432rpt_int64: 47
433rpt_uint32: 255
434rpt_uint32: 65535
435rpt_uint64: 3735928559
Herbie Ong84f09602019-01-17 19:31:47 -0800436rpt_float: nan
437rpt_float: inf
438rpt_float: -inf
439rpt_float: 1.034
Herbie Ongcddf8192018-11-28 18:25:20 -0800440rpt_double: nan
441rpt_double: inf
442rpt_double: -inf
443rpt_double: 1.23e-308
444rpt_string: "hello"
445rpt_string: "世界"
446rpt_bytes: "hello"
447rpt_bytes: "世界"
448`,
449 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700450 desc: "repeated contains invalid UTF-8",
451 input: &pb2.Repeats{
452 RptString: []string{"abc\xff"},
453 },
Herbie Ong21a39742019-04-08 17:32:44 -0700454 wantErr: true,
455 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800456 desc: "repeated enums",
Herbie Ong800c9902018-12-06 15:28:53 -0800457 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800458 RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
Herbie Ongcddf8192018-11-28 18:25:20 -0800459 RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
Herbie Ong800c9902018-12-06 15:28:53 -0800460 },
Herbie Ong8170d692019-02-13 14:13:21 -0800461 want: `rpt_enum: ONE
462rpt_enum: TWO
463rpt_enum: TEN
Herbie Ongcddf8192018-11-28 18:25:20 -0800464rpt_enum: 42
Herbie Ongcddf8192018-11-28 18:25:20 -0800465rpt_nested_enum: DOS
466rpt_nested_enum: 47
467rpt_nested_enum: DIEZ
468`,
469 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800470 desc: "repeated messages set to empty",
Herbie Ong800c9902018-12-06 15:28:53 -0800471 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800472 RptNested: []*pb2.Nested{},
473 Rptgroup: []*pb2.Nests_RptGroup{},
Herbie Ong800c9902018-12-06 15:28:53 -0800474 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700475 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800476 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800477 desc: "repeated messages",
Herbie Ong800c9902018-12-06 15:28:53 -0800478 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800479 RptNested: []*pb2.Nested{
480 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700481 OptString: proto.String("repeat nested one"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800482 },
483 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700484 OptString: proto.String("repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800485 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700486 OptString: proto.String("inside repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800487 },
488 },
489 {},
490 },
Herbie Ong800c9902018-12-06 15:28:53 -0800491 },
492 want: `rpt_nested: {
Herbie Ongcddf8192018-11-28 18:25:20 -0800493 opt_string: "repeat nested one"
494}
495rpt_nested: {
496 opt_string: "repeat nested two"
497 opt_nested: {
498 opt_string: "inside repeat nested two"
499 }
500}
501rpt_nested: {}
502`,
503 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800504 desc: "repeated messages contains nil value",
Herbie Ongf5db2df2019-02-07 20:17:45 -0800505 input: &pb2.Nests{
506 RptNested: []*pb2.Nested{nil, {}},
507 },
508 want: `rpt_nested: {}
509rpt_nested: {}
510`,
511 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800512 desc: "repeated groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800513 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800514 Rptgroup: []*pb2.Nests_RptGroup{
515 {
Herbie Ong8170d692019-02-13 14:13:21 -0800516 RptString: []string{"hello", "world"},
Herbie Ongcddf8192018-11-28 18:25:20 -0800517 },
518 {},
Herbie Ong8170d692019-02-13 14:13:21 -0800519 nil,
Herbie Ongcddf8192018-11-28 18:25:20 -0800520 },
Herbie Ong800c9902018-12-06 15:28:53 -0800521 },
Herbie Ongde7313b2019-01-14 19:26:50 -0800522 want: `RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800523 rpt_string: "hello"
524 rpt_string: "world"
Herbie Ongcddf8192018-11-28 18:25:20 -0800525}
Herbie Ongde7313b2019-01-14 19:26:50 -0800526RptGroup: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800527RptGroup: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800528`,
529 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800530 desc: "map fields not set",
531 input: &pb3.Maps{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700532 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800533 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800534 desc: "map fields set to empty",
535 input: &pb3.Maps{
536 Int32ToStr: map[int32]string{},
537 BoolToUint32: map[bool]uint32{},
538 Uint64ToEnum: map[uint64]pb3.Enum{},
539 StrToNested: map[string]*pb3.Nested{},
540 StrToOneofs: map[string]*pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800541 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700542 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800543 }, {
544 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800545 input: &pb3.Maps{
Herbie Ongcddf8192018-11-28 18:25:20 -0800546 Int32ToStr: map[int32]string{
547 -101: "-101",
548 0xff: "0xff",
549 0: "zero",
550 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800551 BoolToUint32: map[bool]uint32{
552 true: 42,
553 false: 101,
554 },
Herbie Ong800c9902018-12-06 15:28:53 -0800555 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800556 want: `int32_to_str: {
557 key: -101
558 value: "-101"
559}
560int32_to_str: {
561 key: 0
562 value: "zero"
563}
564int32_to_str: {
565 key: 255
566 value: "0xff"
567}
Herbie Ongcddf8192018-11-28 18:25:20 -0800568bool_to_uint32: {
569 key: false
570 value: 101
571}
572bool_to_uint32: {
573 key: true
574 value: 42
575}
576`,
577 }, {
578 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800579 input: &pb3.Maps{
580 Uint64ToEnum: map[uint64]pb3.Enum{
581 1: pb3.Enum_ONE,
582 2: pb3.Enum_TWO,
583 10: pb3.Enum_TEN,
584 47: 47,
Herbie Ongcddf8192018-11-28 18:25:20 -0800585 },
Herbie Ong800c9902018-12-06 15:28:53 -0800586 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800587 want: `uint64_to_enum: {
588 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800589 value: ONE
Herbie Ongcddf8192018-11-28 18:25:20 -0800590}
591uint64_to_enum: {
592 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800593 value: TWO
Herbie Ongcddf8192018-11-28 18:25:20 -0800594}
595uint64_to_enum: {
596 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800597 value: TEN
598}
599uint64_to_enum: {
600 key: 47
601 value: 47
Herbie Ongcddf8192018-11-28 18:25:20 -0800602}
603`,
604 }, {
605 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800606 input: &pb3.Maps{
607 StrToNested: map[string]*pb3.Nested{
608 "nested": &pb3.Nested{
609 SString: "nested in a map",
Herbie Ongcddf8192018-11-28 18:25:20 -0800610 },
611 },
Herbie Ong800c9902018-12-06 15:28:53 -0800612 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800613 want: `str_to_nested: {
Herbie Ong8170d692019-02-13 14:13:21 -0800614 key: "nested"
Herbie Ongcddf8192018-11-28 18:25:20 -0800615 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800616 s_string: "nested in a map"
Herbie Ongcddf8192018-11-28 18:25:20 -0800617 }
618}
619`,
620 }, {
621 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800622 input: &pb3.Maps{
623 StrToOneofs: map[string]*pb3.Oneofs{
624 "string": &pb3.Oneofs{
625 Union: &pb3.Oneofs_OneofString{
626 OneofString: "hello",
Herbie Ongcddf8192018-11-28 18:25:20 -0800627 },
628 },
Herbie Ong8170d692019-02-13 14:13:21 -0800629 "nested": &pb3.Oneofs{
630 Union: &pb3.Oneofs_OneofNested{
631 OneofNested: &pb3.Nested{
632 SString: "nested oneof in map field value",
Herbie Ongcddf8192018-11-28 18:25:20 -0800633 },
634 },
635 },
636 },
Herbie Ong800c9902018-12-06 15:28:53 -0800637 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800638 want: `str_to_oneofs: {
639 key: "nested"
640 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800641 oneof_nested: {
642 s_string: "nested oneof in map field value"
Herbie Ongcddf8192018-11-28 18:25:20 -0800643 }
644 }
645}
646str_to_oneofs: {
647 key: "string"
648 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800649 oneof_string: "hello"
Herbie Ongcddf8192018-11-28 18:25:20 -0800650 }
651}
652`,
653 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700654 desc: "map field value contains invalid UTF-8",
655 input: &pb3.Maps{
656 Int32ToStr: map[int32]string{
657 101: "abc\xff",
658 },
659 },
Herbie Ong21a39742019-04-08 17:32:44 -0700660 wantErr: true,
661 }, {
662 desc: "map field key contains invalid UTF-8",
663 input: &pb3.Maps{
664 StrToNested: map[string]*pb3.Nested{
665 "abc\xff": {},
666 },
667 },
Herbie Ong21a39742019-04-08 17:32:44 -0700668 wantErr: true,
669 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800670 desc: "map field contains nil value",
671 input: &pb3.Maps{
672 StrToNested: map[string]*pb3.Nested{
Herbie Ongf5db2df2019-02-07 20:17:45 -0800673 "nil": nil,
674 },
675 },
676 want: `str_to_nested: {
677 key: "nil"
678 value: {}
679}
680`,
681 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700682 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800683 input: &pb2.Requireds{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700684 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800685 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800686 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700687 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800688 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700689 ReqBool: proto.Bool(false),
690 ReqSfixed64: proto.Int64(0xbeefcafe),
691 ReqDouble: proto.Float64(math.NaN()),
692 ReqString: proto.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800693 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800694 },
695 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800696req_sfixed64: 3203386110
697req_double: nan
698req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800699req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800700`,
701 wantErr: true,
702 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700703 desc: "required fields not set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700704 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700705 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700706 ReqBool: proto.Bool(false),
707 ReqSfixed64: proto.Int64(0xbeefcafe),
708 ReqDouble: proto.Float64(math.NaN()),
709 ReqString: proto.String("hello"),
Herbie Ong42577ea2019-03-26 16:26:22 -0700710 ReqEnum: pb2.Enum_ONE.Enum(),
711 },
712 want: `req_bool: false
713req_sfixed64: 3203386110
714req_double: nan
715req_string: "hello"
716req_enum: ONE
717`,
718 }, {
719 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800720 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700721 ReqBool: proto.Bool(false),
722 ReqSfixed64: proto.Int64(0),
723 ReqDouble: proto.Float64(1.23),
724 ReqString: proto.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800725 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800726 ReqNested: &pb2.Nested{},
727 },
728 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800729req_sfixed64: 0
Herbie Ong8170d692019-02-13 14:13:21 -0800730req_double: 1.23
Herbie Ong800c9902018-12-06 15:28:53 -0800731req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800732req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800733req_nested: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800734`,
735 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800736 desc: "indirect required field",
737 input: &pb2.IndirectRequired{
738 OptNested: &pb2.NestedWithRequired{},
739 },
740 want: "opt_nested: {}\n",
741 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800742 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700743 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700744 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700745 input: &pb2.IndirectRequired{
746 OptNested: &pb2.NestedWithRequired{},
747 },
748 want: "opt_nested: {}\n",
749 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800750 desc: "indirect required field in empty repeated",
751 input: &pb2.IndirectRequired{
752 RptNested: []*pb2.NestedWithRequired{},
753 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700754 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800755 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800756 desc: "indirect required field in repeated",
757 input: &pb2.IndirectRequired{
758 RptNested: []*pb2.NestedWithRequired{
759 &pb2.NestedWithRequired{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800760 },
Herbie Ong800c9902018-12-06 15:28:53 -0800761 },
762 want: "rpt_nested: {}\n",
763 wantErr: true,
764 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700765 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700766 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700767 input: &pb2.IndirectRequired{
768 RptNested: []*pb2.NestedWithRequired{
769 &pb2.NestedWithRequired{},
770 },
771 },
772 want: "rpt_nested: {}\n",
773 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800774 desc: "indirect required field in empty map",
775 input: &pb2.IndirectRequired{
776 StrToNested: map[string]*pb2.NestedWithRequired{},
777 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700778 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800779 }, {
780 desc: "indirect required field in map",
781 input: &pb2.IndirectRequired{
782 StrToNested: map[string]*pb2.NestedWithRequired{
783 "fail": &pb2.NestedWithRequired{},
784 },
785 },
786 want: `str_to_nested: {
787 key: "fail"
788 value: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800789}
790`,
Herbie Ong800c9902018-12-06 15:28:53 -0800791 wantErr: true,
Herbie Ong20a1d312018-12-11 21:08:58 -0800792 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700793 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700794 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700795 input: &pb2.IndirectRequired{
796 StrToNested: map[string]*pb2.NestedWithRequired{
797 "fail": &pb2.NestedWithRequired{},
798 },
799 },
800 want: `str_to_nested: {
801 key: "fail"
802 value: {}
803}
804`,
805 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800806 desc: "indirect required field in oneof",
807 input: &pb2.IndirectRequired{
808 Union: &pb2.IndirectRequired_OneofNested{
809 OneofNested: &pb2.NestedWithRequired{},
810 },
811 },
812 want: "oneof_nested: {}\n",
813 wantErr: true,
814 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700815 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700816 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700817 input: &pb2.IndirectRequired{
818 Union: &pb2.IndirectRequired_OneofNested{
819 OneofNested: &pb2.NestedWithRequired{},
820 },
821 },
822 want: "oneof_nested: {}\n",
823 }, {
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700824 desc: "unknown fields not printed",
825 input: func() proto.Message {
826 m := &pb2.Scalars{
827 OptString: proto.String("this message contains unknown fields"),
828 }
829 m.ProtoReflect().SetUnknown(pack.Message{
830 pack.Tag{101, pack.VarintType}, pack.Bool(true),
831 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
832 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
833 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
834 }.Marshal())
835 return m
836 }(),
837 want: `opt_string: "this message contains unknown fields"
838`,
839 }, {
Herbie Ong20a1d312018-12-11 21:08:58 -0800840 desc: "unknown varint and fixed types",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700841 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700842 input: func() proto.Message {
843 m := &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700844 OptString: proto.String("this message contains unknown fields"),
Joe Tsai28216c72019-06-22 13:20:09 -0700845 }
846 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800847 pack.Tag{101, pack.VarintType}, pack.Bool(true),
848 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
849 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
850 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
Joe Tsai28216c72019-06-22 13:20:09 -0700851 }.Marshal())
852 return m
853 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800854 want: `opt_string: "this message contains unknown fields"
855101: 1
856102: 255
857103: 47
858104: 3735928559
859`,
860 }, {
861 desc: "unknown length-delimited",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700862 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700863 input: func() proto.Message {
864 m := new(pb2.Scalars)
865 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800866 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
867 pack.Tag{102, pack.BytesType}, pack.String("hello world"),
868 pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
Joe Tsai28216c72019-06-22 13:20:09 -0700869 }.Marshal())
870 return m
871 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800872 want: `101: "\x01\x00"
873102: "hello world"
874103: "世界"
875`,
876 }, {
877 desc: "unknown group type",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700878 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700879 input: func() proto.Message {
880 m := new(pb2.Scalars)
881 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800882 pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
883 pack.Tag{102, pack.StartGroupType},
884 pack.Tag{101, pack.VarintType}, pack.Bool(false),
885 pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
886 pack.Tag{102, pack.EndGroupType},
Joe Tsai28216c72019-06-22 13:20:09 -0700887 }.Marshal())
888 return m
889 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800890 want: `101: {}
891102: {
892 101: 0
893 102: "inside a group"
894}
895`,
896 }, {
897 desc: "unknown unpack repeated field",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700898 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700899 input: func() proto.Message {
900 m := new(pb2.Scalars)
901 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800902 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
903 pack.Tag{102, pack.BytesType}, pack.String("hello"),
904 pack.Tag{101, pack.VarintType}, pack.Bool(true),
905 pack.Tag{102, pack.BytesType}, pack.String("世界"),
Joe Tsai28216c72019-06-22 13:20:09 -0700906 }.Marshal())
907 return m
908 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800909 want: `101: "\x01\x00\x01"
Herbie Ong20a1d312018-12-11 21:08:58 -0800910102: "hello"
Joe Tsai378c1322019-04-25 23:48:08 -0700911101: 1
Herbie Ong20a1d312018-12-11 21:08:58 -0800912102: "世界"
913`,
Herbie Ongcf253082018-12-17 17:13:07 -0800914 }, {
915 desc: "extensions of non-repeated fields",
916 input: func() proto.Message {
917 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -0700918 OptString: proto.String("non-extension field"),
919 OptBool: proto.Bool(true),
920 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -0800921 }
Damien Neil92f76182019-08-02 16:58:08 -0700922 proto.SetExtension(m, pb2.E_OptExtBool, true)
923 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
924 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
925 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700926 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800927 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700928 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800929 },
930 })
931 return m
932 }(),
933 want: `opt_string: "non-extension field"
934opt_bool: true
935opt_int32: 42
936[pb2.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800937[pb2.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800938[pb2.opt_ext_nested]: {
939 opt_string: "nested in an extension"
940 opt_nested: {
941 opt_string: "another nested in an extension"
942 }
943}
944[pb2.opt_ext_string]: "extension field"
945`,
946 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700947 desc: "extension field contains invalid UTF-8",
948 input: func() proto.Message {
949 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700950 proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
Herbie Ong21a39742019-04-08 17:32:44 -0700951 return m
952 }(),
Herbie Ong21a39742019-04-08 17:32:44 -0700953 wantErr: true,
954 }, {
Herbie Ong09b28a92019-04-03 15:42:41 -0700955 desc: "extension partial returns error",
956 input: func() proto.Message {
957 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700958 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700959 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700960 })
Damien Neil92f76182019-08-02 16:58:08 -0700961 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700962 OptString: proto.String("partial2"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700963 })
964 return m
965 }(),
966 want: `[pb2.ExtensionsContainer.opt_ext_partial]: {
967 opt_string: "partial2"
968}
969[pb2.opt_ext_partial]: {
970 opt_string: "partial1"
971}
972`,
973 wantErr: true,
974 }, {
975 desc: "extension partial with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700976 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong09b28a92019-04-03 15:42:41 -0700977 input: func() proto.Message {
978 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700979 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700980 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700981 })
982 return m
983 }(),
984 want: `[pb2.opt_ext_partial]: {
985 opt_string: "partial1"
986}
987`,
988 }, {
Herbie Ongcf253082018-12-17 17:13:07 -0800989 desc: "extensions of repeated fields",
990 input: func() proto.Message {
991 m := &pb2.Extensions{}
Damien Neil293dc762019-08-29 11:42:57 -0700992 proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
993 proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
994 proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700995 &pb2.Nested{OptString: proto.String("one")},
996 &pb2.Nested{OptString: proto.String("two")},
997 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -0800998 })
999 return m
1000 }(),
Herbie Ong8170d692019-02-13 14:13:21 -08001001 want: `[pb2.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001002[pb2.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001003[pb2.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001004[pb2.rpt_ext_fixed32]: 42
1005[pb2.rpt_ext_fixed32]: 47
1006[pb2.rpt_ext_nested]: {
1007 opt_string: "one"
1008}
1009[pb2.rpt_ext_nested]: {
1010 opt_string: "two"
1011}
1012[pb2.rpt_ext_nested]: {
1013 opt_string: "three"
1014}
1015`,
1016 }, {
1017 desc: "extensions of non-repeated fields in another message",
1018 input: func() proto.Message {
1019 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001020 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1021 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1022 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1023 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001024 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001025 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001026 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001027 },
1028 })
1029 return m
1030 }(),
1031 want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001032[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001033[pb2.ExtensionsContainer.opt_ext_nested]: {
1034 opt_string: "nested in an extension"
1035 opt_nested: {
1036 opt_string: "another nested in an extension"
1037 }
1038}
1039[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1040`,
1041 }, {
1042 desc: "extensions of repeated fields in another message",
1043 input: func() proto.Message {
1044 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001045 OptString: proto.String("non-extension field"),
1046 OptBool: proto.Bool(true),
1047 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -08001048 }
Damien Neil293dc762019-08-29 11:42:57 -07001049 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1050 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1051 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001052 &pb2.Nested{OptString: proto.String("one")},
1053 &pb2.Nested{OptString: proto.String("two")},
1054 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -08001055 })
1056 return m
1057 }(),
1058 want: `opt_string: "non-extension field"
1059opt_bool: true
1060opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001061[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001062[pb2.ExtensionsContainer.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001063[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001064[pb2.ExtensionsContainer.rpt_ext_nested]: {
1065 opt_string: "one"
1066}
1067[pb2.ExtensionsContainer.rpt_ext_nested]: {
1068 opt_string: "two"
1069}
1070[pb2.ExtensionsContainer.rpt_ext_nested]: {
1071 opt_string: "three"
1072}
1073[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
1074[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1075`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001076 }, {
1077 desc: "MessageSet",
1078 input: func() proto.Message {
1079 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001080 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001081 OptString: proto.String("a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001082 })
Damien Neil92f76182019-08-02 16:58:08 -07001083 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001084 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001085 })
Damien Neil92f76182019-08-02 16:58:08 -07001086 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001087 OptString: proto.String("just a regular extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001088 })
1089 return m
1090 }(),
1091 want: `[pb2.MessageSetExtension]: {
1092 opt_string: "a messageset extension"
1093}
1094[pb2.MessageSetExtension.ext_nested]: {
1095 opt_string: "just a regular extension"
1096}
1097[pb2.MessageSetExtension.not_message_set_extension]: {
1098 opt_string: "not a messageset extension"
1099}
1100`,
Joe Tsai1799d112019-08-08 13:31:59 -07001101 skip: !flags.ProtoLegacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001102 }, {
1103 desc: "not real MessageSet 1",
1104 input: func() proto.Message {
1105 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001106 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001107 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001108 })
1109 return m
1110 }(),
1111 want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1112 opt_string: "not a messageset extension"
1113}
1114`,
Joe Tsai1799d112019-08-08 13:31:59 -07001115 skip: !flags.ProtoLegacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001116 }, {
1117 desc: "not real MessageSet 2",
1118 input: func() proto.Message {
1119 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001120 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001121 OptString: proto.String("another not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001122 })
1123 return m
1124 }(),
1125 want: `[pb2.message_set_extension]: {
1126 opt_string: "another not a messageset extension"
1127}
1128`,
Joe Tsai1799d112019-08-08 13:31:59 -07001129 skip: !flags.ProtoLegacy,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001130 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001131 desc: "Any not expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001132 mo: prototext.MarshalOptions{
Herbie Ong66c365c2019-01-04 14:08:41 -08001133 Resolver: preg.NewTypes(),
1134 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001135 input: func() proto.Message {
1136 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001137 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001138 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001139 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001140 },
1141 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001142 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001143 if err != nil {
1144 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1145 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001146 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001147 TypeUrl: "pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001148 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001149 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001150 }(),
1151 want: `type_url: "pb2.Nested"
1152value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1153`,
1154 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001155 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001156 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001157 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001158 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001159 input: func() proto.Message {
1160 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001161 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001162 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001163 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001164 },
1165 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001166 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001167 if err != nil {
1168 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1169 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001170 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001171 TypeUrl: "foo/pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001172 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001173 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001174 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001175 want: `[foo/pb2.Nested]: {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001176 opt_string: "embedded inside Any"
1177 opt_nested: {
1178 opt_string: "inception"
1179 }
1180}
1181`,
1182 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001183 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001184 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001185 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001186 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001187 input: func() proto.Message {
1188 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001189 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001190 }
Damien Neil96c229a2019-04-03 12:17:24 -07001191 b, err := proto.MarshalOptions{
1192 AllowPartial: true,
1193 Deterministic: true,
1194 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001195 if err != nil {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001196 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1197 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001198 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001199 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001200 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001201 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001202 }(),
1203 want: `[pb2.PartialRequired]: {
1204 opt_string: "embedded inside Any"
1205}
1206`,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001207 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001208 desc: "Any with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001209 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001210 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001211 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001212 input: &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001213 TypeUrl: "foo/pb2.Nested",
Joe Tsai6dc168e2019-07-09 23:11:13 -07001214 Value: []byte("\x80"),
Herbie Ong300cff02019-03-20 18:05:16 -07001215 },
Herbie Ong66c365c2019-01-04 14:08:41 -08001216 want: `type_url: "foo/pb2.Nested"
Herbie Onga94f78c2019-01-03 15:39:58 -08001217value: "\x80"
1218`,
Herbie Ongcddf8192018-11-28 18:25:20 -08001219 }}
1220
1221 for _, tt := range tests {
1222 tt := tt
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001223 if tt.skip {
1224 continue
1225 }
Herbie Ongcddf8192018-11-28 18:25:20 -08001226 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong3a385912019-03-20 14:04:24 -07001227 // Use 2-space indentation on all MarshalOptions.
1228 tt.mo.Indent = " "
Herbie Ongf42b55f2019-01-02 15:46:07 -08001229 b, err := tt.mo.Marshal(tt.input)
Herbie Ongcddf8192018-11-28 18:25:20 -08001230 if err != nil && !tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001231 t.Errorf("Marshal() returned error: %v\n", err)
Herbie Ongcddf8192018-11-28 18:25:20 -08001232 }
Herbie Ong800c9902018-12-06 15:28:53 -08001233 if err == nil && tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001234 t.Error("Marshal() got nil error, want error\n")
Herbie Ongcddf8192018-11-28 18:25:20 -08001235 }
Herbie Ong800c9902018-12-06 15:28:53 -08001236 got := string(b)
1237 if tt.want != "" && got != tt.want {
1238 t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
Joe Tsai378c1322019-04-25 23:48:08 -07001239 if diff := cmp.Diff(tt.want, got); diff != "" {
Herbie Ongcddf8192018-11-28 18:25:20 -08001240 t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1241 }
1242 }
1243 })
1244 }
1245}