blob: ce8bc7038f2013cf979ce2e2337ee54cc125e52d [file] [log] [blame]
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package impl
6
7import (
Joe Tsai91e14662018-09-13 13:24:35 -07008 "fmt"
9 "math"
10 "strings"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070011 "testing"
12
13 "github.com/google/go-cmp/cmp"
Joe Tsai91e14662018-09-13 13:24:35 -070014 "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070015
Joe Tsai2c870bb2018-10-17 11:46:52 -070016 "github.com/golang/protobuf/proto"
Damien Neil204f1c02018-10-23 15:03:38 -070017 protoV1 "github.com/golang/protobuf/proto"
18 descriptorV1 "github.com/golang/protobuf/protoc-gen-go/descriptor"
Joe Tsai01ab2962018-09-21 17:44:00 -070019 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
20 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070021)
22
Joe Tsaic6b75612018-09-13 14:24:37 -070023func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
24 md, err := ptype.NewMessage(&t)
25 if err != nil {
26 panic(err)
27 }
28 return md
29}
30
Joe Tsai91e14662018-09-13 13:24:35 -070031var V = pref.ValueOf
32
Joe Tsaifa02f4e2018-09-12 16:20:37 -070033type (
34 MyBool bool
35 MyInt32 int32
36 MyInt64 int64
37 MyUint32 uint32
38 MyUint64 uint64
39 MyFloat32 float32
40 MyFloat64 float64
41 MyString string
42 MyBytes []byte
Joe Tsai91e14662018-09-13 13:24:35 -070043
44 NamedStrings []MyString
45 NamedBytes []MyBytes
Joe Tsaibbfaeb72018-10-17 00:27:21 +000046
47 MapStrings map[MyString]MyString
48 MapBytes map[MyString]MyBytes
Joe Tsaifa02f4e2018-09-12 16:20:37 -070049)
50
Joe Tsai91e14662018-09-13 13:24:35 -070051// List of test operations to perform on messages, vectors, or maps.
52type (
53 messageOp interface{} // equalMessage | hasFields | getFields | setFields | clearFields | vectorFields | mapFields
54 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070055
Joe Tsai91e14662018-09-13 13:24:35 -070056 vectorOp interface{} // equalVector | lenVector | getVector | setVector | appendVector | truncVector
57 vectorOps []vectorOp
58
Joe Tsaibbfaeb72018-10-17 00:27:21 +000059 mapOp interface{} // equalMap | lenMap | hasMap | getMap | setMap | clearMap | rangeMap
60 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070061)
62
63// Test operations performed on a message.
64type (
65 equalMessage pref.Message
66 hasFields map[pref.FieldNumber]bool
67 getFields map[pref.FieldNumber]pref.Value
68 setFields map[pref.FieldNumber]pref.Value
69 clearFields map[pref.FieldNumber]bool
70 vectorFields map[pref.FieldNumber]vectorOps
71 mapFields map[pref.FieldNumber]mapOps
72 messageFields map[pref.FieldNumber]messageOps
73 // TODO: Mutable, Range, ExtensionTypes
74)
75
76// Test operations performed on a vector.
77type (
78 equalVector pref.Vector
79 lenVector int
80 getVector map[int]pref.Value
81 setVector map[int]pref.Value
82 appendVector []pref.Value
83 truncVector int
84 // TODO: Mutable, MutableAppend
85)
86
Joe Tsaibbfaeb72018-10-17 00:27:21 +000087// Test operations performed on a map.
88type (
89 equalMap pref.Map
90 lenMap int
91 hasMap map[interface{}]bool
92 getMap map[interface{}]pref.Value
93 setMap map[interface{}]pref.Value
94 clearMap map[interface{}]bool
95 rangeMap map[interface{}]pref.Value
Joe Tsai3903b212018-10-17 11:54:32 -070096 // TODO: Mutable
Joe Tsaibbfaeb72018-10-17 00:27:21 +000097)
98
Joe Tsai91e14662018-09-13 13:24:35 -070099func TestScalarProto2(t *testing.T) {
100 type ScalarProto2 struct {
101 Bool *bool `protobuf:"1"`
102 Int32 *int32 `protobuf:"2"`
103 Int64 *int64 `protobuf:"3"`
104 Uint32 *uint32 `protobuf:"4"`
105 Uint64 *uint64 `protobuf:"5"`
106 Float32 *float32 `protobuf:"6"`
107 Float64 *float64 `protobuf:"7"`
108 String *string `protobuf:"8"`
109 StringA []byte `protobuf:"9"`
110 Bytes []byte `protobuf:"10"`
111 BytesA *string `protobuf:"11"`
112
113 MyBool *MyBool `protobuf:"12"`
114 MyInt32 *MyInt32 `protobuf:"13"`
115 MyInt64 *MyInt64 `protobuf:"14"`
116 MyUint32 *MyUint32 `protobuf:"15"`
117 MyUint64 *MyUint64 `protobuf:"16"`
118 MyFloat32 *MyFloat32 `protobuf:"17"`
119 MyFloat64 *MyFloat64 `protobuf:"18"`
120 MyString *MyString `protobuf:"19"`
121 MyStringA MyBytes `protobuf:"20"`
122 MyBytes MyBytes `protobuf:"21"`
123 MyBytesA *MyString `protobuf:"22"`
124 }
125
126 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
127 Syntax: pref.Proto2,
128 FullName: "ScalarProto2",
129 Fields: []ptype.Field{
130 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
131 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
132 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
133 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
134 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
135 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
136 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
137 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
138 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
139 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
140 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
141
142 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
143 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
144 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
145 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
146 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
147 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
148 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
149 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
150 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
151 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
152 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
153 },
154 })}
155
156 testMessage(t, nil, mi.MessageOf(&ScalarProto2{}), messageOps{
157 hasFields{
158 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
159 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
160 },
161 getFields{
162 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
163 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
164 },
165 setFields{
166 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
167 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
168 },
169 hasFields{
170 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
171 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
172 },
173 equalMessage(mi.MessageOf(&ScalarProto2{
174 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
175 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
176 })),
177 clearFields{
178 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
179 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
180 },
181 equalMessage(mi.MessageOf(&ScalarProto2{})),
182 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700183}
184
Joe Tsai91e14662018-09-13 13:24:35 -0700185func TestScalarProto3(t *testing.T) {
186 type ScalarProto3 struct {
187 Bool bool `protobuf:"1"`
188 Int32 int32 `protobuf:"2"`
189 Int64 int64 `protobuf:"3"`
190 Uint32 uint32 `protobuf:"4"`
191 Uint64 uint64 `protobuf:"5"`
192 Float32 float32 `protobuf:"6"`
193 Float64 float64 `protobuf:"7"`
194 String string `protobuf:"8"`
195 StringA []byte `protobuf:"9"`
196 Bytes []byte `protobuf:"10"`
197 BytesA string `protobuf:"11"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700198
Joe Tsai91e14662018-09-13 13:24:35 -0700199 MyBool MyBool `protobuf:"12"`
200 MyInt32 MyInt32 `protobuf:"13"`
201 MyInt64 MyInt64 `protobuf:"14"`
202 MyUint32 MyUint32 `protobuf:"15"`
203 MyUint64 MyUint64 `protobuf:"16"`
204 MyFloat32 MyFloat32 `protobuf:"17"`
205 MyFloat64 MyFloat64 `protobuf:"18"`
206 MyString MyString `protobuf:"19"`
207 MyStringA MyBytes `protobuf:"20"`
208 MyBytes MyBytes `protobuf:"21"`
209 MyBytesA MyString `protobuf:"22"`
210 }
Joe Tsaic6b75612018-09-13 14:24:37 -0700211
Joe Tsai91e14662018-09-13 13:24:35 -0700212 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
213 Syntax: pref.Proto3,
214 FullName: "ScalarProto3",
215 Fields: []ptype.Field{
216 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
217 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
218 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
219 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
220 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
221 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
222 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
223 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
224 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
225 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
226 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700227
Joe Tsai91e14662018-09-13 13:24:35 -0700228 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
229 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
230 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
231 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
232 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
233 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
234 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
235 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
236 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
237 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
238 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
239 },
240 })}
241
242 testMessage(t, nil, mi.MessageOf(&ScalarProto3{}), messageOps{
243 hasFields{
244 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
245 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
246 },
247 getFields{
248 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
249 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
250 },
251 setFields{
252 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
253 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
254 },
255 hasFields{
256 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
257 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
258 },
259 equalMessage(mi.MessageOf(&ScalarProto3{})),
260 setFields{
261 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
262 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
263 },
264 hasFields{
265 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
266 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
267 },
268 equalMessage(mi.MessageOf(&ScalarProto3{
269 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
270 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
271 })),
272 clearFields{
273 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
274 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
275 },
276 equalMessage(mi.MessageOf(&ScalarProto3{})),
277 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700278}
279
Joe Tsai91e14662018-09-13 13:24:35 -0700280func TestRepeatedScalars(t *testing.T) {
281 type RepeatedScalars struct {
282 Bools []bool `protobuf:"1"`
283 Int32s []int32 `protobuf:"2"`
284 Int64s []int64 `protobuf:"3"`
285 Uint32s []uint32 `protobuf:"4"`
286 Uint64s []uint64 `protobuf:"5"`
287 Float32s []float32 `protobuf:"6"`
288 Float64s []float64 `protobuf:"7"`
289 Strings []string `protobuf:"8"`
290 StringsA [][]byte `protobuf:"9"`
291 Bytes [][]byte `protobuf:"10"`
292 BytesA []string `protobuf:"11"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700293
Joe Tsai91e14662018-09-13 13:24:35 -0700294 MyStrings1 []MyString `protobuf:"12"`
295 MyStrings2 []MyBytes `protobuf:"13"`
296 MyBytes1 []MyBytes `protobuf:"14"`
297 MyBytes2 []MyString `protobuf:"15"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700298
Joe Tsai91e14662018-09-13 13:24:35 -0700299 MyStrings3 NamedStrings `protobuf:"16"`
300 MyStrings4 NamedBytes `protobuf:"17"`
301 MyBytes3 NamedBytes `protobuf:"18"`
302 MyBytes4 NamedStrings `protobuf:"19"`
303 }
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700304
Joe Tsai91e14662018-09-13 13:24:35 -0700305 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
306 Syntax: pref.Proto2,
307 FullName: "RepeatedScalars",
308 Fields: []ptype.Field{
309 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
310 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
311 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
312 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
313 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
314 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
315 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
316 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
317 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
318 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
319 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700320
Joe Tsai91e14662018-09-13 13:24:35 -0700321 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
322 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
323 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
324 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
325
326 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
327 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
328 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
329 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700330 },
Joe Tsai91e14662018-09-13 13:24:35 -0700331 })}
332
333 empty := mi.MessageOf(&RepeatedScalars{})
334 emptyFS := empty.KnownFields()
335
336 want := mi.MessageOf(&RepeatedScalars{
337 Bools: []bool{true, false, true},
338 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
339 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
340 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
341 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
342 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
343 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
344 Strings: []string{"8", "", "eight"},
345 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
346 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
347 BytesA: []string{"11", "", "eleven"},
348
349 MyStrings1: []MyString{"12", "", "twelve"},
350 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
351 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
352 MyBytes2: []MyString{"15", "", "fifteen"},
353
354 MyStrings3: NamedStrings{"16", "", "sixteen"},
355 MyStrings4: NamedBytes{[]byte("17"), nil, []byte("seventeen")},
356 MyBytes3: NamedBytes{[]byte("18"), nil, []byte("eighteen")},
357 MyBytes4: NamedStrings{"19", "", "nineteen"},
358 })
359 wantFS := want.KnownFields()
360
361 testMessage(t, nil, mi.MessageOf(&RepeatedScalars{}), messageOps{
362 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
363 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19)},
364 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19)},
365 vectorFields{
366 2: {
367 lenVector(0),
368 appendVector{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
369 getVector{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
370 equalVector(wantFS.Get(2).Vector()),
371 },
372 4: {
373 appendVector{V(uint32(0)), V(uint32(0)), V(uint32(0))},
374 setVector{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
375 lenVector(3),
376 },
377 6: {
378 appendVector{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
379 equalVector(wantFS.Get(6).Vector()),
380 },
381 8: {
382 appendVector{V(""), V(""), V(""), V(""), V(""), V("")},
383 lenVector(6),
384 setVector{0: V("8"), 2: V("eight")},
385 truncVector(3),
386 equalVector(wantFS.Get(8).Vector()),
387 },
388 10: {
389 appendVector{V([]byte(nil)), V([]byte(nil))},
390 setVector{0: V([]byte("10"))},
391 appendVector{V([]byte("wrong"))},
392 setVector{2: V([]byte("ten"))},
393 equalVector(wantFS.Get(10).Vector()),
394 },
395 12: {
396 appendVector{V("12"), V("wrong"), V("twelve")},
397 setVector{1: V("")},
398 equalVector(wantFS.Get(12).Vector()),
399 },
400 14: {
401 appendVector{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
402 equalVector(wantFS.Get(14).Vector()),
403 },
404 16: {
405 appendVector{V("16"), V(""), V("sixteen"), V("extra")},
406 truncVector(3),
407 equalVector(wantFS.Get(16).Vector()),
408 },
409 18: {
410 appendVector{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
411 equalVector(wantFS.Get(18).Vector()),
412 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700413 },
Joe Tsai91e14662018-09-13 13:24:35 -0700414 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
415 equalMessage(want),
416 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000417 equalMessage(empty),
418 })
419}
420
421func TestMapScalars(t *testing.T) {
422 type MapScalars struct {
423 KeyBools map[bool]string `protobuf:"1"`
424 KeyInt32s map[int32]string `protobuf:"2"`
425 KeyInt64s map[int64]string `protobuf:"3"`
426 KeyUint32s map[uint32]string `protobuf:"4"`
427 KeyUint64s map[uint64]string `protobuf:"5"`
428 KeyStrings map[string]string `protobuf:"6"`
429
430 ValBools map[string]bool `protobuf:"7"`
431 ValInt32s map[string]int32 `protobuf:"8"`
432 ValInt64s map[string]int64 `protobuf:"9"`
433 ValUint32s map[string]uint32 `protobuf:"10"`
434 ValUint64s map[string]uint64 `protobuf:"11"`
435 ValFloat32s map[string]float32 `protobuf:"12"`
436 ValFloat64s map[string]float64 `protobuf:"13"`
437 ValStrings map[string]string `protobuf:"14"`
438 ValStringsA map[string][]byte `protobuf:"15"`
439 ValBytes map[string][]byte `protobuf:"16"`
440 ValBytesA map[string]string `protobuf:"17"`
441
442 MyStrings1 map[MyString]MyString `protobuf:"18"`
443 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
444 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
445 MyBytes2 map[MyString]MyString `protobuf:"21"`
446
447 MyStrings3 MapStrings `protobuf:"22"`
448 MyStrings4 MapBytes `protobuf:"23"`
449 MyBytes3 MapBytes `protobuf:"24"`
450 MyBytes4 MapStrings `protobuf:"25"`
451 }
452
453 mustMakeMapEntry := func(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
454 return ptype.Field{
455 Name: pref.Name(fmt.Sprintf("f%d", n)),
456 Number: n,
457 Cardinality: pref.Repeated,
458 Kind: pref.MessageKind,
459 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
460 Syntax: pref.Proto2,
461 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
462 Fields: []ptype.Field{
463 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
464 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
465 },
Damien Neil204f1c02018-10-23 15:03:38 -0700466 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000467 }),
468 }
469 }
470 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
471 Syntax: pref.Proto2,
472 FullName: "MapScalars",
473 Fields: []ptype.Field{
474 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
475 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
476 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
477 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
478 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
479 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
480
481 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
482 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
483 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
484 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
485 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
486 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
487 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
488 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
489 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
490 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
491 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
492
493 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
494 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
495 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
496 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
497
498 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
499 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
500 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
501 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
502 },
503 })}
504
505 empty := mi.MessageOf(&MapScalars{})
506 emptyFS := empty.KnownFields()
507
508 want := mi.MessageOf(&MapScalars{
509 KeyBools: map[bool]string{true: "true", false: "false"},
510 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
511 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
512 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
513 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
514 KeyStrings: map[string]string{"": "", "foo": "bar"},
515
516 ValBools: map[string]bool{"true": true, "false": false},
517 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
518 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
519 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
520 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
521 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
522 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
523 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
524 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
525 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
526 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
527
528 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
529 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
530 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
531 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
532
533 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
534 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
535 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
536 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
537 })
538 wantFS := want.KnownFields()
539
540 testMessage(t, nil, mi.MessageOf(&MapScalars{}), messageOps{
541 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
542 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19), 21: emptyFS.Get(21), 23: emptyFS.Get(23), 25: emptyFS.Get(25)},
543 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19), 21: wantFS.Get(21), 23: wantFS.Get(23), 25: wantFS.Get(25)},
544 mapFields{
545 2: {
546 lenMap(0),
547 hasMap{int32(0): false, int32(-1): false, int32(2): false},
548 setMap{int32(0): V("zero")},
549 lenMap(1),
550 hasMap{int32(0): true, int32(-1): false, int32(2): false},
551 setMap{int32(-1): V("one")},
552 lenMap(2),
553 hasMap{int32(0): true, int32(-1): true, int32(2): false},
554 setMap{int32(2): V("two")},
555 lenMap(3),
556 hasMap{int32(0): true, int32(-1): true, int32(2): true},
557 },
558 4: {
559 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
560 equalMap(wantFS.Get(4).Map()),
561 },
562 6: {
563 clearMap{"noexist": true},
564 setMap{"foo": V("bar")},
565 setMap{"": V("empty")},
566 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
567 setMap{"": V(""), "extra": V("extra")},
568 clearMap{"extra": true, "noexist": true},
569 },
570 8: {
571 equalMap(emptyFS.Get(8).Map()),
572 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
573 },
574 10: {
575 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
576 lenMap(3),
577 equalMap(wantFS.Get(10).Map()),
578 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
579 },
580 12: {
581 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
582 clearMap{"e": true, "phi": true},
583 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
584 },
585 14: {
586 equalMap(emptyFS.Get(14).Map()),
587 setMap{"s1": V("s1"), "s2": V("s2")},
588 },
589 16: {
590 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
591 equalMap(wantFS.Get(16).Map()),
592 },
593 18: {
594 hasMap{"s1": false, "s2": false, "s3": false},
595 setMap{"s1": V("s1"), "s2": V("s2")},
596 hasMap{"s1": true, "s2": true, "s3": false},
597 },
598 20: {
599 equalMap(emptyFS.Get(20).Map()),
600 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
601 },
602 22: {
603 rangeMap{},
604 setMap{"s1": V("s1"), "s2": V("s2")},
605 rangeMap{"s1": V("s1"), "s2": V("s2")},
606 lenMap(2),
607 },
608 24: {
609 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
610 equalMap(wantFS.Get(24).Map()),
611 },
612 },
613 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
614 equalMessage(want),
615 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
616 equalMessage(empty),
Joe Tsai91e14662018-09-13 13:24:35 -0700617 })
618}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700619
Joe Tsai2c870bb2018-10-17 11:46:52 -0700620type (
621 OneofScalars struct {
622 Union isOneofScalars_Union `protobuf_oneof:"union"`
623 }
624 isOneofScalars_Union interface {
625 isOneofScalars_Union()
626 }
627
628 OneofScalars_Bool struct {
629 Bool bool `protobuf:"1"`
630 }
631 OneofScalars_Int32 struct {
632 Int32 MyInt32 `protobuf:"2"`
633 }
634 OneofScalars_Int64 struct {
635 Int64 int64 `protobuf:"3"`
636 }
637 OneofScalars_Uint32 struct {
638 Uint32 MyUint32 `protobuf:"4"`
639 }
640 OneofScalars_Uint64 struct {
641 Uint64 uint64 `protobuf:"5"`
642 }
643 OneofScalars_Float32 struct {
644 Float32 MyFloat32 `protobuf:"6"`
645 }
646 OneofScalars_Float64 struct {
647 Float64 float64 `protobuf:"7"`
648 }
649 OneofScalars_String struct {
650 String string `protobuf:"8"`
651 }
652 OneofScalars_StringA struct {
653 StringA []byte `protobuf:"9"`
654 }
655 OneofScalars_StringB struct {
656 StringB MyString `protobuf:"10"`
657 }
658 OneofScalars_Bytes struct {
659 Bytes []byte `protobuf:"11"`
660 }
661 OneofScalars_BytesA struct {
662 BytesA string `protobuf:"12"`
663 }
664 OneofScalars_BytesB struct {
665 BytesB MyBytes `protobuf:"13"`
666 }
667)
668
669func (*OneofScalars) XXX_OneofFuncs() (func(proto.Message, *proto.Buffer) error, func(proto.Message, int, int, *proto.Buffer) (bool, error), func(proto.Message) int, []interface{}) {
670 return nil, nil, nil, []interface{}{
671 (*OneofScalars_Bool)(nil),
672 (*OneofScalars_Int32)(nil),
673 (*OneofScalars_Int64)(nil),
674 (*OneofScalars_Uint32)(nil),
675 (*OneofScalars_Uint64)(nil),
676 (*OneofScalars_Float32)(nil),
677 (*OneofScalars_Float64)(nil),
678 (*OneofScalars_String)(nil),
679 (*OneofScalars_StringA)(nil),
680 (*OneofScalars_StringB)(nil),
681 (*OneofScalars_Bytes)(nil),
682 (*OneofScalars_BytesA)(nil),
683 (*OneofScalars_BytesB)(nil),
684 }
685}
686
687func (*OneofScalars_Bool) isOneofScalars_Union() {}
688func (*OneofScalars_Int32) isOneofScalars_Union() {}
689func (*OneofScalars_Int64) isOneofScalars_Union() {}
690func (*OneofScalars_Uint32) isOneofScalars_Union() {}
691func (*OneofScalars_Uint64) isOneofScalars_Union() {}
692func (*OneofScalars_Float32) isOneofScalars_Union() {}
693func (*OneofScalars_Float64) isOneofScalars_Union() {}
694func (*OneofScalars_String) isOneofScalars_Union() {}
695func (*OneofScalars_StringA) isOneofScalars_Union() {}
696func (*OneofScalars_StringB) isOneofScalars_Union() {}
697func (*OneofScalars_Bytes) isOneofScalars_Union() {}
698func (*OneofScalars_BytesA) isOneofScalars_Union() {}
699func (*OneofScalars_BytesB) isOneofScalars_Union() {}
700
701func TestOneofs(t *testing.T) {
702 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
703 Syntax: pref.Proto2,
704 FullName: "ScalarProto2",
705 Fields: []ptype.Field{
706 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
707 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
708 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
709 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
710 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
711 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
712 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
713 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
714 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
715 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
716 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
717 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
718 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
719 },
720 Oneofs: []ptype.Oneof{{Name: "union"}},
721 })}
722
723 empty := mi.MessageOf(&OneofScalars{})
724 want1 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Bool{true}})
725 want2 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Int32{20}})
726 want3 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Int64{30}})
727 want4 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Uint32{40}})
728 want5 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Uint64{50}})
729 want6 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Float32{60}})
730 want7 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Float64{70}})
731 want8 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_String{string("80")}})
732 want9 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}})
733 want10 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_StringB{MyString("100")}})
734 want11 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}})
735 want12 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_BytesA{string("120")}})
736 want13 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}})
737
738 testMessage(t, nil, mi.MessageOf(&OneofScalars{}), messageOps{
739 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
740 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
741
742 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage(want1),
743 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage(want2),
744 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage(want3),
745 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage(want4),
746 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage(want5),
747 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage(want6),
748 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage(want7),
749 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage(want8),
750 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage(want9),
751 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage(want10),
752 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage(want11),
753 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage(want12),
754 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage(want13),
755
756 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: true},
757 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("130"))},
758 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true},
759 equalMessage(want13),
760 clearFields{13: true},
761 equalMessage(empty),
762 })
763}
764
Joe Tsai91e14662018-09-13 13:24:35 -0700765// TODO: Need to test singular and repeated messages
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700766
Joe Tsai91e14662018-09-13 13:24:35 -0700767var cmpOpts = cmp.Options{
768 cmp.Transformer("UnwrapValue", func(v pref.Value) interface{} {
769 return v.Interface()
770 }),
771 cmp.Transformer("UnwrapMessage", func(m pref.Message) interface{} {
772 v := m.Interface()
773 if v, ok := v.(interface{ Unwrap() interface{} }); ok {
774 return v.Unwrap()
775 }
776 return v
777 }),
778 cmp.Transformer("UnwrapVector", func(v pref.Vector) interface{} {
779 return v.(interface{ Unwrap() interface{} }).Unwrap()
780 }),
781 cmp.Transformer("UnwrapMap", func(m pref.Map) interface{} {
782 return m.(interface{ Unwrap() interface{} }).Unwrap()
783 }),
784 cmpopts.EquateNaNs(),
785}
786
787func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
788 fs := m.KnownFields()
789 for i, op := range tt {
790 p.Push(i)
791 switch op := op.(type) {
792 case equalMessage:
793 if diff := cmp.Diff(op, m, cmpOpts); diff != "" {
794 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
795 }
796 case hasFields:
797 got := map[pref.FieldNumber]bool{}
798 want := map[pref.FieldNumber]bool(op)
799 for n := range want {
800 got[n] = fs.Has(n)
801 }
802 if diff := cmp.Diff(want, got); diff != "" {
803 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
804 }
805 case getFields:
806 got := map[pref.FieldNumber]pref.Value{}
807 want := map[pref.FieldNumber]pref.Value(op)
808 for n := range want {
809 got[n] = fs.Get(n)
810 }
811 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
812 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
813 }
814 case setFields:
815 for n, v := range op {
816 fs.Set(n, v)
817 }
818 case clearFields:
819 for n, ok := range op {
820 if ok {
821 fs.Clear(n)
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700822 }
823 }
Joe Tsai91e14662018-09-13 13:24:35 -0700824 case vectorFields:
825 for n, tt := range op {
826 p.Push(int(n))
827 testVectors(t, p, fs.Mutable(n).(pref.Vector), tt)
828 p.Pop()
829 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000830 case mapFields:
831 for n, tt := range op {
832 p.Push(int(n))
833 testMaps(t, p, fs.Mutable(n).(pref.Map), tt)
834 p.Pop()
835 }
Joe Tsai91e14662018-09-13 13:24:35 -0700836 default:
837 t.Fatalf("operation %v, invalid operation: %T", p, op)
838 }
839 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700840 }
841}
Joe Tsai91e14662018-09-13 13:24:35 -0700842
843func testVectors(t *testing.T, p path, v pref.Vector, tt vectorOps) {
844 for i, op := range tt {
845 p.Push(i)
846 switch op := op.(type) {
847 case equalVector:
848 if diff := cmp.Diff(op, v, cmpOpts); diff != "" {
849 t.Errorf("operation %v, vector mismatch (-want, +got):\n%s", p, diff)
850 }
851 case lenVector:
852 if got, want := v.Len(), int(op); got != want {
853 t.Errorf("operation %v, Vector.Len = %d, want %d", p, got, want)
854 }
855 case getVector:
856 got := map[int]pref.Value{}
857 want := map[int]pref.Value(op)
858 for n := range want {
859 got[n] = v.Get(n)
860 }
861 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
862 t.Errorf("operation %v, Vector.Get mismatch (-want, +got):\n%s", p, diff)
863 }
864 case setVector:
865 for n, e := range op {
866 v.Set(n, e)
867 }
868 case appendVector:
869 for _, e := range op {
870 v.Append(e)
871 }
872 case truncVector:
873 v.Truncate(int(op))
874 default:
875 t.Fatalf("operation %v, invalid operation: %T", p, op)
876 }
877 p.Pop()
878 }
879}
880
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000881func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
882 for i, op := range tt {
883 p.Push(i)
884 switch op := op.(type) {
885 case equalMap:
886 if diff := cmp.Diff(op, m, cmpOpts); diff != "" {
887 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
888 }
889 case lenMap:
890 if got, want := m.Len(), int(op); got != want {
891 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
892 }
893 case hasMap:
894 got := map[interface{}]bool{}
895 want := map[interface{}]bool(op)
896 for k := range want {
897 got[k] = m.Has(V(k).MapKey())
898 }
899 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
900 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
901 }
902 case getMap:
903 got := map[interface{}]pref.Value{}
904 want := map[interface{}]pref.Value(op)
905 for k := range want {
906 got[k] = m.Get(V(k).MapKey())
907 }
908 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
909 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
910 }
911 case setMap:
912 for k, v := range op {
913 m.Set(V(k).MapKey(), v)
914 }
915 case clearMap:
916 for v, ok := range op {
917 if ok {
918 m.Clear(V(v).MapKey())
919 }
920 }
921 case rangeMap:
922 got := map[interface{}]pref.Value{}
923 want := map[interface{}]pref.Value(op)
924 m.Range(func(k pref.MapKey, v pref.Value) bool {
925 got[k.Interface()] = v
926 return true
927 })
928 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
929 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
930 }
931 default:
932 t.Fatalf("operation %v, invalid operation: %T", p, op)
933 }
934 p.Pop()
935 }
936}
937
Joe Tsai91e14662018-09-13 13:24:35 -0700938type path []int
939
940func (p *path) Push(i int) { *p = append(*p, i) }
941func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
942func (p path) String() string {
943 var ss []string
944 for _, i := range p {
945 ss = append(ss, fmt.Sprint(i))
946 }
947 return strings.Join(ss, ".")
948}