blob: 97fbabdae729e873cd535644cdeb4062974795e5 [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
Joe Tsai08e00302018-11-26 22:32:06 -08005package impl_test
Joe Tsaifa02f4e2018-09-12 16:20:37 -07006
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"
Joe Tsai08e00302018-11-26 22:32:06 -080014 pimpl "github.com/golang/protobuf/v2/internal/impl"
Joe Tsai009e0672018-11-27 18:45:07 -080015 scalar "github.com/golang/protobuf/v2/internal/scalar"
Joe Tsai08e00302018-11-26 22:32:06 -080016 pvalue "github.com/golang/protobuf/v2/internal/value"
Joe Tsai01ab2962018-09-21 17:44:00 -070017 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
18 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsai87b955b2018-11-14 21:59:49 -080019 cmp "github.com/google/go-cmp/cmp"
20 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070021
Joe Tsai08e00302018-11-26 22:32:06 -080022 // The legacy package must be imported prior to use of any legacy messages.
23 // TODO: Remove this when protoV1 registers these hooks for you.
24 _ "github.com/golang/protobuf/v2/internal/legacy"
25
Joe Tsai87b955b2018-11-14 21:59:49 -080026 proto2_20180125 "github.com/golang/protobuf/v2/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
Joe Tsaie1f8d502018-11-26 18:55:29 -080027 descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070028)
29
Joe Tsai4b7aff62018-11-14 14:05:19 -080030// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070031type (
Joe Tsai87b955b2018-11-14 21:59:49 -080032 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070033 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070034
Joe Tsai87b955b2018-11-14 21:59:49 -080035 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080036 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070037
Joe Tsai87b955b2018-11-14 21:59:49 -080038 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000039 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070040)
41
42// Test operations performed on a message.
43type (
Joe Tsai87b955b2018-11-14 21:59:49 -080044 // check that the message contents match
45 equalMessage struct{ pref.Message }
46 // check presence for specific fields in the message
47 hasFields map[pref.FieldNumber]bool
48 // check that specific message fields match
49 getFields map[pref.FieldNumber]pref.Value
50 // set specific message fields
51 setFields map[pref.FieldNumber]pref.Value
52 // clear specific fields in the message
53 clearFields []pref.FieldNumber
54 // apply messageOps on each specified message field
Joe Tsai91e14662018-09-13 13:24:35 -070055 messageFields map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080056 // apply listOps on each specified list field
57 listFields map[pref.FieldNumber]listOps
58 // apply mapOps on each specified map fields
59 mapFields map[pref.FieldNumber]mapOps
60 // range through all fields and check that they match
61 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070062)
63
Joe Tsai87b955b2018-11-14 21:59:49 -080064func (equalMessage) isMessageOp() {}
65func (hasFields) isMessageOp() {}
66func (getFields) isMessageOp() {}
67func (setFields) isMessageOp() {}
68func (clearFields) isMessageOp() {}
69func (messageFields) isMessageOp() {}
70func (listFields) isMessageOp() {}
71func (mapFields) isMessageOp() {}
72func (rangeFields) isMessageOp() {}
73
Joe Tsai4b7aff62018-11-14 14:05:19 -080074// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070075type (
Joe Tsai87b955b2018-11-14 21:59:49 -080076 // check that the list contents match
77 equalList struct{ pref.List }
78 // check that list length matches
79 lenList int
80 // check that specific list entries match
81 getList map[int]pref.Value
82 // set specific list entries
83 setList map[int]pref.Value
84 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080085 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080086 // apply messageOps on a newly appended message
87 appendMessageList messageOps
88 // truncate the list to the specified length
89 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -070090)
91
Joe Tsai87b955b2018-11-14 21:59:49 -080092func (equalList) isListOp() {}
93func (lenList) isListOp() {}
94func (getList) isListOp() {}
95func (setList) isListOp() {}
96func (appendList) isListOp() {}
97func (appendMessageList) isListOp() {}
98func (truncList) isListOp() {}
99
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000100// Test operations performed on a map.
101type (
Joe Tsai87b955b2018-11-14 21:59:49 -0800102 // check that the map contents match
103 equalMap struct{ pref.Map }
104 // check that map length matches
105 lenMap int
106 // check presence for specific entries in the map
107 hasMap map[interface{}]bool
108 // check that specific map entries match
109 getMap map[interface{}]pref.Value
110 // set specific map entries
111 setMap map[interface{}]pref.Value
112 // clear specific entries in the map
113 clearMap []interface{}
114 // apply messageOps on each specified message entry
115 messageMap map[interface{}]messageOps
116 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000117 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000118)
119
Joe Tsai87b955b2018-11-14 21:59:49 -0800120func (equalMap) isMapOp() {}
121func (lenMap) isMapOp() {}
122func (hasMap) isMapOp() {}
123func (getMap) isMapOp() {}
124func (setMap) isMapOp() {}
125func (clearMap) isMapOp() {}
126func (messageMap) isMapOp() {}
127func (rangeMap) isMapOp() {}
128
Joe Tsaice6edd32018-10-19 16:27:46 -0700129type ScalarProto2 struct {
130 Bool *bool `protobuf:"1"`
131 Int32 *int32 `protobuf:"2"`
132 Int64 *int64 `protobuf:"3"`
133 Uint32 *uint32 `protobuf:"4"`
134 Uint64 *uint64 `protobuf:"5"`
135 Float32 *float32 `protobuf:"6"`
136 Float64 *float64 `protobuf:"7"`
137 String *string `protobuf:"8"`
138 StringA []byte `protobuf:"9"`
139 Bytes []byte `protobuf:"10"`
140 BytesA *string `protobuf:"11"`
141
142 MyBool *MyBool `protobuf:"12"`
143 MyInt32 *MyInt32 `protobuf:"13"`
144 MyInt64 *MyInt64 `protobuf:"14"`
145 MyUint32 *MyUint32 `protobuf:"15"`
146 MyUint64 *MyUint64 `protobuf:"16"`
147 MyFloat32 *MyFloat32 `protobuf:"17"`
148 MyFloat64 *MyFloat64 `protobuf:"18"`
149 MyString *MyString `protobuf:"19"`
150 MyStringA MyBytes `protobuf:"20"`
151 MyBytes MyBytes `protobuf:"21"`
152 MyBytesA *MyString `protobuf:"22"`
153}
154
Joe Tsai87b955b2018-11-14 21:59:49 -0800155func mustMakeEnumDesc(t ptype.StandaloneEnum) pref.EnumDescriptor {
156 ed, err := ptype.NewEnum(&t)
157 if err != nil {
158 panic(err)
159 }
160 return ed
161}
162
163func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
164 md, err := ptype.NewMessage(&t)
165 if err != nil {
166 panic(err)
167 }
168 return md
169}
170
171var V = pref.ValueOf
172var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
173
174type (
175 MyBool bool
176 MyInt32 int32
177 MyInt64 int64
178 MyUint32 uint32
179 MyUint64 uint64
180 MyFloat32 float32
181 MyFloat64 float64
182 MyString string
183 MyBytes []byte
184
185 ListStrings []MyString
186 ListBytes []MyBytes
187
188 MapStrings map[MyString]MyString
189 MapBytes map[MyString]MyBytes
190)
191
Joe Tsai08e00302018-11-26 22:32:06 -0800192var scalarProto2Type = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800193 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700194 Syntax: pref.Proto2,
195 FullName: "ScalarProto2",
196 Fields: []ptype.Field{
197 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
198 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
199 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
200 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
201 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
202 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
203 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
204 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
205 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
206 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
207 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
208
209 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
210 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
211 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
212 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
213 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
214 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
215 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
216 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
217 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
218 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
219 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
220 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800221 }),
222 func(pref.MessageType) pref.ProtoMessage {
223 return new(ScalarProto2)
224 },
225)}
Joe Tsai91e14662018-09-13 13:24:35 -0700226
Joe Tsaif0c01e42018-11-06 13:05:20 -0800227func (m *ScalarProto2) Type() pref.MessageType { return scalarProto2Type.Type }
228func (m *ScalarProto2) KnownFields() pref.KnownFields { return scalarProto2Type.KnownFieldsOf(m) }
229func (m *ScalarProto2) UnknownFields() pref.UnknownFields { return scalarProto2Type.UnknownFieldsOf(m) }
230func (m *ScalarProto2) Interface() pref.ProtoMessage { return m }
231func (m *ScalarProto2) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800232
233func TestScalarProto2(t *testing.T) {
234 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700235 hasFields{
236 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
237 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
238 },
239 getFields{
240 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")),
241 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")),
242 },
243 setFields{
244 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)),
245 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)),
246 },
247 hasFields{
248 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
249 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
250 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800251 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700252 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
253 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 -0800254 }},
255 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
256 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700257 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800258
259 // Test read-only operations on nil message.
260 testMessage(t, nil, (*ScalarProto2)(nil), messageOps{
261 hasFields{
262 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
263 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
264 },
265 getFields{
266 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")),
267 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")),
268 },
269 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700270}
271
Joe Tsaice6edd32018-10-19 16:27:46 -0700272type ScalarProto3 struct {
273 Bool bool `protobuf:"1"`
274 Int32 int32 `protobuf:"2"`
275 Int64 int64 `protobuf:"3"`
276 Uint32 uint32 `protobuf:"4"`
277 Uint64 uint64 `protobuf:"5"`
278 Float32 float32 `protobuf:"6"`
279 Float64 float64 `protobuf:"7"`
280 String string `protobuf:"8"`
281 StringA []byte `protobuf:"9"`
282 Bytes []byte `protobuf:"10"`
283 BytesA string `protobuf:"11"`
284
285 MyBool MyBool `protobuf:"12"`
286 MyInt32 MyInt32 `protobuf:"13"`
287 MyInt64 MyInt64 `protobuf:"14"`
288 MyUint32 MyUint32 `protobuf:"15"`
289 MyUint64 MyUint64 `protobuf:"16"`
290 MyFloat32 MyFloat32 `protobuf:"17"`
291 MyFloat64 MyFloat64 `protobuf:"18"`
292 MyString MyString `protobuf:"19"`
293 MyStringA MyBytes `protobuf:"20"`
294 MyBytes MyBytes `protobuf:"21"`
295 MyBytesA MyString `protobuf:"22"`
296}
297
Joe Tsai08e00302018-11-26 22:32:06 -0800298var scalarProto3Type = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800299 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700300 Syntax: pref.Proto3,
301 FullName: "ScalarProto3",
302 Fields: []ptype.Field{
303 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
304 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
305 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
306 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
307 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
308 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
309 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
310 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
311 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
312 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
313 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700314
Joe Tsai91e14662018-09-13 13:24:35 -0700315 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
316 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
317 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
318 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
319 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
320 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
321 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
322 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
323 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
324 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
325 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
326 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800327 }),
328 func(pref.MessageType) pref.ProtoMessage {
329 return new(ScalarProto3)
330 },
331)}
Joe Tsai91e14662018-09-13 13:24:35 -0700332
Joe Tsaif0c01e42018-11-06 13:05:20 -0800333func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.Type }
334func (m *ScalarProto3) KnownFields() pref.KnownFields { return scalarProto3Type.KnownFieldsOf(m) }
335func (m *ScalarProto3) UnknownFields() pref.UnknownFields { return scalarProto3Type.UnknownFieldsOf(m) }
336func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
337func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800338
339func TestScalarProto3(t *testing.T) {
340 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700341 hasFields{
342 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
343 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
344 },
345 getFields{
346 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)),
347 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)),
348 },
349 setFields{
350 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)),
351 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)),
352 },
353 hasFields{
354 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
355 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
356 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800357 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700358 setFields{
359 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")),
360 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")),
361 },
362 hasFields{
363 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
364 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
365 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800366 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700367 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
368 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800369 }},
Joe Tsai44e389c2018-11-19 15:27:09 -0800370 setFields{
371 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
372 },
373 hasFields{
374 2: true, 3: true, 6: true, 7: true,
375 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800376 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
377 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700378 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800379
380 // Test read-only operations on nil message.
381 testMessage(t, nil, (*ScalarProto3)(nil), messageOps{
382 hasFields{
383 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
384 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
385 },
386 getFields{
387 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)),
388 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)),
389 },
390 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700391}
392
Joe Tsaif0c01e42018-11-06 13:05:20 -0800393type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700394 Bools []bool `protobuf:"1"`
395 Int32s []int32 `protobuf:"2"`
396 Int64s []int64 `protobuf:"3"`
397 Uint32s []uint32 `protobuf:"4"`
398 Uint64s []uint64 `protobuf:"5"`
399 Float32s []float32 `protobuf:"6"`
400 Float64s []float64 `protobuf:"7"`
401 Strings []string `protobuf:"8"`
402 StringsA [][]byte `protobuf:"9"`
403 Bytes [][]byte `protobuf:"10"`
404 BytesA []string `protobuf:"11"`
405
406 MyStrings1 []MyString `protobuf:"12"`
407 MyStrings2 []MyBytes `protobuf:"13"`
408 MyBytes1 []MyBytes `protobuf:"14"`
409 MyBytes2 []MyString `protobuf:"15"`
410
Joe Tsai4b7aff62018-11-14 14:05:19 -0800411 MyStrings3 ListStrings `protobuf:"16"`
412 MyStrings4 ListBytes `protobuf:"17"`
413 MyBytes3 ListBytes `protobuf:"18"`
414 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700415}
416
Joe Tsai08e00302018-11-26 22:32:06 -0800417var listScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800418 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700419 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800420 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700421 Fields: []ptype.Field{
422 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
423 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
424 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
425 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
426 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
427 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
428 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
429 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
430 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
431 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
432 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700433
Joe Tsai91e14662018-09-13 13:24:35 -0700434 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
435 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
436 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
437 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
438
439 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
440 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
441 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
442 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700443 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800444 }),
445 func(pref.MessageType) pref.ProtoMessage {
446 return new(ListScalars)
447 },
448)}
Joe Tsai91e14662018-09-13 13:24:35 -0700449
Joe Tsaif0c01e42018-11-06 13:05:20 -0800450func (m *ListScalars) Type() pref.MessageType { return listScalarsType.Type }
451func (m *ListScalars) KnownFields() pref.KnownFields { return listScalarsType.KnownFieldsOf(m) }
452func (m *ListScalars) UnknownFields() pref.UnknownFields { return listScalarsType.UnknownFieldsOf(m) }
453func (m *ListScalars) Interface() pref.ProtoMessage { return m }
454func (m *ListScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800455
456func TestListScalars(t *testing.T) {
457 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700458 emptyFS := empty.KnownFields()
459
Joe Tsaif0c01e42018-11-06 13:05:20 -0800460 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700461 Bools: []bool{true, false, true},
462 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
463 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
464 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
465 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
466 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
467 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
468 Strings: []string{"8", "", "eight"},
469 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
470 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
471 BytesA: []string{"11", "", "eleven"},
472
473 MyStrings1: []MyString{"12", "", "twelve"},
474 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
475 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
476 MyBytes2: []MyString{"15", "", "fifteen"},
477
Joe Tsai4b7aff62018-11-14 14:05:19 -0800478 MyStrings3: ListStrings{"16", "", "sixteen"},
479 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
480 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
481 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800482 }
Joe Tsai91e14662018-09-13 13:24:35 -0700483 wantFS := want.KnownFields()
484
Joe Tsaif0c01e42018-11-06 13:05:20 -0800485 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700486 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},
487 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)},
488 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 -0800489 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700490 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800491 lenList(0),
492 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
493 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800494 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700495 },
496 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800497 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
498 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
499 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700500 },
501 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800502 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800503 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700504 },
505 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800506 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
507 lenList(6),
508 setList{0: V("8"), 2: V("eight")},
509 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800510 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700511 },
512 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800513 appendList{V([]byte(nil)), V([]byte(nil))},
514 setList{0: V([]byte("10"))},
515 appendList{V([]byte("wrong"))},
516 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800517 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700518 },
519 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800520 appendList{V("12"), V("wrong"), V("twelve")},
521 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800522 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700523 },
524 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800525 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800526 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700527 },
528 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800529 appendList{V("16"), V(""), V("sixteen"), V("extra")},
530 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800531 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700532 },
533 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800534 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800535 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700536 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700537 },
Joe Tsai91e14662018-09-13 13:24:35 -0700538 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 -0800539 equalMessage{want},
540 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
541 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000542 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800543
544 // Test read-only operations on nil message.
545 testMessage(t, nil, (*ListScalars)(nil), messageOps{
546 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},
547 listFields{2: {lenList(0)}, 4: {lenList(0)}, 6: {lenList(0)}, 8: {lenList(0)}, 10: {lenList(0)}, 12: {lenList(0)}, 14: {lenList(0)}, 16: {lenList(0)}, 18: {lenList(0)}},
548 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000549}
550
Joe Tsaice6edd32018-10-19 16:27:46 -0700551type MapScalars struct {
552 KeyBools map[bool]string `protobuf:"1"`
553 KeyInt32s map[int32]string `protobuf:"2"`
554 KeyInt64s map[int64]string `protobuf:"3"`
555 KeyUint32s map[uint32]string `protobuf:"4"`
556 KeyUint64s map[uint64]string `protobuf:"5"`
557 KeyStrings map[string]string `protobuf:"6"`
558
559 ValBools map[string]bool `protobuf:"7"`
560 ValInt32s map[string]int32 `protobuf:"8"`
561 ValInt64s map[string]int64 `protobuf:"9"`
562 ValUint32s map[string]uint32 `protobuf:"10"`
563 ValUint64s map[string]uint64 `protobuf:"11"`
564 ValFloat32s map[string]float32 `protobuf:"12"`
565 ValFloat64s map[string]float64 `protobuf:"13"`
566 ValStrings map[string]string `protobuf:"14"`
567 ValStringsA map[string][]byte `protobuf:"15"`
568 ValBytes map[string][]byte `protobuf:"16"`
569 ValBytesA map[string]string `protobuf:"17"`
570
571 MyStrings1 map[MyString]MyString `protobuf:"18"`
572 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
573 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
574 MyBytes2 map[MyString]MyString `protobuf:"21"`
575
576 MyStrings3 MapStrings `protobuf:"22"`
577 MyStrings4 MapBytes `protobuf:"23"`
578 MyBytes3 MapBytes `protobuf:"24"`
579 MyBytes4 MapStrings `protobuf:"25"`
580}
581
Joe Tsaif0c01e42018-11-06 13:05:20 -0800582func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
583 return ptype.Field{
584 Name: pref.Name(fmt.Sprintf("f%d", n)),
585 Number: n,
586 Cardinality: pref.Repeated,
587 Kind: pref.MessageKind,
588 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
589 Syntax: pref.Proto2,
590 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
591 Fields: []ptype.Field{
592 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
593 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
594 },
Damien Neil232ea152018-12-10 15:14:36 -0800595 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
596 IsMapEntry: true,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800597 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000598 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800599}
600
Joe Tsai08e00302018-11-26 22:32:06 -0800601var mapScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800602 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000603 Syntax: pref.Proto2,
604 FullName: "MapScalars",
605 Fields: []ptype.Field{
606 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
607 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
608 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
609 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
610 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
611 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
612
613 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
614 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
615 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
616 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
617 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
618 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
619 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
620 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
621 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
622 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
623 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
624
625 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
626 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
627 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
628 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
629
630 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
631 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
632 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
633 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
634 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800635 }),
636 func(pref.MessageType) pref.ProtoMessage {
637 return new(MapScalars)
638 },
639)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000640
Joe Tsaif0c01e42018-11-06 13:05:20 -0800641func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.Type }
642func (m *MapScalars) KnownFields() pref.KnownFields { return mapScalarsType.KnownFieldsOf(m) }
643func (m *MapScalars) UnknownFields() pref.UnknownFields { return mapScalarsType.UnknownFieldsOf(m) }
644func (m *MapScalars) Interface() pref.ProtoMessage { return m }
645func (m *MapScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800646
647func TestMapScalars(t *testing.T) {
648 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000649 emptyFS := empty.KnownFields()
650
Joe Tsaif0c01e42018-11-06 13:05:20 -0800651 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000652 KeyBools: map[bool]string{true: "true", false: "false"},
653 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
654 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
655 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
656 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
657 KeyStrings: map[string]string{"": "", "foo": "bar"},
658
659 ValBools: map[string]bool{"true": true, "false": false},
660 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
661 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
662 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
663 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
664 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
665 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
666 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
667 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
668 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
669 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
670
671 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
672 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
673 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
674 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
675
676 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
677 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
678 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
679 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800680 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000681 wantFS := want.KnownFields()
682
Joe Tsaif0c01e42018-11-06 13:05:20 -0800683 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000684 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},
685 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)},
686 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)},
687 mapFields{
688 2: {
689 lenMap(0),
690 hasMap{int32(0): false, int32(-1): false, int32(2): false},
691 setMap{int32(0): V("zero")},
692 lenMap(1),
693 hasMap{int32(0): true, int32(-1): false, int32(2): false},
694 setMap{int32(-1): V("one")},
695 lenMap(2),
696 hasMap{int32(0): true, int32(-1): true, int32(2): false},
697 setMap{int32(2): V("two")},
698 lenMap(3),
699 hasMap{int32(0): true, int32(-1): true, int32(2): true},
700 },
701 4: {
702 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800703 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000704 },
705 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800706 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000707 setMap{"foo": V("bar")},
708 setMap{"": V("empty")},
709 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
710 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800711 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000712 },
713 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800714 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000715 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
716 },
717 10: {
718 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
719 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800720 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000721 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
722 },
723 12: {
724 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800725 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000726 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
727 },
728 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800729 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000730 setMap{"s1": V("s1"), "s2": V("s2")},
731 },
732 16: {
733 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800734 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000735 },
736 18: {
737 hasMap{"s1": false, "s2": false, "s3": false},
738 setMap{"s1": V("s1"), "s2": V("s2")},
739 hasMap{"s1": true, "s2": true, "s3": false},
740 },
741 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800742 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000743 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
744 },
745 22: {
746 rangeMap{},
747 setMap{"s1": V("s1"), "s2": V("s2")},
748 rangeMap{"s1": V("s1"), "s2": V("s2")},
749 lenMap(2),
750 },
751 24: {
752 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800753 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000754 },
755 },
756 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 -0800757 equalMessage{want},
758 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},
759 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700760 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800761
762 // Test read-only operations on nil message.
763 testMessage(t, nil, (*MapScalars)(nil), messageOps{
764 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},
765 mapFields{2: {lenMap(0)}, 4: {lenMap(0)}, 6: {lenMap(0)}, 8: {lenMap(0)}, 10: {lenMap(0)}, 12: {lenMap(0)}, 14: {lenMap(0)}, 16: {lenMap(0)}, 18: {lenMap(0)}, 20: {lenMap(0)}, 22: {lenMap(0)}, 24: {lenMap(0)}},
766 })
Joe Tsai91e14662018-09-13 13:24:35 -0700767}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700768
Joe Tsai87b955b2018-11-14 21:59:49 -0800769type OneofScalars struct {
770 Union isOneofScalars_Union `protobuf_oneof:"union"`
771}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700772
Joe Tsai08e00302018-11-26 22:32:06 -0800773var oneofScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800774 mustMakeMessageDesc(ptype.StandaloneMessage{
775 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800776 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800777 Fields: []ptype.Field{
778 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
779 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
780 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
781 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
782 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
783 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
784 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
785 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
786 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
787 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
788 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
789 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
790 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
791 },
792 Oneofs: []ptype.Oneof{{Name: "union"}},
793 }),
794 func(pref.MessageType) pref.ProtoMessage {
795 return new(OneofScalars)
796 },
797)}
798
799func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.Type }
800func (m *OneofScalars) KnownFields() pref.KnownFields { return oneofScalarsType.KnownFieldsOf(m) }
801func (m *OneofScalars) UnknownFields() pref.UnknownFields { return oneofScalarsType.UnknownFieldsOf(m) }
802func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
803func (m *OneofScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800804
Joe Tsaif18ab532018-11-27 17:25:04 -0800805func (*OneofScalars) XXX_OneofWrappers() []interface{} {
806 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700807 (*OneofScalars_Bool)(nil),
808 (*OneofScalars_Int32)(nil),
809 (*OneofScalars_Int64)(nil),
810 (*OneofScalars_Uint32)(nil),
811 (*OneofScalars_Uint64)(nil),
812 (*OneofScalars_Float32)(nil),
813 (*OneofScalars_Float64)(nil),
814 (*OneofScalars_String)(nil),
815 (*OneofScalars_StringA)(nil),
816 (*OneofScalars_StringB)(nil),
817 (*OneofScalars_Bytes)(nil),
818 (*OneofScalars_BytesA)(nil),
819 (*OneofScalars_BytesB)(nil),
820 }
821}
822
Joe Tsai87b955b2018-11-14 21:59:49 -0800823type (
824 isOneofScalars_Union interface {
825 isOneofScalars_Union()
826 }
827 OneofScalars_Bool struct {
828 Bool bool `protobuf:"1"`
829 }
830 OneofScalars_Int32 struct {
831 Int32 MyInt32 `protobuf:"2"`
832 }
833 OneofScalars_Int64 struct {
834 Int64 int64 `protobuf:"3"`
835 }
836 OneofScalars_Uint32 struct {
837 Uint32 MyUint32 `protobuf:"4"`
838 }
839 OneofScalars_Uint64 struct {
840 Uint64 uint64 `protobuf:"5"`
841 }
842 OneofScalars_Float32 struct {
843 Float32 MyFloat32 `protobuf:"6"`
844 }
845 OneofScalars_Float64 struct {
846 Float64 float64 `protobuf:"7"`
847 }
848 OneofScalars_String struct {
849 String string `protobuf:"8"`
850 }
851 OneofScalars_StringA struct {
852 StringA []byte `protobuf:"9"`
853 }
854 OneofScalars_StringB struct {
855 StringB MyString `protobuf:"10"`
856 }
857 OneofScalars_Bytes struct {
858 Bytes []byte `protobuf:"11"`
859 }
860 OneofScalars_BytesA struct {
861 BytesA string `protobuf:"12"`
862 }
863 OneofScalars_BytesB struct {
864 BytesB MyBytes `protobuf:"13"`
865 }
866)
867
Joe Tsai2c870bb2018-10-17 11:46:52 -0700868func (*OneofScalars_Bool) isOneofScalars_Union() {}
869func (*OneofScalars_Int32) isOneofScalars_Union() {}
870func (*OneofScalars_Int64) isOneofScalars_Union() {}
871func (*OneofScalars_Uint32) isOneofScalars_Union() {}
872func (*OneofScalars_Uint64) isOneofScalars_Union() {}
873func (*OneofScalars_Float32) isOneofScalars_Union() {}
874func (*OneofScalars_Float64) isOneofScalars_Union() {}
875func (*OneofScalars_String) isOneofScalars_Union() {}
876func (*OneofScalars_StringA) isOneofScalars_Union() {}
877func (*OneofScalars_StringB) isOneofScalars_Union() {}
878func (*OneofScalars_Bytes) isOneofScalars_Union() {}
879func (*OneofScalars_BytesA) isOneofScalars_Union() {}
880func (*OneofScalars_BytesB) isOneofScalars_Union() {}
881
882func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800883 empty := &OneofScalars{}
884 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
885 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
886 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
887 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
888 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
889 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
890 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
891 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
892 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
893 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
894 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
895 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
896 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700897
Joe Tsaif0c01e42018-11-06 13:05:20 -0800898 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700899 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},
900 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"))},
901
Joe Tsai87b955b2018-11-14 21:59:49 -0800902 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
903 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
904 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
905 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
906 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
907 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
908 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
909 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
910 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
911 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
912 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
913 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
914 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700915
916 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},
917 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 -0800918 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
919 equalMessage{want13},
920 clearFields{13},
921 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700922 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800923
924 // Test read-only operations on nil message.
925 testMessage(t, nil, (*OneofScalars)(nil), messageOps{
926 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},
927 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"))},
928 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700929}
930
Joe Tsai87b955b2018-11-14 21:59:49 -0800931type EnumProto2 int32
932
933var enumProto2Type = ptype.GoEnum(
934 mustMakeEnumDesc(ptype.StandaloneEnum{
935 Syntax: pref.Proto2,
936 FullName: "EnumProto2",
937 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
938 }),
939 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
940 return EnumProto2(n)
941 },
942)
943
944func (e EnumProto2) Enum() *EnumProto2 { return &e }
945func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
946func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
947func (e EnumProto2) ProtoReflect() pref.Enum { return e }
948
949type EnumProto3 int32
950
951var enumProto3Type = ptype.GoEnum(
952 mustMakeEnumDesc(ptype.StandaloneEnum{
953 Syntax: pref.Proto3,
954 FullName: "EnumProto3",
955 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
956 }),
957 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
958 return EnumProto3(n)
959 },
960)
961
962func (e EnumProto3) Enum() *EnumProto3 { return &e }
963func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
964func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
965func (e EnumProto3) ProtoReflect() pref.Enum { return e }
966
967type EnumMessages struct {
968 EnumP2 *EnumProto2 `protobuf:"1"`
969 EnumP3 *EnumProto3 `protobuf:"2"`
970 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
971 MessageCycle *EnumMessages `protobuf:"4"`
972 EnumList []EnumProto2 `protobuf:"5"`
973 MessageList []*ScalarProto2 `protobuf:"6"`
974 EnumMap map[string]EnumProto3 `protobuf:"7"`
975 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
976 Union isEnumMessages_Union `protobuf_oneof:"union"`
977}
978
Joe Tsai08e00302018-11-26 22:32:06 -0800979var enumMessagesType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsai87b955b2018-11-14 21:59:49 -0800980 mustMakeMessageDesc(ptype.StandaloneMessage{
981 Syntax: pref.Proto2,
982 FullName: "EnumMessages",
983 Fields: []ptype.Field{
984 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type},
985 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type},
Joe Tsai08e00302018-11-26 22:32:06 -0800986 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: pimpl.Export{}.MessageOf(new(proto2_20180125.Message)).Type()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800987 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
988 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type},
989 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.Type},
990 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
991 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
992 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type},
993 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type},
994 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.Type},
995 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.Type},
996 },
997 Oneofs: []ptype.Oneof{{Name: "union"}},
998 }),
999 func(pref.MessageType) pref.ProtoMessage {
1000 return new(EnumMessages)
1001 },
1002)}
1003
1004var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1005 Syntax: pref.Proto2,
1006 FullName: "EnumMessages.F7Entry",
1007 Fields: []ptype.Field{
1008 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1009 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type},
1010 },
Damien Neil232ea152018-12-10 15:14:36 -08001011 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
1012 IsMapEntry: true,
Joe Tsai87b955b2018-11-14 21:59:49 -08001013})
1014
1015var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1016 Syntax: pref.Proto2,
1017 FullName: "EnumMessages.F8Entry",
1018 Fields: []ptype.Field{
1019 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1020 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.Type},
1021 },
Damien Neil232ea152018-12-10 15:14:36 -08001022 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
1023 IsMapEntry: true,
Joe Tsai87b955b2018-11-14 21:59:49 -08001024})
1025
1026func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.Type }
1027func (m *EnumMessages) KnownFields() pref.KnownFields { return enumMessagesType.KnownFieldsOf(m) }
1028func (m *EnumMessages) UnknownFields() pref.UnknownFields { return enumMessagesType.UnknownFieldsOf(m) }
1029func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
1030func (m *EnumMessages) ProtoReflect() pref.Message { return m }
Joe Tsai87b955b2018-11-14 21:59:49 -08001031
Joe Tsaif18ab532018-11-27 17:25:04 -08001032func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1033 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001034 (*EnumMessages_OneofE2)(nil),
1035 (*EnumMessages_OneofE3)(nil),
1036 (*EnumMessages_OneofM2)(nil),
1037 (*EnumMessages_OneofM3)(nil),
1038 }
1039}
1040
1041type (
1042 isEnumMessages_Union interface {
1043 isEnumMessages_Union()
1044 }
1045 EnumMessages_OneofE2 struct {
1046 OneofE2 EnumProto2 `protobuf:"9"`
1047 }
1048 EnumMessages_OneofE3 struct {
1049 OneofE3 EnumProto3 `protobuf:"10"`
1050 }
1051 EnumMessages_OneofM2 struct {
1052 OneofM2 *ScalarProto2 `protobuf:"11"`
1053 }
1054 EnumMessages_OneofM3 struct {
1055 OneofM3 *ScalarProto3 `protobuf:"12"`
1056 }
1057)
1058
1059func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1060func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1061func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1062func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1063
1064func TestEnumMessages(t *testing.T) {
Joe Tsai08e00302018-11-26 22:32:06 -08001065 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)})
Joe Tsai87b955b2018-11-14 21:59:49 -08001066 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
Joe Tsai009e0672018-11-27 18:45:07 -08001067 wantM2a := &ScalarProto2{Float32: scalar.Float32(math.Pi)}
1068 wantM2b := &ScalarProto2{Float32: scalar.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001069 wantM3a := &ScalarProto3{Float32: math.Pi}
1070 wantM3b := &ScalarProto3{Float32: math.Ln2}
1071
1072 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1073 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1074
1075 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1076 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1077
1078 testMessage(t, nil, &EnumMessages{}, messageOps{
1079 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},
Joe Tsaif6d4a422018-11-19 14:26:06 -08001080 getFields{1: VE(0xbeef), 2: VE(1), 3: V(nil), 4: V(nil), 9: VE(0xbeef), 10: VE(1)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001081
1082 // Test singular enums.
1083 setFields{1: VE(0xdead), 2: VE(0)},
1084 getFields{1: VE(0xdead), 2: VE(0)},
1085 hasFields{1: true, 2: true},
1086
1087 // Test singular messages.
1088 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1089 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1090 getFields{3: V(wantL), 4: V(wantM)},
1091 clearFields{3, 4},
1092 hasFields{3: false, 4: false},
1093 setFields{3: V(wantL), 4: V(wantM)},
1094 hasFields{3: true, 4: true},
1095
1096 // Test list of enums and messages.
1097 listFields{
1098 5: listOps{
1099 appendList{VE(111), VE(222)},
1100 setList{0: VE(333)},
1101 getList{0: VE(333), 1: VE(222)},
1102 lenList(2),
1103 },
1104 6: listOps{
1105 appendMessageList{setFields{4: V(uint32(1e6))}},
1106 appendMessageList{setFields{6: V(float32(math.Phi))}},
1107 setList{0: V(wantM2a)},
1108 getList{0: V(wantM2a), 1: V(wantM2b)},
1109 },
1110 },
1111 getFields{5: wantList5, 6: wantList6},
1112 hasFields{5: true, 6: true},
1113 listFields{5: listOps{truncList(0)}},
1114 hasFields{5: false, 6: true},
1115
1116 // Test maps of enums and messages.
1117 mapFields{
1118 7: mapOps{
1119 setMap{"one": VE(1), "two": VE(2)},
1120 hasMap{"one": true, "two": true, "three": false},
1121 lenMap(2),
1122 },
1123 8: mapOps{
1124 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1125 setMap{"ln2": V(wantM3b)},
1126 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1127 lenMap(2),
1128 },
1129 },
1130 getFields{7: wantMap7, 8: wantMap8},
1131 hasFields{7: true, 8: true},
1132 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1133 hasFields{7: true, 8: false},
1134
1135 // Test oneofs of enums and messages.
1136 setFields{9: VE(0xdead)},
1137 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1138 setFields{10: VE(0)},
1139 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1140 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1141 getFields{11: V(wantM2a)},
1142 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1143 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1144 getFields{12: V(wantM3a)},
1145 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1146
1147 // Check entire message.
1148 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1149 equalMessage{&EnumMessages{
1150 EnumP2: EnumProto2(0xdead).Enum(),
1151 EnumP3: EnumProto3(0).Enum(),
Joe Tsai009e0672018-11-27 18:45:07 -08001152 MessageLegacy: &proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001153 MessageCycle: wantM,
1154 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1155 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1156 Union: &EnumMessages_OneofM3{wantM3a},
1157 }},
1158 clearFields{1, 2, 3, 4, 6, 7, 12},
1159 equalMessage{&EnumMessages{}},
1160 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001161
1162 // Test read-only operations on nil message.
1163 testMessage(t, nil, (*EnumMessages)(nil), messageOps{
1164 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},
1165 getFields{1: VE(0xbeef), 2: VE(1), 3: V(nil), 4: V(nil), 9: VE(0xbeef), 10: VE(1), 11: V(nil), 12: V(nil)},
1166 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1167 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1168 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001169}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001170
Joe Tsai91e14662018-09-13 13:24:35 -07001171var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001172 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1173 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001174 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001175 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1176 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001177 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001178 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
Joe Tsaiba0ef9a2018-11-29 14:54:05 -08001179 return x.ProtoUnwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001180 }),
1181 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001182 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001183}
1184
1185func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1186 fs := m.KnownFields()
1187 for i, op := range tt {
1188 p.Push(i)
1189 switch op := op.(type) {
1190 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001191 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001192 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1193 }
1194 case hasFields:
1195 got := map[pref.FieldNumber]bool{}
1196 want := map[pref.FieldNumber]bool(op)
1197 for n := range want {
1198 got[n] = fs.Has(n)
1199 }
1200 if diff := cmp.Diff(want, got); diff != "" {
1201 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1202 }
1203 case getFields:
1204 got := map[pref.FieldNumber]pref.Value{}
1205 want := map[pref.FieldNumber]pref.Value(op)
1206 for n := range want {
1207 got[n] = fs.Get(n)
1208 }
1209 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1210 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1211 }
1212 case setFields:
1213 for n, v := range op {
1214 fs.Set(n, v)
1215 }
1216 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001217 for _, n := range op {
1218 fs.Clear(n)
1219 }
1220 case messageFields:
1221 for n, tt := range op {
1222 p.Push(int(n))
Damien Neil97e7f572018-12-07 14:28:33 -08001223 if !fs.Has(n) {
1224 fs.Set(n, V(fs.NewMessage(n)))
1225 }
1226 testMessage(t, p, fs.Get(n).Message(), tt)
Joe Tsai87b955b2018-11-14 21:59:49 -08001227 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001228 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001229 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001230 for n, tt := range op {
1231 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001232 testLists(t, p, fs.Get(n).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001233 p.Pop()
1234 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001235 case mapFields:
1236 for n, tt := range op {
1237 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001238 testMaps(t, p, fs.Get(n).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001239 p.Pop()
1240 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001241 case rangeFields:
1242 got := map[pref.FieldNumber]pref.Value{}
1243 want := map[pref.FieldNumber]pref.Value(op)
1244 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1245 got[n] = v
1246 return true
1247 })
1248 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1249 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1250 }
Joe Tsai91e14662018-09-13 13:24:35 -07001251 default:
1252 t.Fatalf("operation %v, invalid operation: %T", p, op)
1253 }
1254 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001255 }
1256}
Joe Tsai91e14662018-09-13 13:24:35 -07001257
Joe Tsai4b7aff62018-11-14 14:05:19 -08001258func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001259 for i, op := range tt {
1260 p.Push(i)
1261 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001262 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001263 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001264 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001265 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001266 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001267 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001268 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001269 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001270 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001271 got := map[int]pref.Value{}
1272 want := map[int]pref.Value(op)
1273 for n := range want {
1274 got[n] = v.Get(n)
1275 }
1276 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001277 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001278 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001279 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001280 for n, e := range op {
1281 v.Set(n, e)
1282 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001283 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001284 for _, e := range op {
1285 v.Append(e)
1286 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001287 case appendMessageList:
Damien Neil97e7f572018-12-07 14:28:33 -08001288 m := v.NewMessage().ProtoReflect()
1289 v.Append(V(m))
1290 testMessage(t, p, m, messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001291 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001292 v.Truncate(int(op))
1293 default:
1294 t.Fatalf("operation %v, invalid operation: %T", p, op)
1295 }
1296 p.Pop()
1297 }
1298}
1299
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001300func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1301 for i, op := range tt {
1302 p.Push(i)
1303 switch op := op.(type) {
1304 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001305 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001306 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1307 }
1308 case lenMap:
1309 if got, want := m.Len(), int(op); got != want {
1310 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1311 }
1312 case hasMap:
1313 got := map[interface{}]bool{}
1314 want := map[interface{}]bool(op)
1315 for k := range want {
1316 got[k] = m.Has(V(k).MapKey())
1317 }
1318 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1319 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1320 }
1321 case getMap:
1322 got := map[interface{}]pref.Value{}
1323 want := map[interface{}]pref.Value(op)
1324 for k := range want {
1325 got[k] = m.Get(V(k).MapKey())
1326 }
1327 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1328 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1329 }
1330 case setMap:
1331 for k, v := range op {
1332 m.Set(V(k).MapKey(), v)
1333 }
1334 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001335 for _, k := range op {
1336 m.Clear(V(k).MapKey())
1337 }
1338 case messageMap:
1339 for k, tt := range op {
Damien Neil97e7f572018-12-07 14:28:33 -08001340 mk := V(k).MapKey()
1341 if !m.Has(mk) {
1342 m.Set(mk, V(m.NewMessage()))
1343 }
1344 testMessage(t, p, m.Get(mk).Message(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001345 }
1346 case rangeMap:
1347 got := map[interface{}]pref.Value{}
1348 want := map[interface{}]pref.Value(op)
1349 m.Range(func(k pref.MapKey, v pref.Value) bool {
1350 got[k.Interface()] = v
1351 return true
1352 })
1353 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1354 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1355 }
1356 default:
1357 t.Fatalf("operation %v, invalid operation: %T", p, op)
1358 }
1359 p.Pop()
1360 }
1361}
1362
Joe Tsai91e14662018-09-13 13:24:35 -07001363type path []int
1364
1365func (p *path) Push(i int) { *p = append(*p, i) }
1366func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1367func (p path) String() string {
1368 var ss []string
1369 for _, i := range p {
1370 ss = append(ss, fmt.Sprint(i))
1371 }
1372 return strings.Join(ss, ".")
1373}