blob: f1f0671c1aa397e4f2472d7467f497668ca57b3d [file] [log] [blame]
Damien Neilc37adef2019-04-01 13:49:56 -07001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package impl
6
7import (
Damien Neil6e40b322019-10-01 13:05:16 -07008 "fmt"
Damien Neilc37adef2019-04-01 13:49:56 -07009 "reflect"
Joe Tsai6e095992019-08-10 13:56:36 -070010 "sync"
Damien Neilc37adef2019-04-01 13:49:56 -070011
12 "google.golang.org/protobuf/internal/encoding/wire"
Damien Neilc37adef2019-04-01 13:49:56 -070013 "google.golang.org/protobuf/proto"
14 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsai6e095992019-08-10 13:56:36 -070015 preg "google.golang.org/protobuf/reflect/protoregistry"
Damien Neilc37adef2019-04-01 13:49:56 -070016)
17
18type errInvalidUTF8 struct{}
19
20func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
21func (errInvalidUTF8) InvalidUTF8() bool { return true }
22
Damien Neilce413af2019-12-05 16:36:28 -080023// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
24//
25// For size, marshal, and isInit operations, functions are set only on the first field
26// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
27// to the appropriate field-specific function as necessary.
28//
29// The unmarshal function is set on each field individually as usual.
30func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
31 type oneofFieldInfo struct {
32 wiretag uint64 // field tag (number + wire type)
33 tagsize int // size of the varint-encoded tag
34 funcs pointerCoderFuncs
Damien Neil5322bdb2019-04-09 15:57:05 -070035 }
Damien Neilce413af2019-12-05 16:36:28 -080036 fs := si.oneofsByName[od.Name()]
37 ft := fs.Type
38 oneofFields := make(map[reflect.Type]*oneofFieldInfo)
39 needIsInit := false
40 fields := od.Fields()
41 for i, lim := 0, fields.Len(); i < lim; i++ {
42 fd := od.Fields().Get(i)
43 num := fd.Number()
44 cf := mi.coderFields[num]
45 ot := si.oneofWrappersByNumber[num]
46 funcs := fieldCoder(fd, ot.Field(0).Type)
47 oneofFields[ot] = &oneofFieldInfo{
48 wiretag: cf.wiretag,
49 tagsize: cf.tagsize,
50 funcs: funcs,
51 }
52 if funcs.isInit != nil {
53 needIsInit = true
54 }
Damien Neilf0831e82020-01-21 14:25:12 -080055 cf.funcs.unmarshal = func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai6c286742019-07-11 23:15:05 -070056 var vw reflect.Value // pointer to wrapper type
57 vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
58 if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
59 vw = vi.Elem()
60 } else {
61 vw = reflect.New(ot)
62 }
Damien Neilf0831e82020-01-21 14:25:12 -080063 out, err := funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, opts)
Damien Neile91877d2019-06-27 10:54:42 -070064 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -080065 return out, err
Damien Neilc37adef2019-04-01 13:49:56 -070066 }
Joe Tsai6c286742019-07-11 23:15:05 -070067 vi.Set(vw)
Damien Neilf0831e82020-01-21 14:25:12 -080068 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -070069 }
70 }
Damien Neilce413af2019-12-05 16:36:28 -080071 getInfo := func(p pointer) (pointer, *oneofFieldInfo) {
72 v := p.AsValueOf(ft).Elem()
73 if v.IsNil() {
74 return pointer{}, nil
75 }
76 v = v.Elem() // interface -> *struct
77 if v.IsNil() {
78 return pointer{}, nil
79 }
80 return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
81 }
82 first := mi.coderFields[od.Fields().Get(0).Number()]
83 first.funcs.size = func(p pointer, tagsize int, opts marshalOptions) int {
84 p, info := getInfo(p)
85 if info == nil || info.funcs.size == nil {
86 return 0
87 }
88 return info.funcs.size(p, info.tagsize, opts)
89 }
90 first.funcs.marshal = func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
91 p, info := getInfo(p)
92 if info == nil || info.funcs.marshal == nil {
93 return b, nil
94 }
95 return info.funcs.marshal(b, p, info.wiretag, opts)
96 }
97 if needIsInit {
98 first.funcs.isInit = func(p pointer) error {
99 p, info := getInfo(p)
100 if info == nil || info.funcs.isInit == nil {
101 return nil
102 }
103 return info.funcs.isInit(p)
104 }
105 }
Damien Neilc37adef2019-04-01 13:49:56 -0700106}
107
Joe Tsai6e095992019-08-10 13:56:36 -0700108func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
109 var once sync.Once
110 var messageType pref.MessageType
111 lazyInit := func() {
112 once.Do(func() {
113 messageName := fd.Message().FullName()
114 messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
115 })
116 }
117
Damien Neil6e40b322019-10-01 13:05:16 -0700118 num := fd.Number()
Joe Tsai6e095992019-08-10 13:56:36 -0700119 return pointerCoderFuncs{
120 size: func(p pointer, tagsize int, opts marshalOptions) int {
Damien Neil6e40b322019-10-01 13:05:16 -0700121 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700122 if !ok {
123 return 0
124 }
Damien Neil6e40b322019-10-01 13:05:16 -0700125 lazyInit()
126 if messageType == nil {
127 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
128 }
129 return sizeMessage(m, tagsize, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700130 },
131 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil6e40b322019-10-01 13:05:16 -0700132 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700133 if !ok {
134 return b, nil
135 }
Damien Neil6e40b322019-10-01 13:05:16 -0700136 lazyInit()
137 if messageType == nil {
138 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
139 }
140 return appendMessage(b, m, wiretag, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700141 },
Damien Neilf0831e82020-01-21 14:25:12 -0800142 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai6e095992019-08-10 13:56:36 -0700143 fs := p.WeakFields()
Damien Neil6e40b322019-10-01 13:05:16 -0700144 m, ok := fs.get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700145 if !ok {
146 lazyInit()
147 if messageType == nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800148 return unmarshalOutput{}, errUnknown
Joe Tsai6e095992019-08-10 13:56:36 -0700149 }
Damien Neil6e40b322019-10-01 13:05:16 -0700150 m = messageType.New().Interface()
151 fs.set(num, m)
Joe Tsai6e095992019-08-10 13:56:36 -0700152 }
Damien Neil6e40b322019-10-01 13:05:16 -0700153 return consumeMessage(b, m, wtyp, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700154 },
155 isInit: func(p pointer) error {
Damien Neil6e40b322019-10-01 13:05:16 -0700156 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700157 if !ok {
158 return nil
159 }
Damien Neil6e40b322019-10-01 13:05:16 -0700160 return proto.IsInitialized(m)
Joe Tsai6e095992019-08-10 13:56:36 -0700161 },
162 }
163}
164
Damien Neilc37adef2019-04-01 13:49:56 -0700165func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai070c1012019-07-26 23:45:58 -0700166 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800167 funcs := pointerCoderFuncs{
Damien Neilc37adef2019-04-01 13:49:56 -0700168 size: func(p pointer, tagsize int, opts marshalOptions) int {
Joe Tsai070c1012019-07-26 23:45:58 -0700169 return sizeMessageInfo(p, mi, tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700170 },
171 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700172 return appendMessageInfo(b, p, wiretag, mi, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700173 },
Damien Neilf0831e82020-01-21 14:25:12 -0800174 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700175 return consumeMessageInfo(b, p, mi, wtyp, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700176 },
Damien Neilc37adef2019-04-01 13:49:56 -0700177 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800178 if needsInitCheck(mi.Desc) {
179 funcs.isInit = func(p pointer) error {
180 return mi.isInitializedPointer(p.Elem())
181 }
182 }
183 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700184 } else {
185 return pointerCoderFuncs{
186 size: func(p pointer, tagsize int, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -0700187 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700188 return sizeMessage(m, tagsize, opts)
189 },
190 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -0700191 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700192 return appendMessage(b, m, wiretag, opts)
193 },
Damien Neilf0831e82020-01-21 14:25:12 -0800194 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700195 mp := p.AsValueOf(ft).Elem()
196 if mp.IsNil() {
197 mp.Set(reflect.New(ft.Elem()))
198 }
199 return consumeMessage(b, asMessage(mp), wtyp, opts)
200 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700201 isInit: func(p pointer) error {
202 m := asMessage(p.AsValueOf(ft).Elem())
203 return proto.IsInitialized(m)
204 },
Damien Neilc37adef2019-04-01 13:49:56 -0700205 }
206 }
207}
208
Joe Tsai4fe96632019-05-22 05:12:36 -0400209func sizeMessageInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700210 return wire.SizeBytes(mi.sizePointer(p.Elem(), opts)) + tagsize
211}
212
Joe Tsai4fe96632019-05-22 05:12:36 -0400213func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700214 b = wire.AppendVarint(b, wiretag)
215 b = wire.AppendVarint(b, uint64(mi.sizePointer(p.Elem(), opts)))
216 return mi.marshalAppendPointer(b, p.Elem(), opts)
217}
218
Damien Neilf0831e82020-01-21 14:25:12 -0800219func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700220 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800221 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700222 }
223 v, n := wire.ConsumeBytes(b)
224 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800225 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700226 }
227 if p.Elem().IsNil() {
Damien Neil16163b42019-08-06 15:43:25 -0700228 p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
Damien Neile91877d2019-06-27 10:54:42 -0700229 }
230 if _, err := mi.unmarshalPointer(v, p.Elem(), 0, opts); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800231 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700232 }
Damien Neilf0831e82020-01-21 14:25:12 -0800233 out.n = n
234 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700235}
236
Damien Neilc37adef2019-04-01 13:49:56 -0700237func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
238 return wire.SizeBytes(proto.Size(m)) + tagsize
239}
240
241func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
242 b = wire.AppendVarint(b, wiretag)
243 b = wire.AppendVarint(b, uint64(proto.Size(m)))
244 return opts.Options().MarshalAppend(b, m)
245}
246
Damien Neilf0831e82020-01-21 14:25:12 -0800247func consumeMessage(b []byte, m proto.Message, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700248 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800249 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700250 }
251 v, n := wire.ConsumeBytes(b)
252 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800253 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700254 }
255 if err := opts.Options().Unmarshal(v, m); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800256 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700257 }
Damien Neilf0831e82020-01-21 14:25:12 -0800258 out.n = n
259 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700260}
261
Damien Neil68b81c32019-08-22 11:41:32 -0700262func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
263 m := v.Message().Interface()
Damien Neilc37adef2019-04-01 13:49:56 -0700264 return sizeMessage(m, tagsize, opts)
265}
266
Damien Neil68b81c32019-08-22 11:41:32 -0700267func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
268 m := v.Message().Interface()
Damien Neilc37adef2019-04-01 13:49:56 -0700269 return appendMessage(b, m, wiretag, opts)
270}
271
Damien Neilf0831e82020-01-21 14:25:12 -0800272func consumeMessageValue(b []byte, v pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
Damien Neil68b81c32019-08-22 11:41:32 -0700273 m := v.Message().Interface()
Damien Neilf0831e82020-01-21 14:25:12 -0800274 out, err := consumeMessage(b, m, wtyp, opts)
275 return v, out, err
Damien Neile91877d2019-06-27 10:54:42 -0700276}
277
Damien Neil68b81c32019-08-22 11:41:32 -0700278func isInitMessageValue(v pref.Value) error {
279 m := v.Message().Interface()
Damien Neil5322bdb2019-04-09 15:57:05 -0700280 return proto.IsInitialized(m)
281}
282
Damien Neil68b81c32019-08-22 11:41:32 -0700283var coderMessageValue = valueCoderFuncs{
284 size: sizeMessageValue,
285 marshal: appendMessageValue,
286 unmarshal: consumeMessageValue,
287 isInit: isInitMessageValue,
288}
289
290func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int {
291 m := v.Message().Interface()
292 return sizeGroup(m, tagsize, opts)
293}
294
295func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
296 m := v.Message().Interface()
297 return appendGroup(b, m, wiretag, opts)
298}
299
Damien Neilf0831e82020-01-21 14:25:12 -0800300func consumeGroupValue(b []byte, v pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
Damien Neil68b81c32019-08-22 11:41:32 -0700301 m := v.Message().Interface()
Damien Neilf0831e82020-01-21 14:25:12 -0800302 out, err := consumeGroup(b, m, num, wtyp, opts)
303 return v, out, err
Damien Neil68b81c32019-08-22 11:41:32 -0700304}
305
306var coderGroupValue = valueCoderFuncs{
307 size: sizeGroupValue,
308 marshal: appendGroupValue,
309 unmarshal: consumeGroupValue,
310 isInit: isInitMessageValue,
Damien Neilc37adef2019-04-01 13:49:56 -0700311}
312
313func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Damien Neile91877d2019-06-27 10:54:42 -0700314 num := fd.Number()
Joe Tsai070c1012019-07-26 23:45:58 -0700315 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800316 funcs := pointerCoderFuncs{
Damien Neilc37adef2019-04-01 13:49:56 -0700317 size: func(p pointer, tagsize int, opts marshalOptions) int {
Joe Tsai070c1012019-07-26 23:45:58 -0700318 return sizeGroupType(p, mi, tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700319 },
320 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700321 return appendGroupType(b, p, wiretag, mi, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700322 },
Damien Neilf0831e82020-01-21 14:25:12 -0800323 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700324 return consumeGroupType(b, p, mi, num, wtyp, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700325 },
Damien Neilc37adef2019-04-01 13:49:56 -0700326 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800327 if needsInitCheck(mi.Desc) {
328 funcs.isInit = func(p pointer) error {
329 return mi.isInitializedPointer(p.Elem())
330 }
331 }
332 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700333 } else {
334 return pointerCoderFuncs{
335 size: func(p pointer, tagsize int, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -0700336 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700337 return sizeGroup(m, tagsize, opts)
338 },
339 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -0700340 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700341 return appendGroup(b, m, wiretag, opts)
342 },
Damien Neilf0831e82020-01-21 14:25:12 -0800343 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700344 mp := p.AsValueOf(ft).Elem()
345 if mp.IsNil() {
346 mp.Set(reflect.New(ft.Elem()))
347 }
348 return consumeGroup(b, asMessage(mp), num, wtyp, opts)
349 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700350 isInit: func(p pointer) error {
351 m := asMessage(p.AsValueOf(ft).Elem())
352 return proto.IsInitialized(m)
353 },
Damien Neilc37adef2019-04-01 13:49:56 -0700354 }
355 }
356}
357
Joe Tsai4fe96632019-05-22 05:12:36 -0400358func sizeGroupType(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700359 return 2*tagsize + mi.sizePointer(p.Elem(), opts)
360}
361
Joe Tsai4fe96632019-05-22 05:12:36 -0400362func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700363 b = wire.AppendVarint(b, wiretag) // start group
364 b, err := mi.marshalAppendPointer(b, p.Elem(), opts)
365 b = wire.AppendVarint(b, wiretag+1) // end group
366 return b, err
367}
368
Damien Neilf0831e82020-01-21 14:25:12 -0800369func consumeGroupType(b []byte, p pointer, mi *MessageInfo, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700370 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800371 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700372 }
373 if p.Elem().IsNil() {
Damien Neil16163b42019-08-06 15:43:25 -0700374 p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
Damien Neile91877d2019-06-27 10:54:42 -0700375 }
376 return mi.unmarshalPointer(b, p.Elem(), num, opts)
377}
378
Damien Neilc37adef2019-04-01 13:49:56 -0700379func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
380 return 2*tagsize + proto.Size(m)
381}
382
383func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
384 b = wire.AppendVarint(b, wiretag) // start group
385 b, err := opts.Options().MarshalAppend(b, m)
386 b = wire.AppendVarint(b, wiretag+1) // end group
387 return b, err
388}
389
Damien Neilf0831e82020-01-21 14:25:12 -0800390func consumeGroup(b []byte, m proto.Message, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700391 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800392 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700393 }
394 b, n := wire.ConsumeGroup(num, b)
395 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800396 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700397 }
Damien Neilf0831e82020-01-21 14:25:12 -0800398 out.n = n
399 return out, opts.Options().Unmarshal(b, m)
Damien Neilc37adef2019-04-01 13:49:56 -0700400}
401
Damien Neilc37adef2019-04-01 13:49:56 -0700402func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai070c1012019-07-26 23:45:58 -0700403 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800404 funcs := pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700405 size: func(p pointer, tagsize int, opts marshalOptions) int {
Joe Tsai070c1012019-07-26 23:45:58 -0700406 return sizeMessageSliceInfo(p, mi, tagsize, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700407 },
Damien Neilc37adef2019-04-01 13:49:56 -0700408 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700409 return appendMessageSliceInfo(b, p, wiretag, mi, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700410 },
Damien Neilf0831e82020-01-21 14:25:12 -0800411 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700412 return consumeMessageSliceInfo(b, p, mi, wtyp, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700413 },
414 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800415 if needsInitCheck(mi.Desc) {
416 funcs.isInit = func(p pointer) error {
417 return isInitMessageSliceInfo(p, mi)
418 }
419 }
420 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700421 }
422 return pointerCoderFuncs{
423 size: func(p pointer, tagsize int, opts marshalOptions) int {
424 return sizeMessageSlice(p, ft, tagsize, opts)
425 },
426 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
427 return appendMessageSlice(b, p, wiretag, ft, opts)
428 },
Damien Neilf0831e82020-01-21 14:25:12 -0800429 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700430 return consumeMessageSlice(b, p, ft, wtyp, opts)
431 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700432 isInit: func(p pointer) error {
433 return isInitMessageSlice(p, ft)
434 },
Damien Neilc37adef2019-04-01 13:49:56 -0700435 }
436}
437
Joe Tsai4fe96632019-05-22 05:12:36 -0400438func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700439 s := p.PointerSlice()
440 n := 0
441 for _, v := range s {
442 n += wire.SizeBytes(mi.sizePointer(v, opts)) + tagsize
443 }
444 return n
445}
446
Joe Tsai4fe96632019-05-22 05:12:36 -0400447func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700448 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700449 var err error
450 for _, v := range s {
451 b = wire.AppendVarint(b, wiretag)
452 siz := mi.sizePointer(v, opts)
453 b = wire.AppendVarint(b, uint64(siz))
454 b, err = mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700455 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700456 return b, err
457 }
458 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700459 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700460}
461
Damien Neilf0831e82020-01-21 14:25:12 -0800462func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700463 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800464 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700465 }
466 v, n := wire.ConsumeBytes(b)
467 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800468 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700469 }
Damien Neil16163b42019-08-06 15:43:25 -0700470 m := reflect.New(mi.GoReflectType.Elem()).Interface()
Damien Neile91877d2019-06-27 10:54:42 -0700471 mp := pointerOfIface(m)
472 if _, err := mi.unmarshalPointer(v, mp, 0, opts); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800473 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700474 }
475 p.AppendPointerSlice(mp)
Damien Neilf0831e82020-01-21 14:25:12 -0800476 out.n = n
477 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700478}
479
Damien Neil5322bdb2019-04-09 15:57:05 -0700480func isInitMessageSliceInfo(p pointer, mi *MessageInfo) error {
481 s := p.PointerSlice()
482 for _, v := range s {
483 if err := mi.isInitializedPointer(v); err != nil {
484 return err
485 }
486 }
487 return nil
488}
489
Damien Neilc37adef2019-04-01 13:49:56 -0700490func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
491 s := p.PointerSlice()
492 n := 0
493 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700494 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700495 n += wire.SizeBytes(proto.Size(m)) + tagsize
496 }
497 return n
498}
499
500func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
501 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700502 var err error
503 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700504 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700505 b = wire.AppendVarint(b, wiretag)
506 siz := proto.Size(m)
507 b = wire.AppendVarint(b, uint64(siz))
508 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700509 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700510 return b, err
511 }
512 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700513 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700514}
515
Damien Neilf0831e82020-01-21 14:25:12 -0800516func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700517 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800518 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700519 }
520 v, n := wire.ConsumeBytes(b)
521 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800522 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700523 }
524 mp := reflect.New(goType.Elem())
525 if err := opts.Options().Unmarshal(v, asMessage(mp)); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800526 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700527 }
528 p.AppendPointerSlice(pointerOfValue(mp))
Damien Neilf0831e82020-01-21 14:25:12 -0800529 out.n = n
530 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700531}
532
Damien Neil5322bdb2019-04-09 15:57:05 -0700533func isInitMessageSlice(p pointer, goType reflect.Type) error {
534 s := p.PointerSlice()
535 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700536 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neil5322bdb2019-04-09 15:57:05 -0700537 if err := proto.IsInitialized(m); err != nil {
538 return err
539 }
540 }
541 return nil
542}
543
Damien Neilc37adef2019-04-01 13:49:56 -0700544// Slices of messages
545
Damien Neil68b81c32019-08-22 11:41:32 -0700546func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
547 list := listv.List()
548 n := 0
549 for i, llen := 0, list.Len(); i < llen; i++ {
550 m := list.Get(i).Message().Interface()
551 n += wire.SizeBytes(proto.Size(m)) + tagsize
552 }
553 return n
Damien Neilc37adef2019-04-01 13:49:56 -0700554}
555
Damien Neil68b81c32019-08-22 11:41:32 -0700556func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
557 list := listv.List()
558 mopts := opts.Options()
559 for i, llen := 0, list.Len(); i < llen; i++ {
560 m := list.Get(i).Message().Interface()
561 b = wire.AppendVarint(b, wiretag)
562 siz := proto.Size(m)
563 b = wire.AppendVarint(b, uint64(siz))
564 var err error
565 b, err = mopts.MarshalAppend(b, m)
566 if err != nil {
567 return b, err
568 }
569 }
570 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700571}
572
Damien Neilf0831e82020-01-21 14:25:12 -0800573func consumeMessageSliceValue(b []byte, listv pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
Damien Neil68b81c32019-08-22 11:41:32 -0700574 list := listv.List()
575 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800576 return pref.Value{}, out, errUnknown
Damien Neil68b81c32019-08-22 11:41:32 -0700577 }
578 v, n := wire.ConsumeBytes(b)
579 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800580 return pref.Value{}, out, wire.ParseError(n)
Damien Neil68b81c32019-08-22 11:41:32 -0700581 }
582 m := list.NewElement()
583 if err := opts.Options().Unmarshal(v, m.Message().Interface()); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800584 return pref.Value{}, out, err
Damien Neil68b81c32019-08-22 11:41:32 -0700585 }
586 list.Append(m)
Damien Neilf0831e82020-01-21 14:25:12 -0800587 out.n = n
588 return listv, out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700589}
590
Damien Neil68b81c32019-08-22 11:41:32 -0700591func isInitMessageSliceValue(listv pref.Value) error {
592 list := listv.List()
593 for i, llen := 0, list.Len(); i < llen; i++ {
594 m := list.Get(i).Message().Interface()
595 if err := proto.IsInitialized(m); err != nil {
596 return err
597 }
598 }
599 return nil
Damien Neil5322bdb2019-04-09 15:57:05 -0700600}
601
Damien Neil68b81c32019-08-22 11:41:32 -0700602var coderMessageSliceValue = valueCoderFuncs{
603 size: sizeMessageSliceValue,
604 marshal: appendMessageSliceValue,
605 unmarshal: consumeMessageSliceValue,
606 isInit: isInitMessageSliceValue,
607}
608
609func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
610 list := listv.List()
611 n := 0
612 for i, llen := 0, list.Len(); i < llen; i++ {
613 m := list.Get(i).Message().Interface()
614 n += 2*tagsize + proto.Size(m)
615 }
616 return n
617}
618
619func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
620 list := listv.List()
621 mopts := opts.Options()
622 for i, llen := 0, list.Len(); i < llen; i++ {
623 m := list.Get(i).Message().Interface()
624 b = wire.AppendVarint(b, wiretag) // start group
625 var err error
626 b, err = mopts.MarshalAppend(b, m)
627 if err != nil {
628 return b, err
629 }
630 b = wire.AppendVarint(b, wiretag+1) // end group
631 }
632 return b, nil
633}
634
Damien Neilf0831e82020-01-21 14:25:12 -0800635func consumeGroupSliceValue(b []byte, listv pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
Damien Neil68b81c32019-08-22 11:41:32 -0700636 list := listv.List()
637 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800638 return pref.Value{}, out, errUnknown
Damien Neil68b81c32019-08-22 11:41:32 -0700639 }
640 b, n := wire.ConsumeGroup(num, b)
641 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800642 return pref.Value{}, out, wire.ParseError(n)
Damien Neil68b81c32019-08-22 11:41:32 -0700643 }
644 m := list.NewElement()
645 if err := opts.Options().Unmarshal(b, m.Message().Interface()); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800646 return pref.Value{}, out, err
Damien Neil68b81c32019-08-22 11:41:32 -0700647 }
648 list.Append(m)
Damien Neilf0831e82020-01-21 14:25:12 -0800649 out.n = n
650 return listv, out, nil
Damien Neil68b81c32019-08-22 11:41:32 -0700651}
652
653var coderGroupSliceValue = valueCoderFuncs{
654 size: sizeGroupSliceValue,
655 marshal: appendGroupSliceValue,
656 unmarshal: consumeGroupSliceValue,
657 isInit: isInitMessageSliceValue,
Damien Neilc37adef2019-04-01 13:49:56 -0700658}
659
660func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Damien Neile91877d2019-06-27 10:54:42 -0700661 num := fd.Number()
Joe Tsai070c1012019-07-26 23:45:58 -0700662 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800663 funcs := pointerCoderFuncs{
Damien Neilc37adef2019-04-01 13:49:56 -0700664 size: func(p pointer, tagsize int, opts marshalOptions) int {
Joe Tsai070c1012019-07-26 23:45:58 -0700665 return sizeGroupSliceInfo(p, mi, tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700666 },
667 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700668 return appendGroupSliceInfo(b, p, wiretag, mi, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700669 },
Damien Neilf0831e82020-01-21 14:25:12 -0800670 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai070c1012019-07-26 23:45:58 -0700671 return consumeGroupSliceInfo(b, p, num, wtyp, mi, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700672 },
Damien Neilc37adef2019-04-01 13:49:56 -0700673 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800674 if needsInitCheck(mi.Desc) {
675 funcs.isInit = func(p pointer) error {
676 return isInitMessageSliceInfo(p, mi)
677 }
678 }
679 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700680 }
681 return pointerCoderFuncs{
682 size: func(p pointer, tagsize int, opts marshalOptions) int {
683 return sizeGroupSlice(p, ft, tagsize, opts)
684 },
685 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
686 return appendGroupSlice(b, p, wiretag, ft, opts)
687 },
Damien Neilf0831e82020-01-21 14:25:12 -0800688 unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700689 return consumeGroupSlice(b, p, num, wtyp, ft, opts)
690 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700691 isInit: func(p pointer) error {
692 return isInitMessageSlice(p, ft)
693 },
Damien Neilc37adef2019-04-01 13:49:56 -0700694 }
695}
696
697func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
698 s := p.PointerSlice()
699 n := 0
700 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700701 m := asMessage(v.AsValueOf(messageType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700702 n += 2*tagsize + proto.Size(m)
703 }
704 return n
705}
706
707func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
708 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700709 var err error
710 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700711 m := asMessage(v.AsValueOf(messageType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700712 b = wire.AppendVarint(b, wiretag) // start group
713 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700714 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700715 return b, err
716 }
717 b = wire.AppendVarint(b, wiretag+1) // end group
718 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700719 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700720}
721
Damien Neilf0831e82020-01-21 14:25:12 -0800722func consumeGroupSlice(b []byte, p pointer, num wire.Number, wtyp wire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700723 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800724 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700725 }
726 b, n := wire.ConsumeGroup(num, b)
727 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800728 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700729 }
730 mp := reflect.New(goType.Elem())
731 if err := opts.Options().Unmarshal(b, asMessage(mp)); err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800732 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700733 }
734 p.AppendPointerSlice(pointerOfValue(mp))
Damien Neilf0831e82020-01-21 14:25:12 -0800735 out.n = n
736 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700737}
738
Joe Tsai4fe96632019-05-22 05:12:36 -0400739func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700740 s := p.PointerSlice()
741 n := 0
742 for _, v := range s {
743 n += 2*tagsize + mi.sizePointer(v, opts)
744 }
745 return n
746}
747
Joe Tsai4fe96632019-05-22 05:12:36 -0400748func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700749 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700750 var err error
751 for _, v := range s {
752 b = wire.AppendVarint(b, wiretag) // start group
753 b, err = mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700754 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700755 return b, err
756 }
757 b = wire.AppendVarint(b, wiretag+1) // end group
758 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700759 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700760}
761
Damien Neilf0831e82020-01-21 14:25:12 -0800762func consumeGroupSliceInfo(b []byte, p pointer, num wire.Number, wtyp wire.Type, mi *MessageInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700763 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800764 return unmarshalOutput{}, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700765 }
Damien Neil16163b42019-08-06 15:43:25 -0700766 m := reflect.New(mi.GoReflectType.Elem()).Interface()
Damien Neile91877d2019-06-27 10:54:42 -0700767 mp := pointerOfIface(m)
Damien Neilf0831e82020-01-21 14:25:12 -0800768 out, err := mi.unmarshalPointer(b, mp, num, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700769 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800770 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700771 }
772 p.AppendPointerSlice(mp)
Damien Neilf0831e82020-01-21 14:25:12 -0800773 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700774}
775
Damien Neil5b6d0472019-06-14 11:54:07 -0700776func asMessage(v reflect.Value) pref.ProtoMessage {
777 if m, ok := v.Interface().(pref.ProtoMessage); ok {
778 return m
779 }
780 return legacyWrapMessage(v)
781}