blob: dd6a8a1c67b3d1a1885681918b884440cd85d6c4 [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 Neilc600d6c2020-01-21 15:00:33 -080016 piface "google.golang.org/protobuf/runtime/protoiface"
Damien Neilc37adef2019-04-01 13:49:56 -070017)
18
19type errInvalidUTF8 struct{}
20
21func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
22func (errInvalidUTF8) InvalidUTF8() bool { return true }
23
Damien Neilce413af2019-12-05 16:36:28 -080024// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
25//
26// For size, marshal, and isInit operations, functions are set only on the first field
27// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
28// to the appropriate field-specific function as necessary.
29//
30// The unmarshal function is set on each field individually as usual.
31func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
Damien Neilce413af2019-12-05 16:36:28 -080032 fs := si.oneofsByName[od.Name()]
33 ft := fs.Type
Damien Neil316febd2020-02-09 12:26:50 -080034 oneofFields := make(map[reflect.Type]*coderFieldInfo)
Damien Neilce413af2019-12-05 16:36:28 -080035 needIsInit := false
36 fields := od.Fields()
37 for i, lim := 0, fields.Len(); i < lim; i++ {
38 fd := od.Fields().Get(i)
39 num := fd.Number()
Damien Neil316febd2020-02-09 12:26:50 -080040 // Make a copy of the original coderFieldInfo for use in unmarshaling.
41 //
42 // oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
43 //
44 // mi.coderFields[num].marshal is set on only the first field in the oneof,
45 // and dispatches to the field-specific marshaler in oneofFields.
46 cf := *mi.coderFields[num]
Damien Neilce413af2019-12-05 16:36:28 -080047 ot := si.oneofWrappersByNumber[num]
Damien Neil316febd2020-02-09 12:26:50 -080048 cf.mi, cf.funcs = fieldCoder(fd, ot.Field(0).Type)
49 oneofFields[ot] = &cf
50 if cf.funcs.isInit != nil {
Damien Neilce413af2019-12-05 16:36:28 -080051 needIsInit = true
52 }
Damien Neil316febd2020-02-09 12:26:50 -080053 mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai6c286742019-07-11 23:15:05 -070054 var vw reflect.Value // pointer to wrapper type
55 vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
56 if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
57 vw = vi.Elem()
58 } else {
59 vw = reflect.New(ot)
60 }
Damien Neil316febd2020-02-09 12:26:50 -080061 out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
Damien Neile91877d2019-06-27 10:54:42 -070062 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -080063 return out, err
Damien Neilc37adef2019-04-01 13:49:56 -070064 }
Joe Tsai6c286742019-07-11 23:15:05 -070065 vi.Set(vw)
Damien Neilf0831e82020-01-21 14:25:12 -080066 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -070067 }
68 }
Damien Neil316febd2020-02-09 12:26:50 -080069 getInfo := func(p pointer) (pointer, *coderFieldInfo) {
Damien Neilce413af2019-12-05 16:36:28 -080070 v := p.AsValueOf(ft).Elem()
71 if v.IsNil() {
72 return pointer{}, nil
73 }
74 v = v.Elem() // interface -> *struct
75 if v.IsNil() {
76 return pointer{}, nil
77 }
78 return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
79 }
80 first := mi.coderFields[od.Fields().Get(0).Number()]
Damien Neil316febd2020-02-09 12:26:50 -080081 first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
Damien Neilce413af2019-12-05 16:36:28 -080082 p, info := getInfo(p)
83 if info == nil || info.funcs.size == nil {
84 return 0
85 }
Damien Neil316febd2020-02-09 12:26:50 -080086 return info.funcs.size(p, info, opts)
Damien Neilce413af2019-12-05 16:36:28 -080087 }
Damien Neil316febd2020-02-09 12:26:50 -080088 first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neilce413af2019-12-05 16:36:28 -080089 p, info := getInfo(p)
90 if info == nil || info.funcs.marshal == nil {
91 return b, nil
92 }
Damien Neil316febd2020-02-09 12:26:50 -080093 return info.funcs.marshal(b, p, info, opts)
Damien Neilce413af2019-12-05 16:36:28 -080094 }
95 if needIsInit {
Damien Neil316febd2020-02-09 12:26:50 -080096 first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
Damien Neilce413af2019-12-05 16:36:28 -080097 p, info := getInfo(p)
98 if info == nil || info.funcs.isInit == nil {
99 return nil
100 }
Damien Neil316febd2020-02-09 12:26:50 -0800101 return info.funcs.isInit(p, info)
Damien Neilce413af2019-12-05 16:36:28 -0800102 }
103 }
Damien Neilc37adef2019-04-01 13:49:56 -0700104}
105
Joe Tsai6e095992019-08-10 13:56:36 -0700106func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
107 var once sync.Once
108 var messageType pref.MessageType
109 lazyInit := func() {
110 once.Do(func() {
111 messageName := fd.Message().FullName()
112 messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
113 })
114 }
115
Damien Neil6e40b322019-10-01 13:05:16 -0700116 num := fd.Number()
Joe Tsai6e095992019-08-10 13:56:36 -0700117 return pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800118 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
Damien Neil6e40b322019-10-01 13:05:16 -0700119 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700120 if !ok {
121 return 0
122 }
Damien Neil6e40b322019-10-01 13:05:16 -0700123 lazyInit()
124 if messageType == nil {
125 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
126 }
Damien Neil316febd2020-02-09 12:26:50 -0800127 return sizeMessage(m, f.tagsize, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700128 },
Damien Neil316febd2020-02-09 12:26:50 -0800129 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neil6e40b322019-10-01 13:05:16 -0700130 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700131 if !ok {
132 return b, nil
133 }
Damien Neil6e40b322019-10-01 13:05:16 -0700134 lazyInit()
135 if messageType == nil {
136 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
137 }
Damien Neil316febd2020-02-09 12:26:50 -0800138 return appendMessage(b, m, f.wiretag, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700139 },
Damien Neil316febd2020-02-09 12:26:50 -0800140 unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Joe Tsai6e095992019-08-10 13:56:36 -0700141 fs := p.WeakFields()
Damien Neil6e40b322019-10-01 13:05:16 -0700142 m, ok := fs.get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700143 if !ok {
144 lazyInit()
145 if messageType == nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800146 return unmarshalOutput{}, errUnknown
Joe Tsai6e095992019-08-10 13:56:36 -0700147 }
Damien Neil6e40b322019-10-01 13:05:16 -0700148 m = messageType.New().Interface()
149 fs.set(num, m)
Joe Tsai6e095992019-08-10 13:56:36 -0700150 }
Damien Neil6e40b322019-10-01 13:05:16 -0700151 return consumeMessage(b, m, wtyp, opts)
Joe Tsai6e095992019-08-10 13:56:36 -0700152 },
Damien Neil316febd2020-02-09 12:26:50 -0800153 isInit: func(p pointer, f *coderFieldInfo) error {
Damien Neil6e40b322019-10-01 13:05:16 -0700154 m, ok := p.WeakFields().get(num)
Joe Tsai6e095992019-08-10 13:56:36 -0700155 if !ok {
156 return nil
157 }
Damien Neil6e40b322019-10-01 13:05:16 -0700158 return proto.IsInitialized(m)
Joe Tsai6e095992019-08-10 13:56:36 -0700159 },
160 }
161}
162
Damien Neilc37adef2019-04-01 13:49:56 -0700163func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai070c1012019-07-26 23:45:58 -0700164 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800165 funcs := pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800166 size: sizeMessageInfo,
167 marshal: appendMessageInfo,
168 unmarshal: consumeMessageInfo,
Damien Neilc37adef2019-04-01 13:49:56 -0700169 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800170 if needsInitCheck(mi.Desc) {
Damien Neil316febd2020-02-09 12:26:50 -0800171 funcs.isInit = isInitMessageInfo
Damien Neil7abc2de2020-01-09 14:13:57 -0800172 }
173 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700174 } else {
175 return pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800176 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -0700177 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neil316febd2020-02-09 12:26:50 -0800178 return sizeMessage(m, f.tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700179 },
Damien Neil316febd2020-02-09 12:26:50 -0800180 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -0700181 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neil316febd2020-02-09 12:26:50 -0800182 return appendMessage(b, m, f.wiretag, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700183 },
Damien Neil316febd2020-02-09 12:26:50 -0800184 unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700185 mp := p.AsValueOf(ft).Elem()
186 if mp.IsNil() {
187 mp.Set(reflect.New(ft.Elem()))
188 }
189 return consumeMessage(b, asMessage(mp), wtyp, opts)
190 },
Damien Neil316febd2020-02-09 12:26:50 -0800191 isInit: func(p pointer, f *coderFieldInfo) error {
Damien Neil5322bdb2019-04-09 15:57:05 -0700192 m := asMessage(p.AsValueOf(ft).Elem())
193 return proto.IsInitialized(m)
194 },
Damien Neilc37adef2019-04-01 13:49:56 -0700195 }
196 }
197}
198
Damien Neil316febd2020-02-09 12:26:50 -0800199func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
200 return wire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
Damien Neilc37adef2019-04-01 13:49:56 -0700201}
202
Damien Neil316febd2020-02-09 12:26:50 -0800203func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
204 b = wire.AppendVarint(b, f.wiretag)
205 b = wire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
206 return f.mi.marshalAppendPointer(b, p.Elem(), opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700207}
208
Damien Neil316febd2020-02-09 12:26:50 -0800209func consumeMessageInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700210 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800211 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700212 }
213 v, n := wire.ConsumeBytes(b)
214 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800215 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700216 }
217 if p.Elem().IsNil() {
Damien Neil316febd2020-02-09 12:26:50 -0800218 p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
Damien Neile91877d2019-06-27 10:54:42 -0700219 }
Damien Neil316febd2020-02-09 12:26:50 -0800220 o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
Damien Neilc600d6c2020-01-21 15:00:33 -0800221 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800222 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700223 }
Damien Neilf0831e82020-01-21 14:25:12 -0800224 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800225 out.initialized = o.initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800226 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700227}
228
Damien Neil316febd2020-02-09 12:26:50 -0800229func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
230 return f.mi.isInitializedPointer(p.Elem())
231}
232
Damien Neilc37adef2019-04-01 13:49:56 -0700233func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
234 return wire.SizeBytes(proto.Size(m)) + tagsize
235}
236
237func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
238 b = wire.AppendVarint(b, wiretag)
239 b = wire.AppendVarint(b, uint64(proto.Size(m)))
240 return opts.Options().MarshalAppend(b, m)
241}
242
Damien Neilf0831e82020-01-21 14:25:12 -0800243func consumeMessage(b []byte, m proto.Message, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700244 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800245 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700246 }
247 v, n := wire.ConsumeBytes(b)
248 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800249 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700250 }
Damien Neilc600d6c2020-01-21 15:00:33 -0800251 o, err := opts.Options().UnmarshalState(m, piface.UnmarshalInput{
252 Buf: v,
253 })
254 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800255 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700256 }
Damien Neilf0831e82020-01-21 14:25:12 -0800257 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800258 out.initialized = o.Initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800259 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 Neil316febd2020-02-09 12:26:50 -0800317 size: sizeGroupType,
318 marshal: appendGroupType,
319 unmarshal: consumeGroupType,
Damien Neilc37adef2019-04-01 13:49:56 -0700320 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800321 if needsInitCheck(mi.Desc) {
Damien Neil316febd2020-02-09 12:26:50 -0800322 funcs.isInit = isInitMessageInfo
Damien Neil7abc2de2020-01-09 14:13:57 -0800323 }
324 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700325 } else {
326 return pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800327 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -0700328 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neil316febd2020-02-09 12:26:50 -0800329 return sizeGroup(m, f.tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700330 },
Damien Neil316febd2020-02-09 12:26:50 -0800331 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -0700332 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neil316febd2020-02-09 12:26:50 -0800333 return appendGroup(b, m, f.wiretag, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700334 },
Damien Neil316febd2020-02-09 12:26:50 -0800335 unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700336 mp := p.AsValueOf(ft).Elem()
337 if mp.IsNil() {
338 mp.Set(reflect.New(ft.Elem()))
339 }
340 return consumeGroup(b, asMessage(mp), num, wtyp, opts)
341 },
Damien Neil316febd2020-02-09 12:26:50 -0800342 isInit: func(p pointer, f *coderFieldInfo) error {
Damien Neil5322bdb2019-04-09 15:57:05 -0700343 m := asMessage(p.AsValueOf(ft).Elem())
344 return proto.IsInitialized(m)
345 },
Damien Neilc37adef2019-04-01 13:49:56 -0700346 }
347 }
348}
349
Damien Neil316febd2020-02-09 12:26:50 -0800350func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
351 return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700352}
353
Damien Neil316febd2020-02-09 12:26:50 -0800354func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
355 b = wire.AppendVarint(b, f.wiretag) // start group
356 b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
357 b = wire.AppendVarint(b, f.wiretag+1) // end group
Damien Neilc37adef2019-04-01 13:49:56 -0700358 return b, err
359}
360
Damien Neil316febd2020-02-09 12:26:50 -0800361func consumeGroupType(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700362 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800363 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700364 }
365 if p.Elem().IsNil() {
Damien Neil316febd2020-02-09 12:26:50 -0800366 p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
Damien Neile91877d2019-06-27 10:54:42 -0700367 }
Damien Neil316febd2020-02-09 12:26:50 -0800368 return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700369}
370
Damien Neilc37adef2019-04-01 13:49:56 -0700371func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
372 return 2*tagsize + proto.Size(m)
373}
374
375func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
376 b = wire.AppendVarint(b, wiretag) // start group
377 b, err := opts.Options().MarshalAppend(b, m)
378 b = wire.AppendVarint(b, wiretag+1) // end group
379 return b, err
380}
381
Damien Neilf0831e82020-01-21 14:25:12 -0800382func 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 -0700383 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800384 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700385 }
386 b, n := wire.ConsumeGroup(num, b)
387 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800388 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700389 }
Damien Neilc600d6c2020-01-21 15:00:33 -0800390 o, err := opts.Options().UnmarshalState(m, piface.UnmarshalInput{
391 Buf: b,
392 })
393 if err != nil {
394 return out, err
395 }
Damien Neilf0831e82020-01-21 14:25:12 -0800396 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800397 out.initialized = o.Initialized
398 return out, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700399}
400
Damien Neilc37adef2019-04-01 13:49:56 -0700401func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai070c1012019-07-26 23:45:58 -0700402 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800403 funcs := pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800404 size: sizeMessageSliceInfo,
405 marshal: appendMessageSliceInfo,
406 unmarshal: consumeMessageSliceInfo,
Damien Neilc37adef2019-04-01 13:49:56 -0700407 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800408 if needsInitCheck(mi.Desc) {
Damien Neil316febd2020-02-09 12:26:50 -0800409 funcs.isInit = isInitMessageSliceInfo
Damien Neil7abc2de2020-01-09 14:13:57 -0800410 }
411 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700412 }
413 return pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800414 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
415 return sizeMessageSlice(p, ft, f.tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700416 },
Damien Neil316febd2020-02-09 12:26:50 -0800417 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
418 return appendMessageSlice(b, p, f.wiretag, ft, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700419 },
Damien Neil316febd2020-02-09 12:26:50 -0800420 unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700421 return consumeMessageSlice(b, p, ft, wtyp, opts)
422 },
Damien Neil316febd2020-02-09 12:26:50 -0800423 isInit: func(p pointer, f *coderFieldInfo) error {
Damien Neil5322bdb2019-04-09 15:57:05 -0700424 return isInitMessageSlice(p, ft)
425 },
Damien Neilc37adef2019-04-01 13:49:56 -0700426 }
427}
428
Damien Neil316febd2020-02-09 12:26:50 -0800429func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700430 s := p.PointerSlice()
431 n := 0
432 for _, v := range s {
Damien Neil316febd2020-02-09 12:26:50 -0800433 n += wire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
Damien Neilc37adef2019-04-01 13:49:56 -0700434 }
435 return n
436}
437
Damien Neil316febd2020-02-09 12:26:50 -0800438func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700439 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700440 var err error
441 for _, v := range s {
Damien Neil316febd2020-02-09 12:26:50 -0800442 b = wire.AppendVarint(b, f.wiretag)
443 siz := f.mi.sizePointer(v, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700444 b = wire.AppendVarint(b, uint64(siz))
Damien Neil316febd2020-02-09 12:26:50 -0800445 b, err = f.mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700446 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700447 return b, err
448 }
449 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700450 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700451}
452
Damien Neil316febd2020-02-09 12:26:50 -0800453func consumeMessageSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700454 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800455 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700456 }
457 v, n := wire.ConsumeBytes(b)
458 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800459 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700460 }
Damien Neil316febd2020-02-09 12:26:50 -0800461 m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
Damien Neile91877d2019-06-27 10:54:42 -0700462 mp := pointerOfIface(m)
Damien Neil316febd2020-02-09 12:26:50 -0800463 o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
Damien Neilc600d6c2020-01-21 15:00:33 -0800464 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800465 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700466 }
467 p.AppendPointerSlice(mp)
Damien Neilf0831e82020-01-21 14:25:12 -0800468 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800469 out.initialized = o.initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800470 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700471}
472
Damien Neil316febd2020-02-09 12:26:50 -0800473func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
Damien Neil5322bdb2019-04-09 15:57:05 -0700474 s := p.PointerSlice()
475 for _, v := range s {
Damien Neil316febd2020-02-09 12:26:50 -0800476 if err := f.mi.isInitializedPointer(v); err != nil {
Damien Neil5322bdb2019-04-09 15:57:05 -0700477 return err
478 }
479 }
480 return nil
481}
482
Damien Neilc37adef2019-04-01 13:49:56 -0700483func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
484 s := p.PointerSlice()
485 n := 0
486 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700487 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700488 n += wire.SizeBytes(proto.Size(m)) + tagsize
489 }
490 return n
491}
492
493func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
494 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700495 var err error
496 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700497 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700498 b = wire.AppendVarint(b, wiretag)
499 siz := proto.Size(m)
500 b = wire.AppendVarint(b, uint64(siz))
501 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700502 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700503 return b, err
504 }
505 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700506 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700507}
508
Damien Neilf0831e82020-01-21 14:25:12 -0800509func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
Damien Neile91877d2019-06-27 10:54:42 -0700510 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800511 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700512 }
513 v, n := wire.ConsumeBytes(b)
514 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800515 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700516 }
517 mp := reflect.New(goType.Elem())
Damien Neilc600d6c2020-01-21 15:00:33 -0800518 o, err := opts.Options().UnmarshalState(asMessage(mp), piface.UnmarshalInput{
519 Buf: v,
520 })
521 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800522 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700523 }
524 p.AppendPointerSlice(pointerOfValue(mp))
Damien Neilf0831e82020-01-21 14:25:12 -0800525 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800526 out.initialized = o.Initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800527 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700528}
529
Damien Neil5322bdb2019-04-09 15:57:05 -0700530func isInitMessageSlice(p pointer, goType reflect.Type) error {
531 s := p.PointerSlice()
532 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700533 m := asMessage(v.AsValueOf(goType.Elem()))
Damien Neil5322bdb2019-04-09 15:57:05 -0700534 if err := proto.IsInitialized(m); err != nil {
535 return err
536 }
537 }
538 return nil
539}
540
Damien Neilc37adef2019-04-01 13:49:56 -0700541// Slices of messages
542
Damien Neil68b81c32019-08-22 11:41:32 -0700543func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
544 list := listv.List()
545 n := 0
546 for i, llen := 0, list.Len(); i < llen; i++ {
547 m := list.Get(i).Message().Interface()
548 n += wire.SizeBytes(proto.Size(m)) + tagsize
549 }
550 return n
Damien Neilc37adef2019-04-01 13:49:56 -0700551}
552
Damien Neil68b81c32019-08-22 11:41:32 -0700553func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
554 list := listv.List()
555 mopts := opts.Options()
556 for i, llen := 0, list.Len(); i < llen; i++ {
557 m := list.Get(i).Message().Interface()
558 b = wire.AppendVarint(b, wiretag)
559 siz := proto.Size(m)
560 b = wire.AppendVarint(b, uint64(siz))
561 var err error
562 b, err = mopts.MarshalAppend(b, m)
563 if err != nil {
564 return b, err
565 }
566 }
567 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700568}
569
Damien Neilf0831e82020-01-21 14:25:12 -0800570func 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 -0700571 list := listv.List()
572 if wtyp != wire.BytesType {
Damien Neilf0831e82020-01-21 14:25:12 -0800573 return pref.Value{}, out, errUnknown
Damien Neil68b81c32019-08-22 11:41:32 -0700574 }
575 v, n := wire.ConsumeBytes(b)
576 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800577 return pref.Value{}, out, wire.ParseError(n)
Damien Neil68b81c32019-08-22 11:41:32 -0700578 }
579 m := list.NewElement()
Damien Neilc600d6c2020-01-21 15:00:33 -0800580 o, err := opts.Options().UnmarshalState(m.Message().Interface(), piface.UnmarshalInput{
581 Buf: v,
582 })
583 if 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
Damien Neilc600d6c2020-01-21 15:00:33 -0800588 out.initialized = o.Initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800589 return listv, out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700590}
591
Damien Neil68b81c32019-08-22 11:41:32 -0700592func isInitMessageSliceValue(listv pref.Value) error {
593 list := listv.List()
594 for i, llen := 0, list.Len(); i < llen; i++ {
595 m := list.Get(i).Message().Interface()
596 if err := proto.IsInitialized(m); err != nil {
597 return err
598 }
599 }
600 return nil
Damien Neil5322bdb2019-04-09 15:57:05 -0700601}
602
Damien Neil68b81c32019-08-22 11:41:32 -0700603var coderMessageSliceValue = valueCoderFuncs{
604 size: sizeMessageSliceValue,
605 marshal: appendMessageSliceValue,
606 unmarshal: consumeMessageSliceValue,
607 isInit: isInitMessageSliceValue,
608}
609
610func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
611 list := listv.List()
612 n := 0
613 for i, llen := 0, list.Len(); i < llen; i++ {
614 m := list.Get(i).Message().Interface()
615 n += 2*tagsize + proto.Size(m)
616 }
617 return n
618}
619
620func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
621 list := listv.List()
622 mopts := opts.Options()
623 for i, llen := 0, list.Len(); i < llen; i++ {
624 m := list.Get(i).Message().Interface()
625 b = wire.AppendVarint(b, wiretag) // start group
626 var err error
627 b, err = mopts.MarshalAppend(b, m)
628 if err != nil {
629 return b, err
630 }
631 b = wire.AppendVarint(b, wiretag+1) // end group
632 }
633 return b, nil
634}
635
Damien Neilf0831e82020-01-21 14:25:12 -0800636func 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 -0700637 list := listv.List()
638 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800639 return pref.Value{}, out, errUnknown
Damien Neil68b81c32019-08-22 11:41:32 -0700640 }
641 b, n := wire.ConsumeGroup(num, b)
642 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800643 return pref.Value{}, out, wire.ParseError(n)
Damien Neil68b81c32019-08-22 11:41:32 -0700644 }
645 m := list.NewElement()
Damien Neilc600d6c2020-01-21 15:00:33 -0800646 o, err := opts.Options().UnmarshalState(m.Message().Interface(), piface.UnmarshalInput{
647 Buf: b,
648 })
649 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800650 return pref.Value{}, out, err
Damien Neil68b81c32019-08-22 11:41:32 -0700651 }
652 list.Append(m)
Damien Neilf0831e82020-01-21 14:25:12 -0800653 out.n = n
Damien Neilc600d6c2020-01-21 15:00:33 -0800654 out.initialized = o.Initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800655 return listv, out, nil
Damien Neil68b81c32019-08-22 11:41:32 -0700656}
657
658var coderGroupSliceValue = valueCoderFuncs{
659 size: sizeGroupSliceValue,
660 marshal: appendGroupSliceValue,
661 unmarshal: consumeGroupSliceValue,
662 isInit: isInitMessageSliceValue,
Damien Neilc37adef2019-04-01 13:49:56 -0700663}
664
665func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Damien Neile91877d2019-06-27 10:54:42 -0700666 num := fd.Number()
Joe Tsai070c1012019-07-26 23:45:58 -0700667 if mi := getMessageInfo(ft); mi != nil {
Damien Neil7abc2de2020-01-09 14:13:57 -0800668 funcs := pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800669 size: sizeGroupSliceInfo,
670 marshal: appendGroupSliceInfo,
671 unmarshal: consumeGroupSliceInfo,
Damien Neilc37adef2019-04-01 13:49:56 -0700672 }
Damien Neil7abc2de2020-01-09 14:13:57 -0800673 if needsInitCheck(mi.Desc) {
Damien Neil316febd2020-02-09 12:26:50 -0800674 funcs.isInit = isInitMessageSliceInfo
Damien Neil7abc2de2020-01-09 14:13:57 -0800675 }
676 return funcs
Damien Neilc37adef2019-04-01 13:49:56 -0700677 }
678 return pointerCoderFuncs{
Damien Neil316febd2020-02-09 12:26:50 -0800679 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
680 return sizeGroupSlice(p, ft, f.tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700681 },
Damien Neil316febd2020-02-09 12:26:50 -0800682 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
683 return appendGroupSlice(b, p, f.wiretag, ft, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700684 },
Damien Neil316febd2020-02-09 12:26:50 -0800685 unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700686 return consumeGroupSlice(b, p, num, wtyp, ft, opts)
687 },
Damien Neil316febd2020-02-09 12:26:50 -0800688 isInit: func(p pointer, f *coderFieldInfo) error {
Damien Neil5322bdb2019-04-09 15:57:05 -0700689 return isInitMessageSlice(p, ft)
690 },
Damien Neilc37adef2019-04-01 13:49:56 -0700691 }
692}
693
694func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
695 s := p.PointerSlice()
696 n := 0
697 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700698 m := asMessage(v.AsValueOf(messageType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700699 n += 2*tagsize + proto.Size(m)
700 }
701 return n
702}
703
704func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
705 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700706 var err error
707 for _, v := range s {
Damien Neile91877d2019-06-27 10:54:42 -0700708 m := asMessage(v.AsValueOf(messageType.Elem()))
Damien Neilc37adef2019-04-01 13:49:56 -0700709 b = wire.AppendVarint(b, wiretag) // start group
710 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700711 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700712 return b, err
713 }
714 b = wire.AppendVarint(b, wiretag+1) // end group
715 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700716 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700717}
718
Damien Neilf0831e82020-01-21 14:25:12 -0800719func 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 -0700720 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800721 return out, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700722 }
723 b, n := wire.ConsumeGroup(num, b)
724 if n < 0 {
Damien Neilf0831e82020-01-21 14:25:12 -0800725 return out, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700726 }
727 mp := reflect.New(goType.Elem())
Damien Neilc600d6c2020-01-21 15:00:33 -0800728 o, err := opts.Options().UnmarshalState(asMessage(mp), piface.UnmarshalInput{
729 Buf: b,
730 })
731 if 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
Damien Neilc600d6c2020-01-21 15:00:33 -0800736 out.initialized = o.Initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800737 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700738}
739
Damien Neil316febd2020-02-09 12:26:50 -0800740func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700741 s := p.PointerSlice()
742 n := 0
743 for _, v := range s {
Damien Neil316febd2020-02-09 12:26:50 -0800744 n += 2*f.tagsize + f.mi.sizePointer(v, opts)
Damien Neilc37adef2019-04-01 13:49:56 -0700745 }
746 return n
747}
748
Damien Neil316febd2020-02-09 12:26:50 -0800749func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700750 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700751 var err error
752 for _, v := range s {
Damien Neil316febd2020-02-09 12:26:50 -0800753 b = wire.AppendVarint(b, f.wiretag) // start group
754 b, err = f.mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700755 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700756 return b, err
757 }
Damien Neil316febd2020-02-09 12:26:50 -0800758 b = wire.AppendVarint(b, f.wiretag+1) // end group
Damien Neilc37adef2019-04-01 13:49:56 -0700759 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700760 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700761}
762
Damien Neil316febd2020-02-09 12:26:50 -0800763func consumeGroupSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700764 if wtyp != wire.StartGroupType {
Damien Neilf0831e82020-01-21 14:25:12 -0800765 return unmarshalOutput{}, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700766 }
Damien Neil316febd2020-02-09 12:26:50 -0800767 m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
Damien Neile91877d2019-06-27 10:54:42 -0700768 mp := pointerOfIface(m)
Damien Neil316febd2020-02-09 12:26:50 -0800769 out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
Damien Neile91877d2019-06-27 10:54:42 -0700770 if err != nil {
Damien Neilf0831e82020-01-21 14:25:12 -0800771 return out, err
Damien Neile91877d2019-06-27 10:54:42 -0700772 }
773 p.AppendPointerSlice(mp)
Damien Neilf0831e82020-01-21 14:25:12 -0800774 return out, nil
Damien Neile91877d2019-06-27 10:54:42 -0700775}
776
Damien Neil5b6d0472019-06-14 11:54:07 -0700777func asMessage(v reflect.Value) pref.ProtoMessage {
778 if m, ok := v.Interface().(pref.ProtoMessage); ok {
779 return m
780 }
781 return legacyWrapMessage(v)
782}