vendor/google.golang.org/protobuf/internal/impl/codec_field.go
changeset 256 6d9efbef00a9
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
       
     1 // 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 
       
     5 package impl
       
     6 
       
     7 import (
       
     8 	"fmt"
       
     9 	"reflect"
       
    10 	"sync"
       
    11 
       
    12 	"google.golang.org/protobuf/encoding/protowire"
       
    13 	"google.golang.org/protobuf/internal/errors"
       
    14 	"google.golang.org/protobuf/proto"
       
    15 	pref "google.golang.org/protobuf/reflect/protoreflect"
       
    16 	preg "google.golang.org/protobuf/reflect/protoregistry"
       
    17 	piface "google.golang.org/protobuf/runtime/protoiface"
       
    18 )
       
    19 
       
    20 type errInvalidUTF8 struct{}
       
    21 
       
    22 func (errInvalidUTF8) Error() string     { return "string field contains invalid UTF-8" }
       
    23 func (errInvalidUTF8) InvalidUTF8() bool { return true }
       
    24 func (errInvalidUTF8) Unwrap() error     { return errors.Error }
       
    25 
       
    26 // initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
       
    27 //
       
    28 // For size, marshal, and isInit operations, functions are set only on the first field
       
    29 // in the oneof. The functions are called when the oneof is non-nil, and will dispatch
       
    30 // to the appropriate field-specific function as necessary.
       
    31 //
       
    32 // The unmarshal function is set on each field individually as usual.
       
    33 func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
       
    34 	fs := si.oneofsByName[od.Name()]
       
    35 	ft := fs.Type
       
    36 	oneofFields := make(map[reflect.Type]*coderFieldInfo)
       
    37 	needIsInit := false
       
    38 	fields := od.Fields()
       
    39 	for i, lim := 0, fields.Len(); i < lim; i++ {
       
    40 		fd := od.Fields().Get(i)
       
    41 		num := fd.Number()
       
    42 		// Make a copy of the original coderFieldInfo for use in unmarshaling.
       
    43 		//
       
    44 		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
       
    45 		//
       
    46 		// mi.coderFields[num].marshal is set on only the first field in the oneof,
       
    47 		// and dispatches to the field-specific marshaler in oneofFields.
       
    48 		cf := *mi.coderFields[num]
       
    49 		ot := si.oneofWrappersByNumber[num]
       
    50 		cf.ft = ot.Field(0).Type
       
    51 		cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
       
    52 		oneofFields[ot] = &cf
       
    53 		if cf.funcs.isInit != nil {
       
    54 			needIsInit = true
       
    55 		}
       
    56 		mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
    57 			var vw reflect.Value         // pointer to wrapper type
       
    58 			vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
       
    59 			if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
       
    60 				vw = vi.Elem()
       
    61 			} else {
       
    62 				vw = reflect.New(ot)
       
    63 			}
       
    64 			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
       
    65 			if err != nil {
       
    66 				return out, err
       
    67 			}
       
    68 			vi.Set(vw)
       
    69 			return out, nil
       
    70 		}
       
    71 	}
       
    72 	getInfo := func(p pointer) (pointer, *coderFieldInfo) {
       
    73 		v := p.AsValueOf(ft).Elem()
       
    74 		if v.IsNil() {
       
    75 			return pointer{}, nil
       
    76 		}
       
    77 		v = v.Elem() // interface -> *struct
       
    78 		if v.IsNil() {
       
    79 			return pointer{}, nil
       
    80 		}
       
    81 		return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
       
    82 	}
       
    83 	first := mi.coderFields[od.Fields().Get(0).Number()]
       
    84 	first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
       
    85 		p, info := getInfo(p)
       
    86 		if info == nil || info.funcs.size == nil {
       
    87 			return 0
       
    88 		}
       
    89 		return info.funcs.size(p, info, opts)
       
    90 	}
       
    91 	first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
    92 		p, info := getInfo(p)
       
    93 		if info == nil || info.funcs.marshal == nil {
       
    94 			return b, nil
       
    95 		}
       
    96 		return info.funcs.marshal(b, p, info, opts)
       
    97 	}
       
    98 	first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
       
    99 		srcp, srcinfo := getInfo(src)
       
   100 		if srcinfo == nil || srcinfo.funcs.merge == nil {
       
   101 			return
       
   102 		}
       
   103 		dstp, dstinfo := getInfo(dst)
       
   104 		if dstinfo != srcinfo {
       
   105 			dst.AsValueOf(ft).Elem().Set(reflect.New(src.AsValueOf(ft).Elem().Elem().Elem().Type()))
       
   106 			dstp = pointerOfValue(dst.AsValueOf(ft).Elem().Elem()).Apply(zeroOffset)
       
   107 		}
       
   108 		srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
       
   109 	}
       
   110 	if needIsInit {
       
   111 		first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
       
   112 			p, info := getInfo(p)
       
   113 			if info == nil || info.funcs.isInit == nil {
       
   114 				return nil
       
   115 			}
       
   116 			return info.funcs.isInit(p, info)
       
   117 		}
       
   118 	}
       
   119 }
       
   120 
       
   121 func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
       
   122 	var once sync.Once
       
   123 	var messageType pref.MessageType
       
   124 	lazyInit := func() {
       
   125 		once.Do(func() {
       
   126 			messageName := fd.Message().FullName()
       
   127 			messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
       
   128 		})
       
   129 	}
       
   130 
       
   131 	return pointerCoderFuncs{
       
   132 		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   133 			m, ok := p.WeakFields().get(f.num)
       
   134 			if !ok {
       
   135 				return 0
       
   136 			}
       
   137 			lazyInit()
       
   138 			if messageType == nil {
       
   139 				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
       
   140 			}
       
   141 			return sizeMessage(m, f.tagsize, opts)
       
   142 		},
       
   143 		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   144 			m, ok := p.WeakFields().get(f.num)
       
   145 			if !ok {
       
   146 				return b, nil
       
   147 			}
       
   148 			lazyInit()
       
   149 			if messageType == nil {
       
   150 				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
       
   151 			}
       
   152 			return appendMessage(b, m, f.wiretag, opts)
       
   153 		},
       
   154 		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   155 			fs := p.WeakFields()
       
   156 			m, ok := fs.get(f.num)
       
   157 			if !ok {
       
   158 				lazyInit()
       
   159 				if messageType == nil {
       
   160 					return unmarshalOutput{}, errUnknown
       
   161 				}
       
   162 				m = messageType.New().Interface()
       
   163 				fs.set(f.num, m)
       
   164 			}
       
   165 			return consumeMessage(b, m, wtyp, opts)
       
   166 		},
       
   167 		isInit: func(p pointer, f *coderFieldInfo) error {
       
   168 			m, ok := p.WeakFields().get(f.num)
       
   169 			if !ok {
       
   170 				return nil
       
   171 			}
       
   172 			return proto.CheckInitialized(m)
       
   173 		},
       
   174 		merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
       
   175 			sm, ok := src.WeakFields().get(f.num)
       
   176 			if !ok {
       
   177 				return
       
   178 			}
       
   179 			dm, ok := dst.WeakFields().get(f.num)
       
   180 			if !ok {
       
   181 				lazyInit()
       
   182 				if messageType == nil {
       
   183 					panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
       
   184 				}
       
   185 				dm = messageType.New().Interface()
       
   186 				dst.WeakFields().set(f.num, dm)
       
   187 			}
       
   188 			opts.Merge(dm, sm)
       
   189 		},
       
   190 	}
       
   191 }
       
   192 
       
   193 func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
       
   194 	if mi := getMessageInfo(ft); mi != nil {
       
   195 		funcs := pointerCoderFuncs{
       
   196 			size:      sizeMessageInfo,
       
   197 			marshal:   appendMessageInfo,
       
   198 			unmarshal: consumeMessageInfo,
       
   199 			merge:     mergeMessage,
       
   200 		}
       
   201 		if needsInitCheck(mi.Desc) {
       
   202 			funcs.isInit = isInitMessageInfo
       
   203 		}
       
   204 		return funcs
       
   205 	} else {
       
   206 		return pointerCoderFuncs{
       
   207 			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   208 				m := asMessage(p.AsValueOf(ft).Elem())
       
   209 				return sizeMessage(m, f.tagsize, opts)
       
   210 			},
       
   211 			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   212 				m := asMessage(p.AsValueOf(ft).Elem())
       
   213 				return appendMessage(b, m, f.wiretag, opts)
       
   214 			},
       
   215 			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   216 				mp := p.AsValueOf(ft).Elem()
       
   217 				if mp.IsNil() {
       
   218 					mp.Set(reflect.New(ft.Elem()))
       
   219 				}
       
   220 				return consumeMessage(b, asMessage(mp), wtyp, opts)
       
   221 			},
       
   222 			isInit: func(p pointer, f *coderFieldInfo) error {
       
   223 				m := asMessage(p.AsValueOf(ft).Elem())
       
   224 				return proto.CheckInitialized(m)
       
   225 			},
       
   226 			merge: mergeMessage,
       
   227 		}
       
   228 	}
       
   229 }
       
   230 
       
   231 func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   232 	return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
       
   233 }
       
   234 
       
   235 func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   236 	b = protowire.AppendVarint(b, f.wiretag)
       
   237 	b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
       
   238 	return f.mi.marshalAppendPointer(b, p.Elem(), opts)
       
   239 }
       
   240 
       
   241 func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   242 	if wtyp != protowire.BytesType {
       
   243 		return out, errUnknown
       
   244 	}
       
   245 	v, n := protowire.ConsumeBytes(b)
       
   246 	if n < 0 {
       
   247 		return out, errDecode
       
   248 	}
       
   249 	if p.Elem().IsNil() {
       
   250 		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
       
   251 	}
       
   252 	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
       
   253 	if err != nil {
       
   254 		return out, err
       
   255 	}
       
   256 	out.n = n
       
   257 	out.initialized = o.initialized
       
   258 	return out, nil
       
   259 }
       
   260 
       
   261 func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
       
   262 	return f.mi.checkInitializedPointer(p.Elem())
       
   263 }
       
   264 
       
   265 func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
       
   266 	return protowire.SizeBytes(proto.Size(m)) + tagsize
       
   267 }
       
   268 
       
   269 func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   270 	b = protowire.AppendVarint(b, wiretag)
       
   271 	b = protowire.AppendVarint(b, uint64(proto.Size(m)))
       
   272 	return opts.Options().MarshalAppend(b, m)
       
   273 }
       
   274 
       
   275 func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   276 	if wtyp != protowire.BytesType {
       
   277 		return out, errUnknown
       
   278 	}
       
   279 	v, n := protowire.ConsumeBytes(b)
       
   280 	if n < 0 {
       
   281 		return out, errDecode
       
   282 	}
       
   283 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   284 		Buf:     v,
       
   285 		Message: m.ProtoReflect(),
       
   286 	})
       
   287 	if err != nil {
       
   288 		return out, err
       
   289 	}
       
   290 	out.n = n
       
   291 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   292 	return out, nil
       
   293 }
       
   294 
       
   295 func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
       
   296 	m := v.Message().Interface()
       
   297 	return sizeMessage(m, tagsize, opts)
       
   298 }
       
   299 
       
   300 func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   301 	m := v.Message().Interface()
       
   302 	return appendMessage(b, m, wiretag, opts)
       
   303 }
       
   304 
       
   305 func consumeMessageValue(b []byte, v pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
       
   306 	m := v.Message().Interface()
       
   307 	out, err := consumeMessage(b, m, wtyp, opts)
       
   308 	return v, out, err
       
   309 }
       
   310 
       
   311 func isInitMessageValue(v pref.Value) error {
       
   312 	m := v.Message().Interface()
       
   313 	return proto.CheckInitialized(m)
       
   314 }
       
   315 
       
   316 var coderMessageValue = valueCoderFuncs{
       
   317 	size:      sizeMessageValue,
       
   318 	marshal:   appendMessageValue,
       
   319 	unmarshal: consumeMessageValue,
       
   320 	isInit:    isInitMessageValue,
       
   321 	merge:     mergeMessageValue,
       
   322 }
       
   323 
       
   324 func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int {
       
   325 	m := v.Message().Interface()
       
   326 	return sizeGroup(m, tagsize, opts)
       
   327 }
       
   328 
       
   329 func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   330 	m := v.Message().Interface()
       
   331 	return appendGroup(b, m, wiretag, opts)
       
   332 }
       
   333 
       
   334 func consumeGroupValue(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
       
   335 	m := v.Message().Interface()
       
   336 	out, err := consumeGroup(b, m, num, wtyp, opts)
       
   337 	return v, out, err
       
   338 }
       
   339 
       
   340 var coderGroupValue = valueCoderFuncs{
       
   341 	size:      sizeGroupValue,
       
   342 	marshal:   appendGroupValue,
       
   343 	unmarshal: consumeGroupValue,
       
   344 	isInit:    isInitMessageValue,
       
   345 	merge:     mergeMessageValue,
       
   346 }
       
   347 
       
   348 func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
       
   349 	num := fd.Number()
       
   350 	if mi := getMessageInfo(ft); mi != nil {
       
   351 		funcs := pointerCoderFuncs{
       
   352 			size:      sizeGroupType,
       
   353 			marshal:   appendGroupType,
       
   354 			unmarshal: consumeGroupType,
       
   355 			merge:     mergeMessage,
       
   356 		}
       
   357 		if needsInitCheck(mi.Desc) {
       
   358 			funcs.isInit = isInitMessageInfo
       
   359 		}
       
   360 		return funcs
       
   361 	} else {
       
   362 		return pointerCoderFuncs{
       
   363 			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   364 				m := asMessage(p.AsValueOf(ft).Elem())
       
   365 				return sizeGroup(m, f.tagsize, opts)
       
   366 			},
       
   367 			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   368 				m := asMessage(p.AsValueOf(ft).Elem())
       
   369 				return appendGroup(b, m, f.wiretag, opts)
       
   370 			},
       
   371 			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   372 				mp := p.AsValueOf(ft).Elem()
       
   373 				if mp.IsNil() {
       
   374 					mp.Set(reflect.New(ft.Elem()))
       
   375 				}
       
   376 				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
       
   377 			},
       
   378 			isInit: func(p pointer, f *coderFieldInfo) error {
       
   379 				m := asMessage(p.AsValueOf(ft).Elem())
       
   380 				return proto.CheckInitialized(m)
       
   381 			},
       
   382 			merge: mergeMessage,
       
   383 		}
       
   384 	}
       
   385 }
       
   386 
       
   387 func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   388 	return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
       
   389 }
       
   390 
       
   391 func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   392 	b = protowire.AppendVarint(b, f.wiretag) // start group
       
   393 	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
       
   394 	b = protowire.AppendVarint(b, f.wiretag+1) // end group
       
   395 	return b, err
       
   396 }
       
   397 
       
   398 func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   399 	if wtyp != protowire.StartGroupType {
       
   400 		return out, errUnknown
       
   401 	}
       
   402 	if p.Elem().IsNil() {
       
   403 		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
       
   404 	}
       
   405 	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
       
   406 }
       
   407 
       
   408 func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
       
   409 	return 2*tagsize + proto.Size(m)
       
   410 }
       
   411 
       
   412 func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   413 	b = protowire.AppendVarint(b, wiretag) // start group
       
   414 	b, err := opts.Options().MarshalAppend(b, m)
       
   415 	b = protowire.AppendVarint(b, wiretag+1) // end group
       
   416 	return b, err
       
   417 }
       
   418 
       
   419 func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   420 	if wtyp != protowire.StartGroupType {
       
   421 		return out, errUnknown
       
   422 	}
       
   423 	b, n := protowire.ConsumeGroup(num, b)
       
   424 	if n < 0 {
       
   425 		return out, errDecode
       
   426 	}
       
   427 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   428 		Buf:     b,
       
   429 		Message: m.ProtoReflect(),
       
   430 	})
       
   431 	if err != nil {
       
   432 		return out, err
       
   433 	}
       
   434 	out.n = n
       
   435 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   436 	return out, nil
       
   437 }
       
   438 
       
   439 func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
       
   440 	if mi := getMessageInfo(ft); mi != nil {
       
   441 		funcs := pointerCoderFuncs{
       
   442 			size:      sizeMessageSliceInfo,
       
   443 			marshal:   appendMessageSliceInfo,
       
   444 			unmarshal: consumeMessageSliceInfo,
       
   445 			merge:     mergeMessageSlice,
       
   446 		}
       
   447 		if needsInitCheck(mi.Desc) {
       
   448 			funcs.isInit = isInitMessageSliceInfo
       
   449 		}
       
   450 		return funcs
       
   451 	}
       
   452 	return pointerCoderFuncs{
       
   453 		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   454 			return sizeMessageSlice(p, ft, f.tagsize, opts)
       
   455 		},
       
   456 		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   457 			return appendMessageSlice(b, p, f.wiretag, ft, opts)
       
   458 		},
       
   459 		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   460 			return consumeMessageSlice(b, p, ft, wtyp, opts)
       
   461 		},
       
   462 		isInit: func(p pointer, f *coderFieldInfo) error {
       
   463 			return isInitMessageSlice(p, ft)
       
   464 		},
       
   465 		merge: mergeMessageSlice,
       
   466 	}
       
   467 }
       
   468 
       
   469 func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   470 	s := p.PointerSlice()
       
   471 	n := 0
       
   472 	for _, v := range s {
       
   473 		n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
       
   474 	}
       
   475 	return n
       
   476 }
       
   477 
       
   478 func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   479 	s := p.PointerSlice()
       
   480 	var err error
       
   481 	for _, v := range s {
       
   482 		b = protowire.AppendVarint(b, f.wiretag)
       
   483 		siz := f.mi.sizePointer(v, opts)
       
   484 		b = protowire.AppendVarint(b, uint64(siz))
       
   485 		b, err = f.mi.marshalAppendPointer(b, v, opts)
       
   486 		if err != nil {
       
   487 			return b, err
       
   488 		}
       
   489 	}
       
   490 	return b, nil
       
   491 }
       
   492 
       
   493 func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   494 	if wtyp != protowire.BytesType {
       
   495 		return out, errUnknown
       
   496 	}
       
   497 	v, n := protowire.ConsumeBytes(b)
       
   498 	if n < 0 {
       
   499 		return out, errDecode
       
   500 	}
       
   501 	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
       
   502 	mp := pointerOfIface(m)
       
   503 	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
       
   504 	if err != nil {
       
   505 		return out, err
       
   506 	}
       
   507 	p.AppendPointerSlice(mp)
       
   508 	out.n = n
       
   509 	out.initialized = o.initialized
       
   510 	return out, nil
       
   511 }
       
   512 
       
   513 func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
       
   514 	s := p.PointerSlice()
       
   515 	for _, v := range s {
       
   516 		if err := f.mi.checkInitializedPointer(v); err != nil {
       
   517 			return err
       
   518 		}
       
   519 	}
       
   520 	return nil
       
   521 }
       
   522 
       
   523 func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
       
   524 	s := p.PointerSlice()
       
   525 	n := 0
       
   526 	for _, v := range s {
       
   527 		m := asMessage(v.AsValueOf(goType.Elem()))
       
   528 		n += protowire.SizeBytes(proto.Size(m)) + tagsize
       
   529 	}
       
   530 	return n
       
   531 }
       
   532 
       
   533 func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
       
   534 	s := p.PointerSlice()
       
   535 	var err error
       
   536 	for _, v := range s {
       
   537 		m := asMessage(v.AsValueOf(goType.Elem()))
       
   538 		b = protowire.AppendVarint(b, wiretag)
       
   539 		siz := proto.Size(m)
       
   540 		b = protowire.AppendVarint(b, uint64(siz))
       
   541 		b, err = opts.Options().MarshalAppend(b, m)
       
   542 		if err != nil {
       
   543 			return b, err
       
   544 		}
       
   545 	}
       
   546 	return b, nil
       
   547 }
       
   548 
       
   549 func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   550 	if wtyp != protowire.BytesType {
       
   551 		return out, errUnknown
       
   552 	}
       
   553 	v, n := protowire.ConsumeBytes(b)
       
   554 	if n < 0 {
       
   555 		return out, errDecode
       
   556 	}
       
   557 	mp := reflect.New(goType.Elem())
       
   558 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   559 		Buf:     v,
       
   560 		Message: asMessage(mp).ProtoReflect(),
       
   561 	})
       
   562 	if err != nil {
       
   563 		return out, err
       
   564 	}
       
   565 	p.AppendPointerSlice(pointerOfValue(mp))
       
   566 	out.n = n
       
   567 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   568 	return out, nil
       
   569 }
       
   570 
       
   571 func isInitMessageSlice(p pointer, goType reflect.Type) error {
       
   572 	s := p.PointerSlice()
       
   573 	for _, v := range s {
       
   574 		m := asMessage(v.AsValueOf(goType.Elem()))
       
   575 		if err := proto.CheckInitialized(m); err != nil {
       
   576 			return err
       
   577 		}
       
   578 	}
       
   579 	return nil
       
   580 }
       
   581 
       
   582 // Slices of messages
       
   583 
       
   584 func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
       
   585 	list := listv.List()
       
   586 	n := 0
       
   587 	for i, llen := 0, list.Len(); i < llen; i++ {
       
   588 		m := list.Get(i).Message().Interface()
       
   589 		n += protowire.SizeBytes(proto.Size(m)) + tagsize
       
   590 	}
       
   591 	return n
       
   592 }
       
   593 
       
   594 func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   595 	list := listv.List()
       
   596 	mopts := opts.Options()
       
   597 	for i, llen := 0, list.Len(); i < llen; i++ {
       
   598 		m := list.Get(i).Message().Interface()
       
   599 		b = protowire.AppendVarint(b, wiretag)
       
   600 		siz := proto.Size(m)
       
   601 		b = protowire.AppendVarint(b, uint64(siz))
       
   602 		var err error
       
   603 		b, err = mopts.MarshalAppend(b, m)
       
   604 		if err != nil {
       
   605 			return b, err
       
   606 		}
       
   607 	}
       
   608 	return b, nil
       
   609 }
       
   610 
       
   611 func consumeMessageSliceValue(b []byte, listv pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
       
   612 	list := listv.List()
       
   613 	if wtyp != protowire.BytesType {
       
   614 		return pref.Value{}, out, errUnknown
       
   615 	}
       
   616 	v, n := protowire.ConsumeBytes(b)
       
   617 	if n < 0 {
       
   618 		return pref.Value{}, out, errDecode
       
   619 	}
       
   620 	m := list.NewElement()
       
   621 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   622 		Buf:     v,
       
   623 		Message: m.Message(),
       
   624 	})
       
   625 	if err != nil {
       
   626 		return pref.Value{}, out, err
       
   627 	}
       
   628 	list.Append(m)
       
   629 	out.n = n
       
   630 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   631 	return listv, out, nil
       
   632 }
       
   633 
       
   634 func isInitMessageSliceValue(listv pref.Value) error {
       
   635 	list := listv.List()
       
   636 	for i, llen := 0, list.Len(); i < llen; i++ {
       
   637 		m := list.Get(i).Message().Interface()
       
   638 		if err := proto.CheckInitialized(m); err != nil {
       
   639 			return err
       
   640 		}
       
   641 	}
       
   642 	return nil
       
   643 }
       
   644 
       
   645 var coderMessageSliceValue = valueCoderFuncs{
       
   646 	size:      sizeMessageSliceValue,
       
   647 	marshal:   appendMessageSliceValue,
       
   648 	unmarshal: consumeMessageSliceValue,
       
   649 	isInit:    isInitMessageSliceValue,
       
   650 	merge:     mergeMessageListValue,
       
   651 }
       
   652 
       
   653 func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
       
   654 	list := listv.List()
       
   655 	n := 0
       
   656 	for i, llen := 0, list.Len(); i < llen; i++ {
       
   657 		m := list.Get(i).Message().Interface()
       
   658 		n += 2*tagsize + proto.Size(m)
       
   659 	}
       
   660 	return n
       
   661 }
       
   662 
       
   663 func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
       
   664 	list := listv.List()
       
   665 	mopts := opts.Options()
       
   666 	for i, llen := 0, list.Len(); i < llen; i++ {
       
   667 		m := list.Get(i).Message().Interface()
       
   668 		b = protowire.AppendVarint(b, wiretag) // start group
       
   669 		var err error
       
   670 		b, err = mopts.MarshalAppend(b, m)
       
   671 		if err != nil {
       
   672 			return b, err
       
   673 		}
       
   674 		b = protowire.AppendVarint(b, wiretag+1) // end group
       
   675 	}
       
   676 	return b, nil
       
   677 }
       
   678 
       
   679 func consumeGroupSliceValue(b []byte, listv pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
       
   680 	list := listv.List()
       
   681 	if wtyp != protowire.StartGroupType {
       
   682 		return pref.Value{}, out, errUnknown
       
   683 	}
       
   684 	b, n := protowire.ConsumeGroup(num, b)
       
   685 	if n < 0 {
       
   686 		return pref.Value{}, out, errDecode
       
   687 	}
       
   688 	m := list.NewElement()
       
   689 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   690 		Buf:     b,
       
   691 		Message: m.Message(),
       
   692 	})
       
   693 	if err != nil {
       
   694 		return pref.Value{}, out, err
       
   695 	}
       
   696 	list.Append(m)
       
   697 	out.n = n
       
   698 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   699 	return listv, out, nil
       
   700 }
       
   701 
       
   702 var coderGroupSliceValue = valueCoderFuncs{
       
   703 	size:      sizeGroupSliceValue,
       
   704 	marshal:   appendGroupSliceValue,
       
   705 	unmarshal: consumeGroupSliceValue,
       
   706 	isInit:    isInitMessageSliceValue,
       
   707 	merge:     mergeMessageListValue,
       
   708 }
       
   709 
       
   710 func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
       
   711 	num := fd.Number()
       
   712 	if mi := getMessageInfo(ft); mi != nil {
       
   713 		funcs := pointerCoderFuncs{
       
   714 			size:      sizeGroupSliceInfo,
       
   715 			marshal:   appendGroupSliceInfo,
       
   716 			unmarshal: consumeGroupSliceInfo,
       
   717 			merge:     mergeMessageSlice,
       
   718 		}
       
   719 		if needsInitCheck(mi.Desc) {
       
   720 			funcs.isInit = isInitMessageSliceInfo
       
   721 		}
       
   722 		return funcs
       
   723 	}
       
   724 	return pointerCoderFuncs{
       
   725 		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   726 			return sizeGroupSlice(p, ft, f.tagsize, opts)
       
   727 		},
       
   728 		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   729 			return appendGroupSlice(b, p, f.wiretag, ft, opts)
       
   730 		},
       
   731 		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   732 			return consumeGroupSlice(b, p, num, wtyp, ft, opts)
       
   733 		},
       
   734 		isInit: func(p pointer, f *coderFieldInfo) error {
       
   735 			return isInitMessageSlice(p, ft)
       
   736 		},
       
   737 		merge: mergeMessageSlice,
       
   738 	}
       
   739 }
       
   740 
       
   741 func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
       
   742 	s := p.PointerSlice()
       
   743 	n := 0
       
   744 	for _, v := range s {
       
   745 		m := asMessage(v.AsValueOf(messageType.Elem()))
       
   746 		n += 2*tagsize + proto.Size(m)
       
   747 	}
       
   748 	return n
       
   749 }
       
   750 
       
   751 func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
       
   752 	s := p.PointerSlice()
       
   753 	var err error
       
   754 	for _, v := range s {
       
   755 		m := asMessage(v.AsValueOf(messageType.Elem()))
       
   756 		b = protowire.AppendVarint(b, wiretag) // start group
       
   757 		b, err = opts.Options().MarshalAppend(b, m)
       
   758 		if err != nil {
       
   759 			return b, err
       
   760 		}
       
   761 		b = protowire.AppendVarint(b, wiretag+1) // end group
       
   762 	}
       
   763 	return b, nil
       
   764 }
       
   765 
       
   766 func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
       
   767 	if wtyp != protowire.StartGroupType {
       
   768 		return out, errUnknown
       
   769 	}
       
   770 	b, n := protowire.ConsumeGroup(num, b)
       
   771 	if n < 0 {
       
   772 		return out, errDecode
       
   773 	}
       
   774 	mp := reflect.New(goType.Elem())
       
   775 	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
       
   776 		Buf:     b,
       
   777 		Message: asMessage(mp).ProtoReflect(),
       
   778 	})
       
   779 	if err != nil {
       
   780 		return out, err
       
   781 	}
       
   782 	p.AppendPointerSlice(pointerOfValue(mp))
       
   783 	out.n = n
       
   784 	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
       
   785 	return out, nil
       
   786 }
       
   787 
       
   788 func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
       
   789 	s := p.PointerSlice()
       
   790 	n := 0
       
   791 	for _, v := range s {
       
   792 		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
       
   793 	}
       
   794 	return n
       
   795 }
       
   796 
       
   797 func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
       
   798 	s := p.PointerSlice()
       
   799 	var err error
       
   800 	for _, v := range s {
       
   801 		b = protowire.AppendVarint(b, f.wiretag) // start group
       
   802 		b, err = f.mi.marshalAppendPointer(b, v, opts)
       
   803 		if err != nil {
       
   804 			return b, err
       
   805 		}
       
   806 		b = protowire.AppendVarint(b, f.wiretag+1) // end group
       
   807 	}
       
   808 	return b, nil
       
   809 }
       
   810 
       
   811 func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
       
   812 	if wtyp != protowire.StartGroupType {
       
   813 		return unmarshalOutput{}, errUnknown
       
   814 	}
       
   815 	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
       
   816 	mp := pointerOfIface(m)
       
   817 	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
       
   818 	if err != nil {
       
   819 		return out, err
       
   820 	}
       
   821 	p.AppendPointerSlice(mp)
       
   822 	return out, nil
       
   823 }
       
   824 
       
   825 func asMessage(v reflect.Value) pref.ProtoMessage {
       
   826 	if m, ok := v.Interface().(pref.ProtoMessage); ok {
       
   827 		return m
       
   828 	}
       
   829 	return legacyWrapMessage(v).Interface()
       
   830 }