blob: 4132fd1355cd88458531ddd5fb47438b4bf610ee [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"
Damien Neil8012b442019-01-18 09:32:24 -080010 "reflect"
Joe Tsai82760ce2019-06-20 03:09:57 -070011 "runtime"
Joe Tsai91e14662018-09-13 13:24:35 -070012 "strings"
Joe Tsai82760ce2019-06-20 03:09:57 -070013 "sync"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070014 "testing"
15
Joe Tsai87b955b2018-11-14 21:59:49 -080016 cmp "github.com/google/go-cmp/cmp"
17 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaid8881392019-06-06 13:01:53 -070018 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070019 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070020 scalar "google.golang.org/protobuf/internal/scalar"
Joe Tsaid8881392019-06-06 13:01:53 -070021 "google.golang.org/protobuf/proto"
22 pdesc "google.golang.org/protobuf/reflect/protodesc"
Damien Neile89e6242019-05-13 23:55:40 -070023 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsaid8881392019-06-06 13:01:53 -070024 "google.golang.org/protobuf/reflect/protoregistry"
Joe Tsaib2f66be2019-05-22 00:42:45 -040025 "google.golang.org/protobuf/reflect/prototype"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070026
Damien Neile89e6242019-05-13 23:55:40 -070027 proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
Joe Tsai82760ce2019-06-20 03:09:57 -070028 testpb "google.golang.org/protobuf/internal/testprotos/test"
Joe Tsaia95b29f2019-05-16 12:47:20 -070029 "google.golang.org/protobuf/types/descriptorpb"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070030)
31
Joe Tsai4b7aff62018-11-14 14:05:19 -080032// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070033type (
Joe Tsai87b955b2018-11-14 21:59:49 -080034 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070035 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070036
Joe Tsai87b955b2018-11-14 21:59:49 -080037 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080038 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070039
Joe Tsai87b955b2018-11-14 21:59:49 -080040 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000041 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070042)
43
44// Test operations performed on a message.
45type (
Joe Tsai87b955b2018-11-14 21:59:49 -080046 // check that the message contents match
47 equalMessage struct{ pref.Message }
48 // check presence for specific fields in the message
49 hasFields map[pref.FieldNumber]bool
50 // check that specific message fields match
51 getFields map[pref.FieldNumber]pref.Value
52 // set specific message fields
53 setFields map[pref.FieldNumber]pref.Value
54 // clear specific fields in the message
55 clearFields []pref.FieldNumber
Joe Tsai4ec39c72019-04-03 13:40:53 -070056 // check for the presence of specific oneof member fields.
57 whichOneofs map[pref.Name]pref.FieldNumber
Joe Tsai87b955b2018-11-14 21:59:49 -080058 // apply messageOps on each specified message field
Joe Tsai378c1322019-04-25 23:48:08 -070059 messageFields map[pref.FieldNumber]messageOps
60 messageFieldsMutable map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080061 // apply listOps on each specified list field
Joe Tsai378c1322019-04-25 23:48:08 -070062 listFields map[pref.FieldNumber]listOps
63 listFieldsMutable map[pref.FieldNumber]listOps
Joe Tsai87b955b2018-11-14 21:59:49 -080064 // apply mapOps on each specified map fields
Joe Tsai378c1322019-04-25 23:48:08 -070065 mapFields map[pref.FieldNumber]mapOps
66 mapFieldsMutable map[pref.FieldNumber]mapOps
Joe Tsai87b955b2018-11-14 21:59:49 -080067 // range through all fields and check that they match
68 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070069)
70
Joe Tsai378c1322019-04-25 23:48:08 -070071func (equalMessage) isMessageOp() {}
72func (hasFields) isMessageOp() {}
73func (getFields) isMessageOp() {}
74func (setFields) isMessageOp() {}
75func (clearFields) isMessageOp() {}
76func (whichOneofs) isMessageOp() {}
77func (messageFields) isMessageOp() {}
78func (messageFieldsMutable) isMessageOp() {}
79func (listFields) isMessageOp() {}
80func (listFieldsMutable) isMessageOp() {}
81func (mapFields) isMessageOp() {}
82func (mapFieldsMutable) isMessageOp() {}
83func (rangeFields) isMessageOp() {}
Joe Tsai87b955b2018-11-14 21:59:49 -080084
Joe Tsai4b7aff62018-11-14 14:05:19 -080085// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070086type (
Joe Tsai87b955b2018-11-14 21:59:49 -080087 // check that the list contents match
88 equalList struct{ pref.List }
89 // check that list length matches
90 lenList int
91 // check that specific list entries match
92 getList map[int]pref.Value
93 // set specific list entries
94 setList map[int]pref.Value
95 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080096 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080097 // apply messageOps on a newly appended message
98 appendMessageList messageOps
99 // truncate the list to the specified length
100 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -0700101)
102
Joe Tsai87b955b2018-11-14 21:59:49 -0800103func (equalList) isListOp() {}
104func (lenList) isListOp() {}
105func (getList) isListOp() {}
106func (setList) isListOp() {}
107func (appendList) isListOp() {}
108func (appendMessageList) isListOp() {}
109func (truncList) isListOp() {}
110
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000111// Test operations performed on a map.
112type (
Joe Tsai87b955b2018-11-14 21:59:49 -0800113 // check that the map contents match
114 equalMap struct{ pref.Map }
115 // check that map length matches
116 lenMap int
117 // check presence for specific entries in the map
118 hasMap map[interface{}]bool
119 // check that specific map entries match
120 getMap map[interface{}]pref.Value
121 // set specific map entries
122 setMap map[interface{}]pref.Value
123 // clear specific entries in the map
124 clearMap []interface{}
125 // apply messageOps on each specified message entry
126 messageMap map[interface{}]messageOps
127 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000128 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000129)
130
Joe Tsai87b955b2018-11-14 21:59:49 -0800131func (equalMap) isMapOp() {}
132func (lenMap) isMapOp() {}
133func (hasMap) isMapOp() {}
134func (getMap) isMapOp() {}
135func (setMap) isMapOp() {}
136func (clearMap) isMapOp() {}
137func (messageMap) isMapOp() {}
138func (rangeMap) isMapOp() {}
139
Joe Tsaice6edd32018-10-19 16:27:46 -0700140type ScalarProto2 struct {
141 Bool *bool `protobuf:"1"`
142 Int32 *int32 `protobuf:"2"`
143 Int64 *int64 `protobuf:"3"`
144 Uint32 *uint32 `protobuf:"4"`
145 Uint64 *uint64 `protobuf:"5"`
146 Float32 *float32 `protobuf:"6"`
147 Float64 *float64 `protobuf:"7"`
148 String *string `protobuf:"8"`
149 StringA []byte `protobuf:"9"`
150 Bytes []byte `protobuf:"10"`
151 BytesA *string `protobuf:"11"`
152
153 MyBool *MyBool `protobuf:"12"`
154 MyInt32 *MyInt32 `protobuf:"13"`
155 MyInt64 *MyInt64 `protobuf:"14"`
156 MyUint32 *MyUint32 `protobuf:"15"`
157 MyUint64 *MyUint64 `protobuf:"16"`
158 MyFloat32 *MyFloat32 `protobuf:"17"`
159 MyFloat64 *MyFloat64 `protobuf:"18"`
160 MyString *MyString `protobuf:"19"`
161 MyStringA MyBytes `protobuf:"20"`
162 MyBytes MyBytes `protobuf:"21"`
163 MyBytesA *MyString `protobuf:"22"`
164}
165
Joe Tsaid8881392019-06-06 13:01:53 -0700166func mustMakeEnumDesc(path string, syntax pref.Syntax, enumDesc string) pref.EnumDescriptor {
167 s := fmt.Sprintf(`name:%q syntax:%q enum_type:[{%s}]`, path, syntax, enumDesc)
168 pb := new(descriptorpb.FileDescriptorProto)
169 if err := prototext.Unmarshal([]byte(s), pb); err != nil {
170 panic(err)
171 }
172 fd, err := pdesc.NewFile(pb, nil)
Joe Tsai87b955b2018-11-14 21:59:49 -0800173 if err != nil {
174 panic(err)
175 }
Joe Tsaid8881392019-06-06 13:01:53 -0700176 return fd.Enums().Get(0)
Joe Tsai87b955b2018-11-14 21:59:49 -0800177}
178
Joe Tsaid8881392019-06-06 13:01:53 -0700179func mustMakeMessageDesc(path string, syntax pref.Syntax, fileDesc, msgDesc string, r pdesc.Resolver) pref.MessageDescriptor {
180 s := fmt.Sprintf(`name:%q syntax:%q %s message_type:[{%s}]`, path, syntax, fileDesc, msgDesc)
181 pb := new(descriptorpb.FileDescriptorProto)
182 if err := prototext.Unmarshal([]byte(s), pb); err != nil {
183 panic(err)
184 }
185 fd, err := pdesc.NewFile(pb, r)
Joe Tsai87b955b2018-11-14 21:59:49 -0800186 if err != nil {
187 panic(err)
188 }
Joe Tsaid8881392019-06-06 13:01:53 -0700189 return fd.Messages().Get(0)
Joe Tsai87b955b2018-11-14 21:59:49 -0800190}
191
192var V = pref.ValueOf
193var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
194
195type (
196 MyBool bool
197 MyInt32 int32
198 MyInt64 int64
199 MyUint32 uint32
200 MyUint64 uint64
201 MyFloat32 float32
202 MyFloat64 float64
203 MyString string
204 MyBytes []byte
205
206 ListStrings []MyString
207 ListBytes []MyBytes
208
209 MapStrings map[MyString]MyString
210 MapBytes map[MyString]MyBytes
211)
212
Joe Tsaib2f66be2019-05-22 00:42:45 -0400213var scalarProto2Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto2)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700214 MessageDescriptor: mustMakeMessageDesc("scalar2.proto", pref.Proto2, "", `
215 name: "ScalarProto2"
216 field: [
217 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true"},
218 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"2"},
219 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"3"},
220 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4"},
221 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5"},
222 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"6"},
223 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7"},
224 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8"},
225 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9"},
226 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"10"},
227 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"11"},
Joe Tsai91e14662018-09-13 13:24:35 -0700228
Joe Tsaid8881392019-06-06 13:01:53 -0700229 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true"},
230 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"13"},
231 {name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"14"},
232 {name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"15"},
233 {name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"16"},
234 {name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"17"},
235 {name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"18"},
236 {name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"19"},
237 {name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"20"},
238 {name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"21"},
239 {name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"22"}
240 ]
241 `, nil),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400242 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -0700243 return pref.ProtoMessage(new(ScalarProto2)).ProtoReflect()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800244 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400245}}
Joe Tsai91e14662018-09-13 13:24:35 -0700246
Joe Tsai378c1322019-04-25 23:48:08 -0700247func (m *ScalarProto2) ProtoReflect() pref.Message { return scalarProto2Type.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800248
249func TestScalarProto2(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700250 testMessage(t, nil, new(ScalarProto2).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700251 hasFields{
252 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
253 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
254 },
255 getFields{
256 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")),
257 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")),
258 },
259 setFields{
260 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)),
261 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)),
262 },
263 hasFields{
264 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
265 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
266 },
Joe Tsai378c1322019-04-25 23:48:08 -0700267 equalMessage{(&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700268 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
269 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
Joe Tsai378c1322019-04-25 23:48:08 -0700270 }).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800271 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
Joe Tsai378c1322019-04-25 23:48:08 -0700272 equalMessage{new(ScalarProto2).ProtoReflect()},
Joe Tsai3e6a39b2019-07-10 10:21:12 -0700273
274 // Setting a bytes field nil empty bytes should preserve presence.
275 setFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
276 getFields{10: V([]byte{}), 11: V([]byte(nil)), 21: V([]byte{}), 22: V([]byte(nil))},
277 hasFields{10: true, 11: true, 21: true, 22: true},
Joe Tsai91e14662018-09-13 13:24:35 -0700278 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800279
280 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700281 testMessage(t, nil, (*ScalarProto2)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800282 hasFields{
283 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
284 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
285 },
286 getFields{
287 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")),
288 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")),
289 },
290 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700291}
292
Joe Tsaice6edd32018-10-19 16:27:46 -0700293type ScalarProto3 struct {
294 Bool bool `protobuf:"1"`
295 Int32 int32 `protobuf:"2"`
296 Int64 int64 `protobuf:"3"`
297 Uint32 uint32 `protobuf:"4"`
298 Uint64 uint64 `protobuf:"5"`
299 Float32 float32 `protobuf:"6"`
300 Float64 float64 `protobuf:"7"`
301 String string `protobuf:"8"`
302 StringA []byte `protobuf:"9"`
303 Bytes []byte `protobuf:"10"`
304 BytesA string `protobuf:"11"`
305
306 MyBool MyBool `protobuf:"12"`
307 MyInt32 MyInt32 `protobuf:"13"`
308 MyInt64 MyInt64 `protobuf:"14"`
309 MyUint32 MyUint32 `protobuf:"15"`
310 MyUint64 MyUint64 `protobuf:"16"`
311 MyFloat32 MyFloat32 `protobuf:"17"`
312 MyFloat64 MyFloat64 `protobuf:"18"`
313 MyString MyString `protobuf:"19"`
314 MyStringA MyBytes `protobuf:"20"`
315 MyBytes MyBytes `protobuf:"21"`
316 MyBytesA MyString `protobuf:"22"`
317}
318
Joe Tsaib2f66be2019-05-22 00:42:45 -0400319var scalarProto3Type = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ScalarProto3)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700320 MessageDescriptor: mustMakeMessageDesc("scalar3.proto", pref.Proto3, "", `
321 name: "ScalarProto3"
322 field: [
323 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL},
324 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32},
325 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64},
326 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32},
327 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64},
328 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT},
329 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE},
330 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING},
331 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING},
332 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES},
333 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700334
Joe Tsaid8881392019-06-06 13:01:53 -0700335 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL},
336 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32},
337 {name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64},
338 {name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32},
339 {name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64},
340 {name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT},
341 {name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE},
342 {name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING},
343 {name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING},
344 {name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES},
345 {name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES}
346 ]
347 `, nil),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400348 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -0700349 return pref.ProtoMessage(new(ScalarProto3)).ProtoReflect()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800350 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400351}}
Joe Tsai91e14662018-09-13 13:24:35 -0700352
Joe Tsai378c1322019-04-25 23:48:08 -0700353func (m *ScalarProto3) ProtoReflect() pref.Message { return scalarProto3Type.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800354
355func TestScalarProto3(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700356 testMessage(t, nil, new(ScalarProto3).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700357 hasFields{
358 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
359 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
360 },
361 getFields{
362 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)),
363 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)),
364 },
365 setFields{
366 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)),
367 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)),
368 },
369 hasFields{
370 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
371 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
372 },
Joe Tsai378c1322019-04-25 23:48:08 -0700373 equalMessage{new(ScalarProto3).ProtoReflect()},
Joe Tsai91e14662018-09-13 13:24:35 -0700374 setFields{
375 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")),
376 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")),
377 },
378 hasFields{
379 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
380 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
381 },
Joe Tsai378c1322019-04-25 23:48:08 -0700382 equalMessage{(&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700383 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
384 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai378c1322019-04-25 23:48:08 -0700385 }).ProtoReflect()},
Joe Tsai44e389c2018-11-19 15:27:09 -0800386 setFields{
387 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
388 },
389 hasFields{
390 2: true, 3: true, 6: true, 7: true,
391 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800392 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
Joe Tsai378c1322019-04-25 23:48:08 -0700393 equalMessage{new(ScalarProto3).ProtoReflect()},
Joe Tsai060cdac2019-04-22 11:44:49 -0700394
395 // Verify that -0 triggers proper Has behavior.
396 hasFields{6: false, 7: false},
397 setFields{6: V(float32(math.Copysign(0, -1))), 7: V(float64(math.Copysign(0, -1)))},
398 hasFields{6: true, 7: true},
Joe Tsai3e6a39b2019-07-10 10:21:12 -0700399
400 // Setting a bytes field to non-nil empty bytes should not preserve presence.
401 setFields{10: V([]byte{}), 11: V([]byte{}), 21: V([]byte{}), 22: V([]byte{})},
402 getFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
403 hasFields{10: false, 11: false, 21: false, 22: false},
Joe Tsai91e14662018-09-13 13:24:35 -0700404 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800405
406 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700407 testMessage(t, nil, (*ScalarProto3)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800408 hasFields{
409 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
410 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
411 },
412 getFields{
413 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)),
414 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)),
415 },
416 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700417}
418
Joe Tsaif0c01e42018-11-06 13:05:20 -0800419type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700420 Bools []bool `protobuf:"1"`
421 Int32s []int32 `protobuf:"2"`
422 Int64s []int64 `protobuf:"3"`
423 Uint32s []uint32 `protobuf:"4"`
424 Uint64s []uint64 `protobuf:"5"`
425 Float32s []float32 `protobuf:"6"`
426 Float64s []float64 `protobuf:"7"`
427 Strings []string `protobuf:"8"`
428 StringsA [][]byte `protobuf:"9"`
429 Bytes [][]byte `protobuf:"10"`
430 BytesA []string `protobuf:"11"`
431
432 MyStrings1 []MyString `protobuf:"12"`
433 MyStrings2 []MyBytes `protobuf:"13"`
434 MyBytes1 []MyBytes `protobuf:"14"`
435 MyBytes2 []MyString `protobuf:"15"`
436
Joe Tsai4b7aff62018-11-14 14:05:19 -0800437 MyStrings3 ListStrings `protobuf:"16"`
438 MyStrings4 ListBytes `protobuf:"17"`
439 MyBytes3 ListBytes `protobuf:"18"`
440 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700441}
442
Joe Tsaib2f66be2019-05-22 00:42:45 -0400443var listScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(ListScalars)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700444 MessageDescriptor: mustMakeMessageDesc("list-scalars.proto", pref.Proto2, "", `
445 name: "ListScalars"
446 field: [
447 {name:"f1" number:1 label:LABEL_REPEATED type:TYPE_BOOL},
448 {name:"f2" number:2 label:LABEL_REPEATED type:TYPE_INT32},
449 {name:"f3" number:3 label:LABEL_REPEATED type:TYPE_INT64},
450 {name:"f4" number:4 label:LABEL_REPEATED type:TYPE_UINT32},
451 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_UINT64},
452 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_FLOAT},
453 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_DOUBLE},
454 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_STRING},
455 {name:"f9" number:9 label:LABEL_REPEATED type:TYPE_STRING},
456 {name:"f10" number:10 label:LABEL_REPEATED type:TYPE_BYTES},
457 {name:"f11" number:11 label:LABEL_REPEATED type:TYPE_BYTES},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700458
Joe Tsaid8881392019-06-06 13:01:53 -0700459 {name:"f12" number:12 label:LABEL_REPEATED type:TYPE_STRING},
460 {name:"f13" number:13 label:LABEL_REPEATED type:TYPE_STRING},
461 {name:"f14" number:14 label:LABEL_REPEATED type:TYPE_BYTES},
462 {name:"f15" number:15 label:LABEL_REPEATED type:TYPE_BYTES},
Joe Tsai91e14662018-09-13 13:24:35 -0700463
Joe Tsaid8881392019-06-06 13:01:53 -0700464 {name:"f16" number:16 label:LABEL_REPEATED type:TYPE_STRING},
465 {name:"f17" number:17 label:LABEL_REPEATED type:TYPE_STRING},
466 {name:"f18" number:18 label:LABEL_REPEATED type:TYPE_BYTES},
467 {name:"f19" number:19 label:LABEL_REPEATED type:TYPE_BYTES}
468 ]
469 `, nil),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400470 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -0700471 return pref.ProtoMessage(new(ListScalars)).ProtoReflect()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800472 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400473}}
Joe Tsai91e14662018-09-13 13:24:35 -0700474
Joe Tsai378c1322019-04-25 23:48:08 -0700475func (m *ListScalars) ProtoReflect() pref.Message { return listScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800476
477func TestListScalars(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700478 empty := new(ListScalars).ProtoReflect()
479 want := (&ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700480 Bools: []bool{true, false, true},
481 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
482 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
483 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
484 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
485 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
486 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
487 Strings: []string{"8", "", "eight"},
488 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
489 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
490 BytesA: []string{"11", "", "eleven"},
491
492 MyStrings1: []MyString{"12", "", "twelve"},
493 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
494 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
495 MyBytes2: []MyString{"15", "", "fifteen"},
496
Joe Tsai4b7aff62018-11-14 14:05:19 -0800497 MyStrings3: ListStrings{"16", "", "sixteen"},
498 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
499 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
500 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsai378c1322019-04-25 23:48:08 -0700501 }).ProtoReflect()
Joe Tsai91e14662018-09-13 13:24:35 -0700502
Joe Tsai378c1322019-04-25 23:48:08 -0700503 testMessage(t, nil, new(ListScalars).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700504 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},
Joe Tsai378c1322019-04-25 23:48:08 -0700505 getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19)},
506 setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19)},
507 listFieldsMutable{
Joe Tsai91e14662018-09-13 13:24:35 -0700508 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800509 lenList(0),
510 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
511 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai378c1322019-04-25 23:48:08 -0700512 equalList{getField(want, 2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700513 },
514 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800515 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
516 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
517 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700518 },
519 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800520 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai378c1322019-04-25 23:48:08 -0700521 equalList{getField(want, 6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700522 },
523 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800524 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
525 lenList(6),
526 setList{0: V("8"), 2: V("eight")},
527 truncList(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700528 equalList{getField(want, 8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700529 },
530 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800531 appendList{V([]byte(nil)), V([]byte(nil))},
532 setList{0: V([]byte("10"))},
533 appendList{V([]byte("wrong"))},
534 setList{2: V([]byte("ten"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700535 equalList{getField(want, 10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700536 },
537 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800538 appendList{V("12"), V("wrong"), V("twelve")},
539 setList{1: V("")},
Joe Tsai378c1322019-04-25 23:48:08 -0700540 equalList{getField(want, 12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700541 },
542 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800543 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700544 equalList{getField(want, 14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700545 },
546 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800547 appendList{V("16"), V(""), V("sixteen"), V("extra")},
548 truncList(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700549 equalList{getField(want, 16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700550 },
551 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800552 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700553 equalList{getField(want, 18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700554 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700555 },
Joe Tsai91e14662018-09-13 13:24:35 -0700556 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 -0800557 equalMessage{want},
558 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
559 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000560 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800561
562 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700563 testMessage(t, nil, (*ListScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800564 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},
565 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)}},
566 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000567}
568
Joe Tsaice6edd32018-10-19 16:27:46 -0700569type MapScalars struct {
570 KeyBools map[bool]string `protobuf:"1"`
571 KeyInt32s map[int32]string `protobuf:"2"`
572 KeyInt64s map[int64]string `protobuf:"3"`
573 KeyUint32s map[uint32]string `protobuf:"4"`
574 KeyUint64s map[uint64]string `protobuf:"5"`
575 KeyStrings map[string]string `protobuf:"6"`
576
577 ValBools map[string]bool `protobuf:"7"`
578 ValInt32s map[string]int32 `protobuf:"8"`
579 ValInt64s map[string]int64 `protobuf:"9"`
580 ValUint32s map[string]uint32 `protobuf:"10"`
581 ValUint64s map[string]uint64 `protobuf:"11"`
582 ValFloat32s map[string]float32 `protobuf:"12"`
583 ValFloat64s map[string]float64 `protobuf:"13"`
584 ValStrings map[string]string `protobuf:"14"`
585 ValStringsA map[string][]byte `protobuf:"15"`
586 ValBytes map[string][]byte `protobuf:"16"`
587 ValBytesA map[string]string `protobuf:"17"`
588
589 MyStrings1 map[MyString]MyString `protobuf:"18"`
590 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
591 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
592 MyBytes2 map[MyString]MyString `protobuf:"21"`
593
594 MyStrings3 MapStrings `protobuf:"22"`
595 MyStrings4 MapBytes `protobuf:"23"`
596 MyBytes3 MapBytes `protobuf:"24"`
597 MyBytes4 MapStrings `protobuf:"25"`
598}
599
Joe Tsaib2f66be2019-05-22 00:42:45 -0400600var mapScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(MapScalars)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700601 MessageDescriptor: mustMakeMessageDesc("map-scalars.proto", pref.Proto2, "", `
602 name: "MapScalars"
603 field: [
604 {name:"f1" number:1 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F1Entry"},
605 {name:"f2" number:2 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F2Entry"},
606 {name:"f3" number:3 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F3Entry"},
607 {name:"f4" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F4Entry"},
608 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F5Entry"},
609 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F6Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000610
Joe Tsaid8881392019-06-06 13:01:53 -0700611 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F7Entry"},
612 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F8Entry"},
613 {name:"f9" number:9 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F9Entry"},
614 {name:"f10" number:10 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F10Entry"},
615 {name:"f11" number:11 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F11Entry"},
616 {name:"f12" number:12 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F12Entry"},
617 {name:"f13" number:13 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F13Entry"},
618 {name:"f14" number:14 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F14Entry"},
619 {name:"f15" number:15 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F15Entry"},
620 {name:"f16" number:16 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F16Entry"},
621 {name:"f17" number:17 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F17Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000622
Joe Tsaid8881392019-06-06 13:01:53 -0700623 {name:"f18" number:18 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F18Entry"},
624 {name:"f19" number:19 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F19Entry"},
625 {name:"f20" number:20 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F20Entry"},
626 {name:"f21" number:21 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F21Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000627
Joe Tsaid8881392019-06-06 13:01:53 -0700628 {name:"f22" number:22 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F22Entry"},
629 {name:"f23" number:23 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F23Entry"},
630 {name:"f24" number:24 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F24Entry"},
631 {name:"f25" number:25 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F25Entry"}
632 ]
633 nested_type: [
634 {name:"F1Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
635 {name:"F2Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT32}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
636 {name:"F3Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT64}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
637 {name:"F4Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
638 {name:"F5Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT64}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
639 {name:"F6Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
640
641 {name:"F7Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BOOL}] options:{map_entry:true}},
642 {name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT32}] options:{map_entry:true}},
643 {name:"F9Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT64}] options:{map_entry:true}},
644 {name:"F10Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT32}] options:{map_entry:true}},
645 {name:"F11Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT64}] options:{map_entry:true}},
646 {name:"F12Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_FLOAT}] options:{map_entry:true}},
647 {name:"F13Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_DOUBLE}] options:{map_entry:true}},
648 {name:"F14Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
649 {name:"F15Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
650 {name:"F16Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
651 {name:"F17Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
652
653 {name:"F18Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
654 {name:"F19Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
655 {name:"F20Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
656 {name:"F21Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
657
658 {name:"F22Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
659 {name:"F23Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
660 {name:"F24Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
661 {name:"F25Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}}
662 ]
663 `, nil),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400664 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -0700665 return pref.ProtoMessage(new(MapScalars)).ProtoReflect()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800666 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400667}}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000668
Joe Tsai378c1322019-04-25 23:48:08 -0700669func (m *MapScalars) ProtoReflect() pref.Message { return mapScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800670
671func TestMapScalars(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700672 empty := new(MapScalars).ProtoReflect()
673 want := (&MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000674 KeyBools: map[bool]string{true: "true", false: "false"},
675 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
676 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
677 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
678 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
679 KeyStrings: map[string]string{"": "", "foo": "bar"},
680
681 ValBools: map[string]bool{"true": true, "false": false},
682 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
683 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
684 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
685 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
686 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
687 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
688 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
689 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
690 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
691 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
692
693 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
694 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
695 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
696 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
697
698 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
699 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
700 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
701 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsai378c1322019-04-25 23:48:08 -0700702 }).ProtoReflect()
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000703
Joe Tsai378c1322019-04-25 23:48:08 -0700704 testMessage(t, nil, new(MapScalars).ProtoReflect(), messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000705 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},
Joe Tsai378c1322019-04-25 23:48:08 -0700706 getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19), 21: getField(empty, 21), 23: getField(empty, 23), 25: getField(empty, 25)},
707 setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19), 21: getField(want, 21), 23: getField(want, 23), 25: getField(want, 25)},
708 mapFieldsMutable{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000709 2: {
710 lenMap(0),
711 hasMap{int32(0): false, int32(-1): false, int32(2): false},
712 setMap{int32(0): V("zero")},
713 lenMap(1),
714 hasMap{int32(0): true, int32(-1): false, int32(2): false},
715 setMap{int32(-1): V("one")},
716 lenMap(2),
717 hasMap{int32(0): true, int32(-1): true, int32(2): false},
718 setMap{int32(2): V("two")},
719 lenMap(3),
720 hasMap{int32(0): true, int32(-1): true, int32(2): true},
721 },
722 4: {
723 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai378c1322019-04-25 23:48:08 -0700724 equalMap{getField(want, 4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000725 },
726 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800727 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000728 setMap{"foo": V("bar")},
729 setMap{"": V("empty")},
730 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
731 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800732 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000733 },
734 8: {
Joe Tsai378c1322019-04-25 23:48:08 -0700735 equalMap{getField(empty, 8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000736 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
737 },
738 10: {
739 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
740 lenMap(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700741 equalMap{getField(want, 10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000742 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
743 },
744 12: {
745 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800746 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000747 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
748 },
749 14: {
Joe Tsai378c1322019-04-25 23:48:08 -0700750 equalMap{getField(empty, 14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000751 setMap{"s1": V("s1"), "s2": V("s2")},
752 },
753 16: {
754 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700755 equalMap{getField(want, 16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000756 },
757 18: {
758 hasMap{"s1": false, "s2": false, "s3": false},
759 setMap{"s1": V("s1"), "s2": V("s2")},
760 hasMap{"s1": true, "s2": true, "s3": false},
761 },
762 20: {
Joe Tsai378c1322019-04-25 23:48:08 -0700763 equalMap{getField(empty, 20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000764 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
765 },
766 22: {
767 rangeMap{},
768 setMap{"s1": V("s1"), "s2": V("s2")},
769 rangeMap{"s1": V("s1"), "s2": V("s2")},
770 lenMap(2),
771 },
772 24: {
773 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700774 equalMap{getField(want, 24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000775 },
776 },
777 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 -0800778 equalMessage{want},
779 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},
780 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700781 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800782
783 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700784 testMessage(t, nil, (*MapScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800785 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},
786 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)}},
787 })
Joe Tsai91e14662018-09-13 13:24:35 -0700788}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700789
Joe Tsai87b955b2018-11-14 21:59:49 -0800790type OneofScalars struct {
791 Union isOneofScalars_Union `protobuf_oneof:"union"`
792}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700793
Joe Tsaib2f66be2019-05-22 00:42:45 -0400794var oneofScalarsType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(OneofScalars)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700795 MessageDescriptor: mustMakeMessageDesc("oneof-scalars.proto", pref.Proto2, "", `
796 name: "OneofScalars"
797 field: [
798 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true" oneof_index:0},
799 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"2" oneof_index:0},
800 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"3" oneof_index:0},
801 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4" oneof_index:0},
802 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5" oneof_index:0},
803 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"6" oneof_index:0},
804 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7" oneof_index:0},
805 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8" oneof_index:0},
806 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9" oneof_index:0},
807 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"10" oneof_index:0},
808 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"11" oneof_index:0},
809 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"12" oneof_index:0},
810 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"13" oneof_index:0}
811 ]
812 oneof_decl: [{name:"union"}]
813 `, nil),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400814 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -0700815 return pref.ProtoMessage(new(OneofScalars)).ProtoReflect()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800816 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400817}}
Joe Tsaif0c01e42018-11-06 13:05:20 -0800818
Joe Tsai378c1322019-04-25 23:48:08 -0700819func (m *OneofScalars) ProtoReflect() pref.Message { return oneofScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800820
Joe Tsaif18ab532018-11-27 17:25:04 -0800821func (*OneofScalars) XXX_OneofWrappers() []interface{} {
822 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700823 (*OneofScalars_Bool)(nil),
824 (*OneofScalars_Int32)(nil),
825 (*OneofScalars_Int64)(nil),
826 (*OneofScalars_Uint32)(nil),
827 (*OneofScalars_Uint64)(nil),
828 (*OneofScalars_Float32)(nil),
829 (*OneofScalars_Float64)(nil),
830 (*OneofScalars_String)(nil),
831 (*OneofScalars_StringA)(nil),
832 (*OneofScalars_StringB)(nil),
833 (*OneofScalars_Bytes)(nil),
834 (*OneofScalars_BytesA)(nil),
835 (*OneofScalars_BytesB)(nil),
836 }
837}
838
Joe Tsai87b955b2018-11-14 21:59:49 -0800839type (
840 isOneofScalars_Union interface {
841 isOneofScalars_Union()
842 }
843 OneofScalars_Bool struct {
844 Bool bool `protobuf:"1"`
845 }
846 OneofScalars_Int32 struct {
847 Int32 MyInt32 `protobuf:"2"`
848 }
849 OneofScalars_Int64 struct {
850 Int64 int64 `protobuf:"3"`
851 }
852 OneofScalars_Uint32 struct {
853 Uint32 MyUint32 `protobuf:"4"`
854 }
855 OneofScalars_Uint64 struct {
856 Uint64 uint64 `protobuf:"5"`
857 }
858 OneofScalars_Float32 struct {
859 Float32 MyFloat32 `protobuf:"6"`
860 }
861 OneofScalars_Float64 struct {
862 Float64 float64 `protobuf:"7"`
863 }
864 OneofScalars_String struct {
865 String string `protobuf:"8"`
866 }
867 OneofScalars_StringA struct {
868 StringA []byte `protobuf:"9"`
869 }
870 OneofScalars_StringB struct {
871 StringB MyString `protobuf:"10"`
872 }
873 OneofScalars_Bytes struct {
874 Bytes []byte `protobuf:"11"`
875 }
876 OneofScalars_BytesA struct {
877 BytesA string `protobuf:"12"`
878 }
879 OneofScalars_BytesB struct {
880 BytesB MyBytes `protobuf:"13"`
881 }
882)
883
Joe Tsai2c870bb2018-10-17 11:46:52 -0700884func (*OneofScalars_Bool) isOneofScalars_Union() {}
885func (*OneofScalars_Int32) isOneofScalars_Union() {}
886func (*OneofScalars_Int64) isOneofScalars_Union() {}
887func (*OneofScalars_Uint32) isOneofScalars_Union() {}
888func (*OneofScalars_Uint64) isOneofScalars_Union() {}
889func (*OneofScalars_Float32) isOneofScalars_Union() {}
890func (*OneofScalars_Float64) isOneofScalars_Union() {}
891func (*OneofScalars_String) isOneofScalars_Union() {}
892func (*OneofScalars_StringA) isOneofScalars_Union() {}
893func (*OneofScalars_StringB) isOneofScalars_Union() {}
894func (*OneofScalars_Bytes) isOneofScalars_Union() {}
895func (*OneofScalars_BytesA) isOneofScalars_Union() {}
896func (*OneofScalars_BytesB) isOneofScalars_Union() {}
897
898func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800899 empty := &OneofScalars{}
900 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
901 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
902 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
903 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
904 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
905 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
906 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
907 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
908 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
909 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
910 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
911 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
912 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700913
Joe Tsai378c1322019-04-25 23:48:08 -0700914 testMessage(t, nil, new(OneofScalars).ProtoReflect(), messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700915 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},
916 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"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700917 whichOneofs{"union": 0},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700918
Joe Tsai378c1322019-04-25 23:48:08 -0700919 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1.ProtoReflect()},
920 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2.ProtoReflect()},
921 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3.ProtoReflect()},
922 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4.ProtoReflect()},
923 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5.ProtoReflect()},
924 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6.ProtoReflect()},
925 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7.ProtoReflect()},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700926
927 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
Joe Tsai378c1322019-04-25 23:48:08 -0700928 whichOneofs{"union": 7},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700929
Joe Tsai378c1322019-04-25 23:48:08 -0700930 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8.ProtoReflect()},
931 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9.ProtoReflect()},
932 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10.ProtoReflect()},
933 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11.ProtoReflect()},
934 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12.ProtoReflect()},
935 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13.ProtoReflect()},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700936
937 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},
938 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 -0800939 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
Joe Tsai378c1322019-04-25 23:48:08 -0700940 whichOneofs{"union": 13},
941 equalMessage{want13.ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800942 clearFields{13},
Joe Tsai378c1322019-04-25 23:48:08 -0700943 whichOneofs{"union": 0},
944 equalMessage{empty.ProtoReflect()},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700945 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800946
947 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700948 testMessage(t, nil, (*OneofScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800949 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},
950 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"))},
951 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700952}
953
Joe Tsai87b955b2018-11-14 21:59:49 -0800954type EnumProto2 int32
955
Joe Tsaib2f66be2019-05-22 00:42:45 -0400956var enumProto2Type = &prototype.Enum{
Joe Tsaid8881392019-06-06 13:01:53 -0700957 EnumDescriptor: mustMakeEnumDesc("enum2.proto", pref.Proto2, `
958 name: "EnumProto2"
959 value: [{name:"DEAD" number:0xdead}, {name:"BEEF" number:0xbeef}]
960 `),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400961 NewEnum: func(n pref.EnumNumber) pref.Enum {
Joe Tsai87b955b2018-11-14 21:59:49 -0800962 return EnumProto2(n)
963 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400964}
Joe Tsai87b955b2018-11-14 21:59:49 -0800965
Joe Tsai0fc49f82019-05-01 12:29:25 -0700966func (e EnumProto2) Descriptor() pref.EnumDescriptor { return enumProto2Type.Descriptor() }
967func (e EnumProto2) Enum() *EnumProto2 { return &e }
968func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Joe Tsai87b955b2018-11-14 21:59:49 -0800969
970type EnumProto3 int32
971
Joe Tsaib2f66be2019-05-22 00:42:45 -0400972var enumProto3Type = &prototype.Enum{
Joe Tsaid8881392019-06-06 13:01:53 -0700973 EnumDescriptor: mustMakeEnumDesc("enum3.proto", pref.Proto3, `
974 name: "EnumProto3",
975 value: [{name:"ALPHA" number:0}, {name:"BRAVO" number:1}]
976 `),
Joe Tsaib2f66be2019-05-22 00:42:45 -0400977 NewEnum: func(n pref.EnumNumber) pref.Enum {
Joe Tsai87b955b2018-11-14 21:59:49 -0800978 return EnumProto3(n)
979 },
Joe Tsaib2f66be2019-05-22 00:42:45 -0400980}
Joe Tsai87b955b2018-11-14 21:59:49 -0800981
Joe Tsai0fc49f82019-05-01 12:29:25 -0700982func (e EnumProto3) Descriptor() pref.EnumDescriptor { return enumProto3Type.Descriptor() }
983func (e EnumProto3) Enum() *EnumProto3 { return &e }
984func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Joe Tsai87b955b2018-11-14 21:59:49 -0800985
986type EnumMessages struct {
987 EnumP2 *EnumProto2 `protobuf:"1"`
988 EnumP3 *EnumProto3 `protobuf:"2"`
989 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
990 MessageCycle *EnumMessages `protobuf:"4"`
991 EnumList []EnumProto2 `protobuf:"5"`
992 MessageList []*ScalarProto2 `protobuf:"6"`
993 EnumMap map[string]EnumProto3 `protobuf:"7"`
994 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
995 Union isEnumMessages_Union `protobuf_oneof:"union"`
996}
997
Joe Tsaib2f66be2019-05-22 00:42:45 -0400998var enumMessagesType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(EnumMessages)), PBType: &prototype.Message{
Joe Tsaid8881392019-06-06 13:01:53 -0700999 MessageDescriptor: mustMakeMessageDesc("enum-messages.proto", pref.Proto2, `
1000 dependency: ["enum2.proto", "enum3.proto", "scalar2.proto", "scalar3.proto", "proto2.v1.0.0-20180125-92554152/test.proto"]
1001 `, `
1002 name: "EnumMessages"
1003 field: [
1004 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto2" default_value:"BEEF"},
1005 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3" default_value:"BRAVO"},
Herbie Ong20aefe92019-06-24 19:21:46 -07001006 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".google.golang.org.proto2_20180125.Message"},
1007 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".EnumMessages"},
Joe Tsaid8881392019-06-06 13:01:53 -07001008 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_ENUM type_name:".EnumProto2"},
1009 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".ScalarProto2"},
1010 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F7Entry"},
1011 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F8Entry"},
1012 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto2" oneof_index:0 default_value:"BEEF"},
1013 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3" oneof_index:0 default_value:"BRAVO"},
1014 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto2" oneof_index:0},
1015 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3" oneof_index:0}
1016 ]
1017 oneof_decl: [{name:"union"}]
1018 nested_type: [
1019 {name:"F7Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3"}] options:{map_entry:true}},
1020 {name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3"}] options:{map_entry:true}}
1021 ]
1022 `, protoregistry.NewFiles(
1023 EnumProto2(0).Descriptor().ParentFile(),
1024 EnumProto3(0).Descriptor().ParentFile(),
1025 ((*ScalarProto2)(nil)).ProtoReflect().Descriptor().ParentFile(),
1026 ((*ScalarProto3)(nil)).ProtoReflect().Descriptor().ParentFile(),
1027 pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message)(nil)).ParentFile(),
1028 )),
Joe Tsaib2f66be2019-05-22 00:42:45 -04001029 NewMessage: func() pref.Message {
Joe Tsai378c1322019-04-25 23:48:08 -07001030 return pref.ProtoMessage(new(EnumMessages)).ProtoReflect()
Joe Tsai87b955b2018-11-14 21:59:49 -08001031 },
Joe Tsaib2f66be2019-05-22 00:42:45 -04001032}}
Joe Tsai87b955b2018-11-14 21:59:49 -08001033
Joe Tsai378c1322019-04-25 23:48:08 -07001034func (m *EnumMessages) ProtoReflect() pref.Message { return enumMessagesType.MessageOf(m) }
Joe Tsai87b955b2018-11-14 21:59:49 -08001035
Joe Tsaif18ab532018-11-27 17:25:04 -08001036func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1037 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001038 (*EnumMessages_OneofE2)(nil),
1039 (*EnumMessages_OneofE3)(nil),
1040 (*EnumMessages_OneofM2)(nil),
1041 (*EnumMessages_OneofM3)(nil),
1042 }
1043}
1044
1045type (
1046 isEnumMessages_Union interface {
1047 isEnumMessages_Union()
1048 }
1049 EnumMessages_OneofE2 struct {
1050 OneofE2 EnumProto2 `protobuf:"9"`
1051 }
1052 EnumMessages_OneofE3 struct {
1053 OneofE3 EnumProto3 `protobuf:"10"`
1054 }
1055 EnumMessages_OneofM2 struct {
1056 OneofM2 *ScalarProto2 `protobuf:"11"`
1057 }
1058 EnumMessages_OneofM3 struct {
1059 OneofM3 *ScalarProto3 `protobuf:"12"`
1060 }
1061)
1062
1063func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1064func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1065func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1066func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1067
1068func TestEnumMessages(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -07001069 emptyL := pimpl.Export{}.MessageOf(new(proto2_20180125.Message))
1070 emptyM := new(EnumMessages).ProtoReflect()
1071 emptyM2 := new(ScalarProto2).ProtoReflect()
1072 emptyM3 := new(ScalarProto3).ProtoReflect()
1073
Joe Tsai08e00302018-11-26 22:32:06 -08001074 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)})
Joe Tsai378c1322019-04-25 23:48:08 -07001075 wantM := (&EnumMessages{EnumP2: EnumProto2(1234).Enum()}).ProtoReflect()
Joe Tsai009e0672018-11-27 18:45:07 -08001076 wantM2a := &ScalarProto2{Float32: scalar.Float32(math.Pi)}
1077 wantM2b := &ScalarProto2{Float32: scalar.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001078 wantM3a := &ScalarProto3{Float32: math.Pi}
1079 wantM3b := &ScalarProto3{Float32: math.Ln2}
1080
Joe Tsai378c1322019-04-25 23:48:08 -07001081 wantList5 := getField((&EnumMessages{EnumList: []EnumProto2{333, 222}}).ProtoReflect(), 5)
1082 wantList6 := getField((&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).ProtoReflect(), 6)
Joe Tsai87b955b2018-11-14 21:59:49 -08001083
Joe Tsai378c1322019-04-25 23:48:08 -07001084 wantMap7 := getField((&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).ProtoReflect(), 7)
1085 wantMap8 := getField((&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).ProtoReflect(), 8)
Joe Tsai87b955b2018-11-14 21:59:49 -08001086
Joe Tsai378c1322019-04-25 23:48:08 -07001087 testMessage(t, nil, new(EnumMessages).ProtoReflect(), messageOps{
Joe Tsai87b955b2018-11-14 21:59:49 -08001088 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 Tsai378c1322019-04-25 23:48:08 -07001089 getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001090
1091 // Test singular enums.
1092 setFields{1: VE(0xdead), 2: VE(0)},
1093 getFields{1: VE(0xdead), 2: VE(0)},
1094 hasFields{1: true, 2: true},
1095
1096 // Test singular messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001097 messageFieldsMutable{3: messageOps{setFields{109: V(float32(math.E))}}},
1098 messageFieldsMutable{4: messageOps{setFields{1: VE(1234)}}},
Joe Tsai87b955b2018-11-14 21:59:49 -08001099 getFields{3: V(wantL), 4: V(wantM)},
1100 clearFields{3, 4},
1101 hasFields{3: false, 4: false},
1102 setFields{3: V(wantL), 4: V(wantM)},
1103 hasFields{3: true, 4: true},
1104
1105 // Test list of enums and messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001106 listFieldsMutable{
Joe Tsai87b955b2018-11-14 21:59:49 -08001107 5: listOps{
1108 appendList{VE(111), VE(222)},
1109 setList{0: VE(333)},
1110 getList{0: VE(333), 1: VE(222)},
1111 lenList(2),
1112 },
1113 6: listOps{
1114 appendMessageList{setFields{4: V(uint32(1e6))}},
1115 appendMessageList{setFields{6: V(float32(math.Phi))}},
Joe Tsai378c1322019-04-25 23:48:08 -07001116 setList{0: V(wantM2a.ProtoReflect())},
1117 getList{0: V(wantM2a.ProtoReflect()), 1: V(wantM2b.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001118 },
1119 },
1120 getFields{5: wantList5, 6: wantList6},
1121 hasFields{5: true, 6: true},
1122 listFields{5: listOps{truncList(0)}},
1123 hasFields{5: false, 6: true},
1124
1125 // Test maps of enums and messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001126 mapFieldsMutable{
Joe Tsai87b955b2018-11-14 21:59:49 -08001127 7: mapOps{
1128 setMap{"one": VE(1), "two": VE(2)},
1129 hasMap{"one": true, "two": true, "three": false},
1130 lenMap(2),
1131 },
1132 8: mapOps{
1133 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
Joe Tsai378c1322019-04-25 23:48:08 -07001134 setMap{"ln2": V(wantM3b.ProtoReflect())},
1135 getMap{"pi": V(wantM3a.ProtoReflect()), "ln2": V(wantM3b.ProtoReflect()), "none": V(nil)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001136 lenMap(2),
1137 },
1138 },
1139 getFields{7: wantMap7, 8: wantMap8},
1140 hasFields{7: true, 8: true},
1141 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1142 hasFields{7: true, 8: false},
1143
1144 // Test oneofs of enums and messages.
1145 setFields{9: VE(0xdead)},
1146 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1147 setFields{10: VE(0)},
1148 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
Joe Tsai378c1322019-04-25 23:48:08 -07001149 messageFieldsMutable{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1150 getFields{11: V(wantM2a.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001151 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
Joe Tsai378c1322019-04-25 23:48:08 -07001152 messageFieldsMutable{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1153 getFields{12: V(wantM3a.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001154 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1155
1156 // Check entire message.
Joe Tsai378c1322019-04-25 23:48:08 -07001157 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a.ProtoReflect())},
1158 equalMessage{(&EnumMessages{
Joe Tsai87b955b2018-11-14 21:59:49 -08001159 EnumP2: EnumProto2(0xdead).Enum(),
1160 EnumP3: EnumProto3(0).Enum(),
Joe Tsai009e0672018-11-27 18:45:07 -08001161 MessageLegacy: &proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)},
Joe Tsai378c1322019-04-25 23:48:08 -07001162 MessageCycle: wantM.Interface().(*EnumMessages),
Joe Tsai87b955b2018-11-14 21:59:49 -08001163 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1164 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1165 Union: &EnumMessages_OneofM3{wantM3a},
Joe Tsai378c1322019-04-25 23:48:08 -07001166 }).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001167 clearFields{1, 2, 3, 4, 6, 7, 12},
Joe Tsai378c1322019-04-25 23:48:08 -07001168 equalMessage{new(EnumMessages).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001169 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001170
1171 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -07001172 testMessage(t, nil, (*EnumMessages)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -08001173 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 Tsai378c1322019-04-25 23:48:08 -07001174 getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1), 11: V(emptyM2), 12: V(emptyM3)},
Joe Tsai6cf80c42018-12-01 04:57:09 -08001175 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1176 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1177 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001178}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001179
Joe Tsai91e14662018-09-13 13:24:35 -07001180var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001181 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
Joe Tsaid8881392019-06-06 13:01:53 -07001182 mx := pimpl.Export{}.MessageOf(x).Interface()
1183 my := pimpl.Export{}.MessageOf(y).Interface()
1184 return proto.Equal(mx, my)
Joe Tsai91e14662018-09-13 13:24:35 -07001185 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001186 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
Joe Tsai378c1322019-04-25 23:48:08 -07001187 switch v := pv.Interface().(type) {
1188 case pref.Message:
1189 out := make(map[pref.FieldNumber]pref.Value)
1190 v.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
1191 out[fd.Number()] = v
1192 return true
1193 })
1194 return out
1195 case pref.List:
1196 var out []pref.Value
1197 for i := 0; i < v.Len(); i++ {
1198 out = append(out, v.Get(i))
1199 }
1200 return out
1201 case pref.Map:
1202 out := make(map[interface{}]pref.Value)
1203 v.Range(func(k pref.MapKey, v pref.Value) bool {
1204 out[k.Interface()] = v
1205 return true
1206 })
1207 return out
1208 default:
1209 return v
1210 }
Joe Tsai91e14662018-09-13 13:24:35 -07001211 }),
1212 cmpopts.EquateNaNs(),
1213}
1214
1215func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
Joe Tsai378c1322019-04-25 23:48:08 -07001216 fieldDescs := m.Descriptor().Fields()
1217 oneofDescs := m.Descriptor().Oneofs()
Joe Tsai91e14662018-09-13 13:24:35 -07001218 for i, op := range tt {
1219 p.Push(i)
1220 switch op := op.(type) {
1221 case equalMessage:
Joe Tsai378c1322019-04-25 23:48:08 -07001222 if diff := cmp.Diff(V(op.Message), V(m), cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001223 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1224 }
1225 case hasFields:
1226 got := map[pref.FieldNumber]bool{}
1227 want := map[pref.FieldNumber]bool(op)
1228 for n := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001229 fd := fieldDescs.ByNumber(n)
1230 got[n] = m.Has(fd)
Joe Tsai91e14662018-09-13 13:24:35 -07001231 }
1232 if diff := cmp.Diff(want, got); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001233 t.Errorf("operation %v, Message.Has mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001234 }
1235 case getFields:
1236 got := map[pref.FieldNumber]pref.Value{}
1237 want := map[pref.FieldNumber]pref.Value(op)
1238 for n := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001239 fd := fieldDescs.ByNumber(n)
1240 got[n] = m.Get(fd)
Joe Tsai91e14662018-09-13 13:24:35 -07001241 }
1242 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001243 t.Errorf("operation %v, Message.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001244 }
1245 case setFields:
1246 for n, v := range op {
Joe Tsai378c1322019-04-25 23:48:08 -07001247 fd := fieldDescs.ByNumber(n)
1248 m.Set(fd, v)
Joe Tsai91e14662018-09-13 13:24:35 -07001249 }
1250 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001251 for _, n := range op {
Joe Tsai378c1322019-04-25 23:48:08 -07001252 fd := fieldDescs.ByNumber(n)
1253 m.Clear(fd)
Joe Tsai87b955b2018-11-14 21:59:49 -08001254 }
Joe Tsai4ec39c72019-04-03 13:40:53 -07001255 case whichOneofs:
1256 got := map[pref.Name]pref.FieldNumber{}
1257 want := map[pref.Name]pref.FieldNumber(op)
1258 for s := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001259 od := oneofDescs.ByName(s)
1260 fd := m.WhichOneof(od)
1261 if fd == nil {
1262 got[s] = 0
1263 } else {
1264 got[s] = fd.Number()
1265 }
Joe Tsai4ec39c72019-04-03 13:40:53 -07001266 }
1267 if diff := cmp.Diff(want, got); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001268 t.Errorf("operation %v, Message.WhichOneof mismatch (-want, +got):\n%s", p, diff)
Joe Tsai4ec39c72019-04-03 13:40:53 -07001269 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001270 case messageFields:
1271 for n, tt := range op {
1272 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001273 fd := fieldDescs.ByNumber(n)
1274 testMessage(t, p, m.Get(fd).Message(), tt)
1275 p.Pop()
1276 }
1277 case messageFieldsMutable:
1278 for n, tt := range op {
1279 p.Push(int(n))
1280 fd := fieldDescs.ByNumber(n)
1281 testMessage(t, p, m.Mutable(fd).Message(), tt)
Joe Tsai87b955b2018-11-14 21:59:49 -08001282 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001283 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001284 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001285 for n, tt := range op {
1286 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001287 fd := fieldDescs.ByNumber(n)
1288 testLists(t, p, m.Get(fd).List(), tt)
1289 p.Pop()
1290 }
1291 case listFieldsMutable:
1292 for n, tt := range op {
1293 p.Push(int(n))
1294 fd := fieldDescs.ByNumber(n)
1295 testLists(t, p, m.Mutable(fd).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001296 p.Pop()
1297 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001298 case mapFields:
1299 for n, tt := range op {
1300 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001301 fd := fieldDescs.ByNumber(n)
1302 testMaps(t, p, m.Get(fd).Map(), tt)
1303 p.Pop()
1304 }
1305 case mapFieldsMutable:
1306 for n, tt := range op {
1307 p.Push(int(n))
1308 fd := fieldDescs.ByNumber(n)
1309 testMaps(t, p, m.Mutable(fd).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001310 p.Pop()
1311 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001312 case rangeFields:
1313 got := map[pref.FieldNumber]pref.Value{}
1314 want := map[pref.FieldNumber]pref.Value(op)
Joe Tsai378c1322019-04-25 23:48:08 -07001315 m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
1316 got[fd.Number()] = v
Joe Tsai87b955b2018-11-14 21:59:49 -08001317 return true
1318 })
1319 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001320 t.Errorf("operation %v, Message.Range mismatch (-want, +got):\n%s", p, diff)
Joe Tsai87b955b2018-11-14 21:59:49 -08001321 }
Joe Tsai91e14662018-09-13 13:24:35 -07001322 default:
1323 t.Fatalf("operation %v, invalid operation: %T", p, op)
1324 }
1325 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001326 }
1327}
Joe Tsai91e14662018-09-13 13:24:35 -07001328
Joe Tsai4b7aff62018-11-14 14:05:19 -08001329func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001330 for i, op := range tt {
1331 p.Push(i)
1332 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001333 case equalList:
Joe Tsai378c1322019-04-25 23:48:08 -07001334 if diff := cmp.Diff(V(op.List), V(v), cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001335 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001336 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001337 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001338 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001339 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001340 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001341 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001342 got := map[int]pref.Value{}
1343 want := map[int]pref.Value(op)
1344 for n := range want {
1345 got[n] = v.Get(n)
1346 }
1347 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001348 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001349 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001350 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001351 for n, e := range op {
1352 v.Set(n, e)
1353 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001354 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001355 for _, e := range op {
1356 v.Append(e)
1357 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001358 case appendMessageList:
Joe Tsai3bc7d6f2019-01-09 02:57:13 -08001359 m := v.NewMessage()
Damien Neil97e7f572018-12-07 14:28:33 -08001360 v.Append(V(m))
1361 testMessage(t, p, m, messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001362 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001363 v.Truncate(int(op))
1364 default:
1365 t.Fatalf("operation %v, invalid operation: %T", p, op)
1366 }
1367 p.Pop()
1368 }
1369}
1370
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001371func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1372 for i, op := range tt {
1373 p.Push(i)
1374 switch op := op.(type) {
1375 case equalMap:
Joe Tsai378c1322019-04-25 23:48:08 -07001376 if diff := cmp.Diff(V(op.Map), V(m), cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001377 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1378 }
1379 case lenMap:
1380 if got, want := m.Len(), int(op); got != want {
1381 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1382 }
1383 case hasMap:
1384 got := map[interface{}]bool{}
1385 want := map[interface{}]bool(op)
1386 for k := range want {
1387 got[k] = m.Has(V(k).MapKey())
1388 }
1389 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1390 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1391 }
1392 case getMap:
1393 got := map[interface{}]pref.Value{}
1394 want := map[interface{}]pref.Value(op)
1395 for k := range want {
1396 got[k] = m.Get(V(k).MapKey())
1397 }
1398 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1399 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1400 }
1401 case setMap:
1402 for k, v := range op {
1403 m.Set(V(k).MapKey(), v)
1404 }
1405 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001406 for _, k := range op {
1407 m.Clear(V(k).MapKey())
1408 }
1409 case messageMap:
1410 for k, tt := range op {
Damien Neil97e7f572018-12-07 14:28:33 -08001411 mk := V(k).MapKey()
1412 if !m.Has(mk) {
1413 m.Set(mk, V(m.NewMessage()))
1414 }
1415 testMessage(t, p, m.Get(mk).Message(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001416 }
1417 case rangeMap:
1418 got := map[interface{}]pref.Value{}
1419 want := map[interface{}]pref.Value(op)
1420 m.Range(func(k pref.MapKey, v pref.Value) bool {
1421 got[k.Interface()] = v
1422 return true
1423 })
1424 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1425 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1426 }
1427 default:
1428 t.Fatalf("operation %v, invalid operation: %T", p, op)
1429 }
1430 p.Pop()
1431 }
1432}
1433
Joe Tsai378c1322019-04-25 23:48:08 -07001434func getField(m pref.Message, n pref.FieldNumber) pref.Value {
1435 fd := m.Descriptor().Fields().ByNumber(n)
1436 return m.Get(fd)
1437}
1438
Joe Tsai91e14662018-09-13 13:24:35 -07001439type path []int
1440
1441func (p *path) Push(i int) { *p = append(*p, i) }
1442func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1443func (p path) String() string {
1444 var ss []string
1445 for _, i := range p {
1446 ss = append(ss, fmt.Sprint(i))
1447 }
1448 return strings.Join(ss, ".")
1449}
Joe Tsai82760ce2019-06-20 03:09:57 -07001450
1451// The MessageState implementation makes the assumption that when a
1452// concrete message is unsafe casted as a *MessageState, the Go GC does
1453// not reclaim the memory for the remainder of the concrete message.
1454func TestUnsafeAssumptions(t *testing.T) {
1455 if !pimpl.UnsafeEnabled {
1456 t.Skip()
1457 }
1458
1459 var wg sync.WaitGroup
1460 for i := 0; i < 10; i++ {
1461 wg.Add(1)
1462 go func() {
1463 var ms [10]pref.Message
1464
1465 // Store the message only in its reflective form.
1466 // Trigger the GC after each iteration.
1467 for j := 0; j < 10; j++ {
1468 ms[j] = (&testpb.TestAllTypes{
1469 OptionalInt32: scalar.Int32(int32(j)),
1470 OptionalFloat: scalar.Float32(float32(j)),
1471 RepeatedInt32: []int32{int32(j)},
1472 RepeatedFloat: []float32{float32(j)},
1473 DefaultInt32: scalar.Int32(int32(j)),
1474 DefaultFloat: scalar.Float32(float32(j)),
1475 }).ProtoReflect()
1476 runtime.GC()
1477 }
1478
1479 // Convert the reflective form back into a concrete form.
1480 // Verify that the values written previously are still the same.
1481 for j := 0; j < 10; j++ {
1482 switch m := ms[j].Interface().(*testpb.TestAllTypes); {
1483 case m.GetOptionalInt32() != int32(j):
1484 case m.GetOptionalFloat() != float32(j):
1485 case m.GetRepeatedInt32()[0] != int32(j):
1486 case m.GetRepeatedFloat()[0] != float32(j):
1487 case m.GetDefaultInt32() != int32(j):
1488 case m.GetDefaultFloat() != float32(j):
1489 default:
1490 continue
1491 }
1492 t.Error("memory corrupted detected")
1493 }
1494 defer wg.Done()
1495 }()
1496 }
1497 wg.Wait()
1498}
1499
1500func BenchmarkName(b *testing.B) {
1501 var sink pref.FullName
1502 b.Run("Value", func(b *testing.B) {
1503 b.ReportAllocs()
1504 m := new(descriptorpb.FileDescriptorProto)
1505 for i := 0; i < b.N; i++ {
1506 sink = m.ProtoReflect().Descriptor().FullName()
1507 }
1508 })
1509 b.Run("Nil", func(b *testing.B) {
1510 b.ReportAllocs()
1511 m := (*descriptorpb.FileDescriptorProto)(nil)
1512 for i := 0; i < b.N; i++ {
1513 sink = m.ProtoReflect().Descriptor().FullName()
1514 }
1515 })
1516 runtime.KeepAlive(sink)
1517}