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