blob: 5852896ae668d68251c324db8f044de9ee822108 [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
Damien Neil204f1c02018-10-23 15:03:38 -070013 protoV1 "github.com/golang/protobuf/proto"
14 descriptorV1 "github.com/golang/protobuf/protoc-gen-go/descriptor"
Joe Tsai01ab2962018-09-21 17:44:00 -070015 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
16 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsai87b955b2018-11-14 21:59:49 -080017 cmp "github.com/google/go-cmp/cmp"
18 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070019
Joe Tsai87b955b2018-11-14 21:59:49 -080020 proto2_20180125 "github.com/golang/protobuf/v2/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
21 pvalue "github.com/golang/protobuf/v2/internal/value"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070022)
23
Joe Tsai4b7aff62018-11-14 14:05:19 -080024// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070025type (
Joe Tsai87b955b2018-11-14 21:59:49 -080026 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070027 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070028
Joe Tsai87b955b2018-11-14 21:59:49 -080029 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080030 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070031
Joe Tsai87b955b2018-11-14 21:59:49 -080032 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000033 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070034)
35
36// Test operations performed on a message.
37type (
Joe Tsai87b955b2018-11-14 21:59:49 -080038 // check that the message contents match
39 equalMessage struct{ pref.Message }
40 // check presence for specific fields in the message
41 hasFields map[pref.FieldNumber]bool
42 // check that specific message fields match
43 getFields map[pref.FieldNumber]pref.Value
44 // set specific message fields
45 setFields map[pref.FieldNumber]pref.Value
46 // clear specific fields in the message
47 clearFields []pref.FieldNumber
48 // apply messageOps on each specified message field
Joe Tsai91e14662018-09-13 13:24:35 -070049 messageFields map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080050 // apply listOps on each specified list field
51 listFields map[pref.FieldNumber]listOps
52 // apply mapOps on each specified map fields
53 mapFields map[pref.FieldNumber]mapOps
54 // range through all fields and check that they match
55 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070056)
57
Joe Tsai87b955b2018-11-14 21:59:49 -080058func (equalMessage) isMessageOp() {}
59func (hasFields) isMessageOp() {}
60func (getFields) isMessageOp() {}
61func (setFields) isMessageOp() {}
62func (clearFields) isMessageOp() {}
63func (messageFields) isMessageOp() {}
64func (listFields) isMessageOp() {}
65func (mapFields) isMessageOp() {}
66func (rangeFields) isMessageOp() {}
67
Joe Tsai4b7aff62018-11-14 14:05:19 -080068// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070069type (
Joe Tsai87b955b2018-11-14 21:59:49 -080070 // check that the list contents match
71 equalList struct{ pref.List }
72 // check that list length matches
73 lenList int
74 // check that specific list entries match
75 getList map[int]pref.Value
76 // set specific list entries
77 setList map[int]pref.Value
78 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080079 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080080 // apply messageOps on a newly appended message
81 appendMessageList messageOps
82 // truncate the list to the specified length
83 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -070084)
85
Joe Tsai87b955b2018-11-14 21:59:49 -080086func (equalList) isListOp() {}
87func (lenList) isListOp() {}
88func (getList) isListOp() {}
89func (setList) isListOp() {}
90func (appendList) isListOp() {}
91func (appendMessageList) isListOp() {}
92func (truncList) isListOp() {}
93
Joe Tsaibbfaeb72018-10-17 00:27:21 +000094// Test operations performed on a map.
95type (
Joe Tsai87b955b2018-11-14 21:59:49 -080096 // check that the map contents match
97 equalMap struct{ pref.Map }
98 // check that map length matches
99 lenMap int
100 // check presence for specific entries in the map
101 hasMap map[interface{}]bool
102 // check that specific map entries match
103 getMap map[interface{}]pref.Value
104 // set specific map entries
105 setMap map[interface{}]pref.Value
106 // clear specific entries in the map
107 clearMap []interface{}
108 // apply messageOps on each specified message entry
109 messageMap map[interface{}]messageOps
110 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000111 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000112)
113
Joe Tsai87b955b2018-11-14 21:59:49 -0800114func (equalMap) isMapOp() {}
115func (lenMap) isMapOp() {}
116func (hasMap) isMapOp() {}
117func (getMap) isMapOp() {}
118func (setMap) isMapOp() {}
119func (clearMap) isMapOp() {}
120func (messageMap) isMapOp() {}
121func (rangeMap) isMapOp() {}
122
Joe Tsaice6edd32018-10-19 16:27:46 -0700123type ScalarProto2 struct {
124 Bool *bool `protobuf:"1"`
125 Int32 *int32 `protobuf:"2"`
126 Int64 *int64 `protobuf:"3"`
127 Uint32 *uint32 `protobuf:"4"`
128 Uint64 *uint64 `protobuf:"5"`
129 Float32 *float32 `protobuf:"6"`
130 Float64 *float64 `protobuf:"7"`
131 String *string `protobuf:"8"`
132 StringA []byte `protobuf:"9"`
133 Bytes []byte `protobuf:"10"`
134 BytesA *string `protobuf:"11"`
135
136 MyBool *MyBool `protobuf:"12"`
137 MyInt32 *MyInt32 `protobuf:"13"`
138 MyInt64 *MyInt64 `protobuf:"14"`
139 MyUint32 *MyUint32 `protobuf:"15"`
140 MyUint64 *MyUint64 `protobuf:"16"`
141 MyFloat32 *MyFloat32 `protobuf:"17"`
142 MyFloat64 *MyFloat64 `protobuf:"18"`
143 MyString *MyString `protobuf:"19"`
144 MyStringA MyBytes `protobuf:"20"`
145 MyBytes MyBytes `protobuf:"21"`
146 MyBytesA *MyString `protobuf:"22"`
147}
148
Joe Tsai87b955b2018-11-14 21:59:49 -0800149func mustMakeEnumDesc(t ptype.StandaloneEnum) pref.EnumDescriptor {
150 ed, err := ptype.NewEnum(&t)
151 if err != nil {
152 panic(err)
153 }
154 return ed
155}
156
157func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
158 md, err := ptype.NewMessage(&t)
159 if err != nil {
160 panic(err)
161 }
162 return md
163}
164
165var V = pref.ValueOf
166var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
167
168type (
169 MyBool bool
170 MyInt32 int32
171 MyInt64 int64
172 MyUint32 uint32
173 MyUint64 uint64
174 MyFloat32 float32
175 MyFloat64 float64
176 MyString string
177 MyBytes []byte
178
179 ListStrings []MyString
180 ListBytes []MyBytes
181
182 MapStrings map[MyString]MyString
183 MapBytes map[MyString]MyBytes
184)
185
Joe Tsaif0c01e42018-11-06 13:05:20 -0800186var scalarProto2Type = MessageType{Type: ptype.GoMessage(
187 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700188 Syntax: pref.Proto2,
189 FullName: "ScalarProto2",
190 Fields: []ptype.Field{
191 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
192 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
193 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
194 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
195 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
196 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
197 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
198 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
199 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
200 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
201 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
202
203 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
204 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
205 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
206 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
207 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
208 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
209 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
210 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
211 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
212 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
213 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
214 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800215 }),
216 func(pref.MessageType) pref.ProtoMessage {
217 return new(ScalarProto2)
218 },
219)}
Joe Tsai91e14662018-09-13 13:24:35 -0700220
Joe Tsaif0c01e42018-11-06 13:05:20 -0800221func (m *ScalarProto2) Type() pref.MessageType { return scalarProto2Type.Type }
222func (m *ScalarProto2) KnownFields() pref.KnownFields { return scalarProto2Type.KnownFieldsOf(m) }
223func (m *ScalarProto2) UnknownFields() pref.UnknownFields { return scalarProto2Type.UnknownFieldsOf(m) }
224func (m *ScalarProto2) Interface() pref.ProtoMessage { return m }
225func (m *ScalarProto2) ProtoReflect() pref.Message { return m }
226func (m *ScalarProto2) ProtoMutable() {}
227
228func TestScalarProto2(t *testing.T) {
229 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700230 hasFields{
231 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
232 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
233 },
234 getFields{
235 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")),
236 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")),
237 },
238 setFields{
239 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)),
240 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)),
241 },
242 hasFields{
243 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
244 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
245 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800246 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700247 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
248 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
Joe Tsai87b955b2018-11-14 21:59:49 -0800249 }},
250 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
251 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700252 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700253}
254
Joe Tsaice6edd32018-10-19 16:27:46 -0700255type ScalarProto3 struct {
256 Bool bool `protobuf:"1"`
257 Int32 int32 `protobuf:"2"`
258 Int64 int64 `protobuf:"3"`
259 Uint32 uint32 `protobuf:"4"`
260 Uint64 uint64 `protobuf:"5"`
261 Float32 float32 `protobuf:"6"`
262 Float64 float64 `protobuf:"7"`
263 String string `protobuf:"8"`
264 StringA []byte `protobuf:"9"`
265 Bytes []byte `protobuf:"10"`
266 BytesA string `protobuf:"11"`
267
268 MyBool MyBool `protobuf:"12"`
269 MyInt32 MyInt32 `protobuf:"13"`
270 MyInt64 MyInt64 `protobuf:"14"`
271 MyUint32 MyUint32 `protobuf:"15"`
272 MyUint64 MyUint64 `protobuf:"16"`
273 MyFloat32 MyFloat32 `protobuf:"17"`
274 MyFloat64 MyFloat64 `protobuf:"18"`
275 MyString MyString `protobuf:"19"`
276 MyStringA MyBytes `protobuf:"20"`
277 MyBytes MyBytes `protobuf:"21"`
278 MyBytesA MyString `protobuf:"22"`
279}
280
Joe Tsaif0c01e42018-11-06 13:05:20 -0800281var scalarProto3Type = MessageType{Type: ptype.GoMessage(
282 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700283 Syntax: pref.Proto3,
284 FullName: "ScalarProto3",
285 Fields: []ptype.Field{
286 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
287 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
288 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
289 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
290 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
291 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
292 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
293 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
294 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
295 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
296 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700297
Joe Tsai91e14662018-09-13 13:24:35 -0700298 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
299 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
300 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
301 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
302 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
303 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
304 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
305 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
306 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
307 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
308 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
309 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800310 }),
311 func(pref.MessageType) pref.ProtoMessage {
312 return new(ScalarProto3)
313 },
314)}
Joe Tsai91e14662018-09-13 13:24:35 -0700315
Joe Tsaif0c01e42018-11-06 13:05:20 -0800316func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.Type }
317func (m *ScalarProto3) KnownFields() pref.KnownFields { return scalarProto3Type.KnownFieldsOf(m) }
318func (m *ScalarProto3) UnknownFields() pref.UnknownFields { return scalarProto3Type.UnknownFieldsOf(m) }
319func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
320func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
321func (m *ScalarProto3) ProtoMutable() {}
322
323func TestScalarProto3(t *testing.T) {
324 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700325 hasFields{
326 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
327 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
328 },
329 getFields{
330 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)),
331 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)),
332 },
333 setFields{
334 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)),
335 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)),
336 },
337 hasFields{
338 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
339 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
340 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800341 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700342 setFields{
343 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")),
344 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")),
345 },
346 hasFields{
347 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
348 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
349 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800350 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700351 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
352 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800353 }},
354 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
355 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700356 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700357}
358
Joe Tsaif0c01e42018-11-06 13:05:20 -0800359type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700360 Bools []bool `protobuf:"1"`
361 Int32s []int32 `protobuf:"2"`
362 Int64s []int64 `protobuf:"3"`
363 Uint32s []uint32 `protobuf:"4"`
364 Uint64s []uint64 `protobuf:"5"`
365 Float32s []float32 `protobuf:"6"`
366 Float64s []float64 `protobuf:"7"`
367 Strings []string `protobuf:"8"`
368 StringsA [][]byte `protobuf:"9"`
369 Bytes [][]byte `protobuf:"10"`
370 BytesA []string `protobuf:"11"`
371
372 MyStrings1 []MyString `protobuf:"12"`
373 MyStrings2 []MyBytes `protobuf:"13"`
374 MyBytes1 []MyBytes `protobuf:"14"`
375 MyBytes2 []MyString `protobuf:"15"`
376
Joe Tsai4b7aff62018-11-14 14:05:19 -0800377 MyStrings3 ListStrings `protobuf:"16"`
378 MyStrings4 ListBytes `protobuf:"17"`
379 MyBytes3 ListBytes `protobuf:"18"`
380 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700381}
382
Joe Tsaif0c01e42018-11-06 13:05:20 -0800383var listScalarsType = MessageType{Type: ptype.GoMessage(
384 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700385 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800386 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700387 Fields: []ptype.Field{
388 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
389 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
390 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
391 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
392 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
393 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
394 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
395 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
396 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
397 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
398 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700399
Joe Tsai91e14662018-09-13 13:24:35 -0700400 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
401 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
402 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
403 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
404
405 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
406 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
407 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
408 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700409 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800410 }),
411 func(pref.MessageType) pref.ProtoMessage {
412 return new(ListScalars)
413 },
414)}
Joe Tsai91e14662018-09-13 13:24:35 -0700415
Joe Tsaif0c01e42018-11-06 13:05:20 -0800416func (m *ListScalars) Type() pref.MessageType { return listScalarsType.Type }
417func (m *ListScalars) KnownFields() pref.KnownFields { return listScalarsType.KnownFieldsOf(m) }
418func (m *ListScalars) UnknownFields() pref.UnknownFields { return listScalarsType.UnknownFieldsOf(m) }
419func (m *ListScalars) Interface() pref.ProtoMessage { return m }
420func (m *ListScalars) ProtoReflect() pref.Message { return m }
421func (m *ListScalars) ProtoMutable() {}
422
423func TestListScalars(t *testing.T) {
424 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700425 emptyFS := empty.KnownFields()
426
Joe Tsaif0c01e42018-11-06 13:05:20 -0800427 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700428 Bools: []bool{true, false, true},
429 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
430 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
431 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
432 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
433 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
434 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
435 Strings: []string{"8", "", "eight"},
436 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
437 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
438 BytesA: []string{"11", "", "eleven"},
439
440 MyStrings1: []MyString{"12", "", "twelve"},
441 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
442 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
443 MyBytes2: []MyString{"15", "", "fifteen"},
444
Joe Tsai4b7aff62018-11-14 14:05:19 -0800445 MyStrings3: ListStrings{"16", "", "sixteen"},
446 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
447 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
448 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800449 }
Joe Tsai91e14662018-09-13 13:24:35 -0700450 wantFS := want.KnownFields()
451
Joe Tsaif0c01e42018-11-06 13:05:20 -0800452 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700453 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},
454 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)},
455 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)},
Joe Tsai4b7aff62018-11-14 14:05:19 -0800456 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700457 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800458 lenList(0),
459 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
460 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800461 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700462 },
463 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800464 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
465 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
466 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700467 },
468 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800469 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800470 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700471 },
472 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800473 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
474 lenList(6),
475 setList{0: V("8"), 2: V("eight")},
476 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800477 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700478 },
479 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800480 appendList{V([]byte(nil)), V([]byte(nil))},
481 setList{0: V([]byte("10"))},
482 appendList{V([]byte("wrong"))},
483 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800484 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700485 },
486 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800487 appendList{V("12"), V("wrong"), V("twelve")},
488 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800489 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700490 },
491 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800492 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800493 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700494 },
495 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800496 appendList{V("16"), V(""), V("sixteen"), V("extra")},
497 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800498 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700499 },
500 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800501 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800502 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700503 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700504 },
Joe Tsai91e14662018-09-13 13:24:35 -0700505 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},
Joe Tsai87b955b2018-11-14 21:59:49 -0800506 equalMessage{want},
507 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
508 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000509 })
510}
511
Joe Tsaice6edd32018-10-19 16:27:46 -0700512type MapScalars struct {
513 KeyBools map[bool]string `protobuf:"1"`
514 KeyInt32s map[int32]string `protobuf:"2"`
515 KeyInt64s map[int64]string `protobuf:"3"`
516 KeyUint32s map[uint32]string `protobuf:"4"`
517 KeyUint64s map[uint64]string `protobuf:"5"`
518 KeyStrings map[string]string `protobuf:"6"`
519
520 ValBools map[string]bool `protobuf:"7"`
521 ValInt32s map[string]int32 `protobuf:"8"`
522 ValInt64s map[string]int64 `protobuf:"9"`
523 ValUint32s map[string]uint32 `protobuf:"10"`
524 ValUint64s map[string]uint64 `protobuf:"11"`
525 ValFloat32s map[string]float32 `protobuf:"12"`
526 ValFloat64s map[string]float64 `protobuf:"13"`
527 ValStrings map[string]string `protobuf:"14"`
528 ValStringsA map[string][]byte `protobuf:"15"`
529 ValBytes map[string][]byte `protobuf:"16"`
530 ValBytesA map[string]string `protobuf:"17"`
531
532 MyStrings1 map[MyString]MyString `protobuf:"18"`
533 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
534 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
535 MyBytes2 map[MyString]MyString `protobuf:"21"`
536
537 MyStrings3 MapStrings `protobuf:"22"`
538 MyStrings4 MapBytes `protobuf:"23"`
539 MyBytes3 MapBytes `protobuf:"24"`
540 MyBytes4 MapStrings `protobuf:"25"`
541}
542
Joe Tsaif0c01e42018-11-06 13:05:20 -0800543func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
544 return ptype.Field{
545 Name: pref.Name(fmt.Sprintf("f%d", n)),
546 Number: n,
547 Cardinality: pref.Repeated,
548 Kind: pref.MessageKind,
549 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
550 Syntax: pref.Proto2,
551 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
552 Fields: []ptype.Field{
553 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
554 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
555 },
556 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
557 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000558 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800559}
560
561var mapScalarsType = MessageType{Type: ptype.GoMessage(
562 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000563 Syntax: pref.Proto2,
564 FullName: "MapScalars",
565 Fields: []ptype.Field{
566 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
567 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
568 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
569 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
570 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
571 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
572
573 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
574 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
575 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
576 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
577 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
578 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
579 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
580 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
581 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
582 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
583 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
584
585 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
586 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
587 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
588 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
589
590 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
591 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
592 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
593 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
594 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800595 }),
596 func(pref.MessageType) pref.ProtoMessage {
597 return new(MapScalars)
598 },
599)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000600
Joe Tsaif0c01e42018-11-06 13:05:20 -0800601func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.Type }
602func (m *MapScalars) KnownFields() pref.KnownFields { return mapScalarsType.KnownFieldsOf(m) }
603func (m *MapScalars) UnknownFields() pref.UnknownFields { return mapScalarsType.UnknownFieldsOf(m) }
604func (m *MapScalars) Interface() pref.ProtoMessage { return m }
605func (m *MapScalars) ProtoReflect() pref.Message { return m }
606func (m *MapScalars) ProtoMutable() {}
607
608func TestMapScalars(t *testing.T) {
609 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000610 emptyFS := empty.KnownFields()
611
Joe Tsaif0c01e42018-11-06 13:05:20 -0800612 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000613 KeyBools: map[bool]string{true: "true", false: "false"},
614 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
615 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
616 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
617 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
618 KeyStrings: map[string]string{"": "", "foo": "bar"},
619
620 ValBools: map[string]bool{"true": true, "false": false},
621 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
622 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
623 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
624 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
625 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
626 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
627 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
628 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
629 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
630 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
631
632 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
633 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
634 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
635 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
636
637 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
638 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
639 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
640 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800641 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000642 wantFS := want.KnownFields()
643
Joe Tsaif0c01e42018-11-06 13:05:20 -0800644 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000645 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},
646 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)},
647 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)},
648 mapFields{
649 2: {
650 lenMap(0),
651 hasMap{int32(0): false, int32(-1): false, int32(2): false},
652 setMap{int32(0): V("zero")},
653 lenMap(1),
654 hasMap{int32(0): true, int32(-1): false, int32(2): false},
655 setMap{int32(-1): V("one")},
656 lenMap(2),
657 hasMap{int32(0): true, int32(-1): true, int32(2): false},
658 setMap{int32(2): V("two")},
659 lenMap(3),
660 hasMap{int32(0): true, int32(-1): true, int32(2): true},
661 },
662 4: {
663 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800664 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000665 },
666 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800667 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000668 setMap{"foo": V("bar")},
669 setMap{"": V("empty")},
670 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
671 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800672 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000673 },
674 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800675 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000676 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
677 },
678 10: {
679 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
680 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800681 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000682 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
683 },
684 12: {
685 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800686 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000687 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
688 },
689 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800690 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000691 setMap{"s1": V("s1"), "s2": V("s2")},
692 },
693 16: {
694 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800695 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000696 },
697 18: {
698 hasMap{"s1": false, "s2": false, "s3": false},
699 setMap{"s1": V("s1"), "s2": V("s2")},
700 hasMap{"s1": true, "s2": true, "s3": false},
701 },
702 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800703 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000704 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
705 },
706 22: {
707 rangeMap{},
708 setMap{"s1": V("s1"), "s2": V("s2")},
709 rangeMap{"s1": V("s1"), "s2": V("s2")},
710 lenMap(2),
711 },
712 24: {
713 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800714 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000715 },
716 },
717 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},
Joe Tsai87b955b2018-11-14 21:59:49 -0800718 equalMessage{want},
719 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25},
720 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700721 })
722}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700723
Joe Tsai87b955b2018-11-14 21:59:49 -0800724type OneofScalars struct {
725 Union isOneofScalars_Union `protobuf_oneof:"union"`
726}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700727
Joe Tsaif0c01e42018-11-06 13:05:20 -0800728var oneofScalarsType = MessageType{Type: ptype.GoMessage(
729 mustMakeMessageDesc(ptype.StandaloneMessage{
730 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800731 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800732 Fields: []ptype.Field{
733 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
734 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
735 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
736 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
737 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
738 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
739 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
740 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
741 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
742 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
743 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
744 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
745 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
746 },
747 Oneofs: []ptype.Oneof{{Name: "union"}},
748 }),
749 func(pref.MessageType) pref.ProtoMessage {
750 return new(OneofScalars)
751 },
752)}
753
754func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.Type }
755func (m *OneofScalars) KnownFields() pref.KnownFields { return oneofScalarsType.KnownFieldsOf(m) }
756func (m *OneofScalars) UnknownFields() pref.UnknownFields { return oneofScalarsType.UnknownFieldsOf(m) }
757func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
758func (m *OneofScalars) ProtoReflect() pref.Message { return m }
759func (m *OneofScalars) ProtoMutable() {}
760
761func (*OneofScalars) XXX_OneofFuncs() (func(protoV1.Message, *protoV1.Buffer) error, func(protoV1.Message, int, int, *protoV1.Buffer) (bool, error), func(protoV1.Message) int, []interface{}) {
Joe Tsai2c870bb2018-10-17 11:46:52 -0700762 return nil, nil, nil, []interface{}{
763 (*OneofScalars_Bool)(nil),
764 (*OneofScalars_Int32)(nil),
765 (*OneofScalars_Int64)(nil),
766 (*OneofScalars_Uint32)(nil),
767 (*OneofScalars_Uint64)(nil),
768 (*OneofScalars_Float32)(nil),
769 (*OneofScalars_Float64)(nil),
770 (*OneofScalars_String)(nil),
771 (*OneofScalars_StringA)(nil),
772 (*OneofScalars_StringB)(nil),
773 (*OneofScalars_Bytes)(nil),
774 (*OneofScalars_BytesA)(nil),
775 (*OneofScalars_BytesB)(nil),
776 }
777}
778
Joe Tsai87b955b2018-11-14 21:59:49 -0800779type (
780 isOneofScalars_Union interface {
781 isOneofScalars_Union()
782 }
783 OneofScalars_Bool struct {
784 Bool bool `protobuf:"1"`
785 }
786 OneofScalars_Int32 struct {
787 Int32 MyInt32 `protobuf:"2"`
788 }
789 OneofScalars_Int64 struct {
790 Int64 int64 `protobuf:"3"`
791 }
792 OneofScalars_Uint32 struct {
793 Uint32 MyUint32 `protobuf:"4"`
794 }
795 OneofScalars_Uint64 struct {
796 Uint64 uint64 `protobuf:"5"`
797 }
798 OneofScalars_Float32 struct {
799 Float32 MyFloat32 `protobuf:"6"`
800 }
801 OneofScalars_Float64 struct {
802 Float64 float64 `protobuf:"7"`
803 }
804 OneofScalars_String struct {
805 String string `protobuf:"8"`
806 }
807 OneofScalars_StringA struct {
808 StringA []byte `protobuf:"9"`
809 }
810 OneofScalars_StringB struct {
811 StringB MyString `protobuf:"10"`
812 }
813 OneofScalars_Bytes struct {
814 Bytes []byte `protobuf:"11"`
815 }
816 OneofScalars_BytesA struct {
817 BytesA string `protobuf:"12"`
818 }
819 OneofScalars_BytesB struct {
820 BytesB MyBytes `protobuf:"13"`
821 }
822)
823
Joe Tsai2c870bb2018-10-17 11:46:52 -0700824func (*OneofScalars_Bool) isOneofScalars_Union() {}
825func (*OneofScalars_Int32) isOneofScalars_Union() {}
826func (*OneofScalars_Int64) isOneofScalars_Union() {}
827func (*OneofScalars_Uint32) isOneofScalars_Union() {}
828func (*OneofScalars_Uint64) isOneofScalars_Union() {}
829func (*OneofScalars_Float32) isOneofScalars_Union() {}
830func (*OneofScalars_Float64) isOneofScalars_Union() {}
831func (*OneofScalars_String) isOneofScalars_Union() {}
832func (*OneofScalars_StringA) isOneofScalars_Union() {}
833func (*OneofScalars_StringB) isOneofScalars_Union() {}
834func (*OneofScalars_Bytes) isOneofScalars_Union() {}
835func (*OneofScalars_BytesA) isOneofScalars_Union() {}
836func (*OneofScalars_BytesB) isOneofScalars_Union() {}
837
838func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800839 empty := &OneofScalars{}
840 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
841 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
842 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
843 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
844 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
845 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
846 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
847 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
848 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
849 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
850 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
851 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
852 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700853
Joe Tsaif0c01e42018-11-06 13:05:20 -0800854 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700855 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},
856 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"))},
857
Joe Tsai87b955b2018-11-14 21:59:49 -0800858 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
859 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
860 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
861 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
862 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
863 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
864 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
865 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
866 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
867 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
868 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
869 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
870 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700871
872 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},
873 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"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800874 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
875 equalMessage{want13},
876 clearFields{13},
877 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700878 })
879}
880
Joe Tsai87b955b2018-11-14 21:59:49 -0800881type EnumProto2 int32
882
883var enumProto2Type = ptype.GoEnum(
884 mustMakeEnumDesc(ptype.StandaloneEnum{
885 Syntax: pref.Proto2,
886 FullName: "EnumProto2",
887 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
888 }),
889 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
890 return EnumProto2(n)
891 },
892)
893
894func (e EnumProto2) Enum() *EnumProto2 { return &e }
895func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
896func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
897func (e EnumProto2) ProtoReflect() pref.Enum { return e }
898
899type EnumProto3 int32
900
901var enumProto3Type = ptype.GoEnum(
902 mustMakeEnumDesc(ptype.StandaloneEnum{
903 Syntax: pref.Proto3,
904 FullName: "EnumProto3",
905 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
906 }),
907 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
908 return EnumProto3(n)
909 },
910)
911
912func (e EnumProto3) Enum() *EnumProto3 { return &e }
913func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
914func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
915func (e EnumProto3) ProtoReflect() pref.Enum { return e }
916
917type EnumMessages struct {
918 EnumP2 *EnumProto2 `protobuf:"1"`
919 EnumP3 *EnumProto3 `protobuf:"2"`
920 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
921 MessageCycle *EnumMessages `protobuf:"4"`
922 EnumList []EnumProto2 `protobuf:"5"`
923 MessageList []*ScalarProto2 `protobuf:"6"`
924 EnumMap map[string]EnumProto3 `protobuf:"7"`
925 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
926 Union isEnumMessages_Union `protobuf_oneof:"union"`
927}
928
929var enumMessagesType = MessageType{Type: ptype.GoMessage(
930 mustMakeMessageDesc(ptype.StandaloneMessage{
931 Syntax: pref.Proto2,
932 FullName: "EnumMessages",
933 Fields: []ptype.Field{
934 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type},
935 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type},
936 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: MessageOf(new(proto2_20180125.Message)).Type()},
937 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
938 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type},
939 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.Type},
940 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
941 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
942 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type},
943 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type},
944 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.Type},
945 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.Type},
946 },
947 Oneofs: []ptype.Oneof{{Name: "union"}},
948 }),
949 func(pref.MessageType) pref.ProtoMessage {
950 return new(EnumMessages)
951 },
952)}
953
954var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
955 Syntax: pref.Proto2,
956 FullName: "EnumMessages.F7Entry",
957 Fields: []ptype.Field{
958 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
959 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type},
960 },
961 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
962})
963
964var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
965 Syntax: pref.Proto2,
966 FullName: "EnumMessages.F8Entry",
967 Fields: []ptype.Field{
968 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
969 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.Type},
970 },
971 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
972})
973
974func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.Type }
975func (m *EnumMessages) KnownFields() pref.KnownFields { return enumMessagesType.KnownFieldsOf(m) }
976func (m *EnumMessages) UnknownFields() pref.UnknownFields { return enumMessagesType.UnknownFieldsOf(m) }
977func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
978func (m *EnumMessages) ProtoReflect() pref.Message { return m }
979func (m *EnumMessages) ProtoMutable() {}
980
981func (*EnumMessages) XXX_OneofFuncs() (func(protoV1.Message, *protoV1.Buffer) error, func(protoV1.Message, int, int, *protoV1.Buffer) (bool, error), func(protoV1.Message) int, []interface{}) {
982 return nil, nil, nil, []interface{}{
983 (*EnumMessages_OneofE2)(nil),
984 (*EnumMessages_OneofE3)(nil),
985 (*EnumMessages_OneofM2)(nil),
986 (*EnumMessages_OneofM3)(nil),
987 }
988}
989
990type (
991 isEnumMessages_Union interface {
992 isEnumMessages_Union()
993 }
994 EnumMessages_OneofE2 struct {
995 OneofE2 EnumProto2 `protobuf:"9"`
996 }
997 EnumMessages_OneofE3 struct {
998 OneofE3 EnumProto3 `protobuf:"10"`
999 }
1000 EnumMessages_OneofM2 struct {
1001 OneofM2 *ScalarProto2 `protobuf:"11"`
1002 }
1003 EnumMessages_OneofM3 struct {
1004 OneofM3 *ScalarProto3 `protobuf:"12"`
1005 }
1006)
1007
1008func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1009func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1010func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1011func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1012
1013func TestEnumMessages(t *testing.T) {
1014 // TODO: Test behavior of Get on unpopulated message.
1015 wantL := MessageOf(&proto2_20180125.Message{OptionalFloat: protoV1.Float32(math.E)})
1016 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
1017 wantM2a := &ScalarProto2{Float32: protoV1.Float32(math.Pi)}
1018 wantM2b := &ScalarProto2{Float32: protoV1.Float32(math.Phi)}
1019 wantM3a := &ScalarProto3{Float32: math.Pi}
1020 wantM3b := &ScalarProto3{Float32: math.Ln2}
1021
1022 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1023 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1024
1025 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1026 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1027
1028 testMessage(t, nil, &EnumMessages{}, messageOps{
1029 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},
1030 getFields{1: VE(0xbeef), 2: VE(1), 9: VE(0xbeef), 10: VE(1)},
1031
1032 // Test singular enums.
1033 setFields{1: VE(0xdead), 2: VE(0)},
1034 getFields{1: VE(0xdead), 2: VE(0)},
1035 hasFields{1: true, 2: true},
1036
1037 // Test singular messages.
1038 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1039 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1040 getFields{3: V(wantL), 4: V(wantM)},
1041 clearFields{3, 4},
1042 hasFields{3: false, 4: false},
1043 setFields{3: V(wantL), 4: V(wantM)},
1044 hasFields{3: true, 4: true},
1045
1046 // Test list of enums and messages.
1047 listFields{
1048 5: listOps{
1049 appendList{VE(111), VE(222)},
1050 setList{0: VE(333)},
1051 getList{0: VE(333), 1: VE(222)},
1052 lenList(2),
1053 },
1054 6: listOps{
1055 appendMessageList{setFields{4: V(uint32(1e6))}},
1056 appendMessageList{setFields{6: V(float32(math.Phi))}},
1057 setList{0: V(wantM2a)},
1058 getList{0: V(wantM2a), 1: V(wantM2b)},
1059 },
1060 },
1061 getFields{5: wantList5, 6: wantList6},
1062 hasFields{5: true, 6: true},
1063 listFields{5: listOps{truncList(0)}},
1064 hasFields{5: false, 6: true},
1065
1066 // Test maps of enums and messages.
1067 mapFields{
1068 7: mapOps{
1069 setMap{"one": VE(1), "two": VE(2)},
1070 hasMap{"one": true, "two": true, "three": false},
1071 lenMap(2),
1072 },
1073 8: mapOps{
1074 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1075 setMap{"ln2": V(wantM3b)},
1076 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1077 lenMap(2),
1078 },
1079 },
1080 getFields{7: wantMap7, 8: wantMap8},
1081 hasFields{7: true, 8: true},
1082 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1083 hasFields{7: true, 8: false},
1084
1085 // Test oneofs of enums and messages.
1086 setFields{9: VE(0xdead)},
1087 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1088 setFields{10: VE(0)},
1089 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1090 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1091 getFields{11: V(wantM2a)},
1092 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1093 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1094 getFields{12: V(wantM3a)},
1095 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1096
1097 // Check entire message.
1098 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1099 equalMessage{&EnumMessages{
1100 EnumP2: EnumProto2(0xdead).Enum(),
1101 EnumP3: EnumProto3(0).Enum(),
1102 MessageLegacy: &proto2_20180125.Message{OptionalFloat: protoV1.Float32(math.E)},
1103 MessageCycle: wantM,
1104 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1105 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1106 Union: &EnumMessages_OneofM3{wantM3a},
1107 }},
1108 clearFields{1, 2, 3, 4, 6, 7, 12},
1109 equalMessage{&EnumMessages{}},
1110 })
1111}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001112
Joe Tsai91e14662018-09-13 13:24:35 -07001113var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001114 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1115 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001116 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001117 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1118 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001119 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001120 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
1121 return x.Unwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001122 }),
1123 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001124 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001125}
1126
1127func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1128 fs := m.KnownFields()
1129 for i, op := range tt {
1130 p.Push(i)
1131 switch op := op.(type) {
1132 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001133 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001134 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1135 }
1136 case hasFields:
1137 got := map[pref.FieldNumber]bool{}
1138 want := map[pref.FieldNumber]bool(op)
1139 for n := range want {
1140 got[n] = fs.Has(n)
1141 }
1142 if diff := cmp.Diff(want, got); diff != "" {
1143 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1144 }
1145 case getFields:
1146 got := map[pref.FieldNumber]pref.Value{}
1147 want := map[pref.FieldNumber]pref.Value(op)
1148 for n := range want {
1149 got[n] = fs.Get(n)
1150 }
1151 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1152 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1153 }
1154 case setFields:
1155 for n, v := range op {
1156 fs.Set(n, v)
1157 }
1158 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001159 for _, n := range op {
1160 fs.Clear(n)
1161 }
1162 case messageFields:
1163 for n, tt := range op {
1164 p.Push(int(n))
1165 testMessage(t, p, fs.Mutable(n).(pref.Message), tt)
1166 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001167 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001168 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001169 for n, tt := range op {
1170 p.Push(int(n))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001171 testLists(t, p, fs.Mutable(n).(pref.List), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001172 p.Pop()
1173 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001174 case mapFields:
1175 for n, tt := range op {
1176 p.Push(int(n))
1177 testMaps(t, p, fs.Mutable(n).(pref.Map), tt)
1178 p.Pop()
1179 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001180 case rangeFields:
1181 got := map[pref.FieldNumber]pref.Value{}
1182 want := map[pref.FieldNumber]pref.Value(op)
1183 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1184 got[n] = v
1185 return true
1186 })
1187 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1188 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1189 }
Joe Tsai91e14662018-09-13 13:24:35 -07001190 default:
1191 t.Fatalf("operation %v, invalid operation: %T", p, op)
1192 }
1193 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001194 }
1195}
Joe Tsai91e14662018-09-13 13:24:35 -07001196
Joe Tsai4b7aff62018-11-14 14:05:19 -08001197func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001198 for i, op := range tt {
1199 p.Push(i)
1200 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001201 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001202 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001203 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001204 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001205 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001206 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001207 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001208 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001209 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001210 got := map[int]pref.Value{}
1211 want := map[int]pref.Value(op)
1212 for n := range want {
1213 got[n] = v.Get(n)
1214 }
1215 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001216 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001217 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001218 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001219 for n, e := range op {
1220 v.Set(n, e)
1221 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001222 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001223 for _, e := range op {
1224 v.Append(e)
1225 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001226 case appendMessageList:
1227 testMessage(t, p, v.MutableAppend().(pref.Message), messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001228 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001229 v.Truncate(int(op))
1230 default:
1231 t.Fatalf("operation %v, invalid operation: %T", p, op)
1232 }
1233 p.Pop()
1234 }
1235}
1236
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001237func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1238 for i, op := range tt {
1239 p.Push(i)
1240 switch op := op.(type) {
1241 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001242 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001243 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1244 }
1245 case lenMap:
1246 if got, want := m.Len(), int(op); got != want {
1247 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1248 }
1249 case hasMap:
1250 got := map[interface{}]bool{}
1251 want := map[interface{}]bool(op)
1252 for k := range want {
1253 got[k] = m.Has(V(k).MapKey())
1254 }
1255 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1256 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1257 }
1258 case getMap:
1259 got := map[interface{}]pref.Value{}
1260 want := map[interface{}]pref.Value(op)
1261 for k := range want {
1262 got[k] = m.Get(V(k).MapKey())
1263 }
1264 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1265 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1266 }
1267 case setMap:
1268 for k, v := range op {
1269 m.Set(V(k).MapKey(), v)
1270 }
1271 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001272 for _, k := range op {
1273 m.Clear(V(k).MapKey())
1274 }
1275 case messageMap:
1276 for k, tt := range op {
1277 testMessage(t, p, m.Mutable(V(k).MapKey()).(pref.Message), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001278 }
1279 case rangeMap:
1280 got := map[interface{}]pref.Value{}
1281 want := map[interface{}]pref.Value(op)
1282 m.Range(func(k pref.MapKey, v pref.Value) bool {
1283 got[k.Interface()] = v
1284 return true
1285 })
1286 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1287 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1288 }
1289 default:
1290 t.Fatalf("operation %v, invalid operation: %T", p, op)
1291 }
1292 p.Pop()
1293 }
1294}
1295
Joe Tsai91e14662018-09-13 13:24:35 -07001296type path []int
1297
1298func (p *path) Push(i int) { *p = append(*p, i) }
1299func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1300func (p path) String() string {
1301 var ss []string
1302 for _, i := range p {
1303 ss = append(ss, fmt.Sprint(i))
1304 }
1305 return strings.Join(ss, ".")
1306}