...

Source file src/google.golang.org/protobuf/internal/impl/codec_field.go

Documentation: google.golang.org/protobuf/internal/impl

     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  	"google.golang.org/protobuf/reflect/protoreflect"
    16  	"google.golang.org/protobuf/reflect/protoregistry"
    17  	"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 protoreflect.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 protoreflect.FieldDescriptor) pointerCoderFuncs {
   122  	var once sync.Once
   123  	var messageType protoreflect.MessageType
   124  	lazyInit := func() {
   125  		once.Do(func() {
   126  			messageName := fd.Message().FullName()
   127  			messageType, _ = protoregistry.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 protoreflect.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  	calculatedSize := f.mi.sizePointer(p.Elem(), opts)
   237  	b = protowire.AppendVarint(b, f.wiretag)
   238  	b = protowire.AppendVarint(b, uint64(calculatedSize))
   239  	before := len(b)
   240  	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
   241  	if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
   242  		return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
   243  	}
   244  	return b, err
   245  }
   246  
   247  func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
   248  	if wtyp != protowire.BytesType {
   249  		return out, errUnknown
   250  	}
   251  	v, n := protowire.ConsumeBytes(b)
   252  	if n < 0 {
   253  		return out, errDecode
   254  	}
   255  	if p.Elem().IsNil() {
   256  		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
   257  	}
   258  	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
   259  	if err != nil {
   260  		return out, err
   261  	}
   262  	out.n = n
   263  	out.initialized = o.initialized
   264  	return out, nil
   265  }
   266  
   267  func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
   268  	return f.mi.checkInitializedPointer(p.Elem())
   269  }
   270  
   271  func sizeMessage(m proto.Message, tagsize int, opts marshalOptions) int {
   272  	return protowire.SizeBytes(opts.Options().Size(m)) + tagsize
   273  }
   274  
   275  func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
   276  	mopts := opts.Options()
   277  	calculatedSize := mopts.Size(m)
   278  	b = protowire.AppendVarint(b, wiretag)
   279  	b = protowire.AppendVarint(b, uint64(calculatedSize))
   280  	before := len(b)
   281  	b, err := mopts.MarshalAppend(b, m)
   282  	if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
   283  		return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
   284  	}
   285  	return b, err
   286  }
   287  
   288  func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
   289  	if wtyp != protowire.BytesType {
   290  		return out, errUnknown
   291  	}
   292  	v, n := protowire.ConsumeBytes(b)
   293  	if n < 0 {
   294  		return out, errDecode
   295  	}
   296  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   297  		Buf:     v,
   298  		Message: m.ProtoReflect(),
   299  	})
   300  	if err != nil {
   301  		return out, err
   302  	}
   303  	out.n = n
   304  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   305  	return out, nil
   306  }
   307  
   308  func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
   309  	m := v.Message().Interface()
   310  	return sizeMessage(m, tagsize, opts)
   311  }
   312  
   313  func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   314  	m := v.Message().Interface()
   315  	return appendMessage(b, m, wiretag, opts)
   316  }
   317  
   318  func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
   319  	m := v.Message().Interface()
   320  	out, err := consumeMessage(b, m, wtyp, opts)
   321  	return v, out, err
   322  }
   323  
   324  func isInitMessageValue(v protoreflect.Value) error {
   325  	m := v.Message().Interface()
   326  	return proto.CheckInitialized(m)
   327  }
   328  
   329  var coderMessageValue = valueCoderFuncs{
   330  	size:      sizeMessageValue,
   331  	marshal:   appendMessageValue,
   332  	unmarshal: consumeMessageValue,
   333  	isInit:    isInitMessageValue,
   334  	merge:     mergeMessageValue,
   335  }
   336  
   337  func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
   338  	m := v.Message().Interface()
   339  	return sizeGroup(m, tagsize, opts)
   340  }
   341  
   342  func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   343  	m := v.Message().Interface()
   344  	return appendGroup(b, m, wiretag, opts)
   345  }
   346  
   347  func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
   348  	m := v.Message().Interface()
   349  	out, err := consumeGroup(b, m, num, wtyp, opts)
   350  	return v, out, err
   351  }
   352  
   353  var coderGroupValue = valueCoderFuncs{
   354  	size:      sizeGroupValue,
   355  	marshal:   appendGroupValue,
   356  	unmarshal: consumeGroupValue,
   357  	isInit:    isInitMessageValue,
   358  	merge:     mergeMessageValue,
   359  }
   360  
   361  func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
   362  	num := fd.Number()
   363  	if mi := getMessageInfo(ft); mi != nil {
   364  		funcs := pointerCoderFuncs{
   365  			size:      sizeGroupType,
   366  			marshal:   appendGroupType,
   367  			unmarshal: consumeGroupType,
   368  			merge:     mergeMessage,
   369  		}
   370  		if needsInitCheck(mi.Desc) {
   371  			funcs.isInit = isInitMessageInfo
   372  		}
   373  		return funcs
   374  	} else {
   375  		return pointerCoderFuncs{
   376  			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   377  				m := asMessage(p.AsValueOf(ft).Elem())
   378  				return sizeGroup(m, f.tagsize, opts)
   379  			},
   380  			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   381  				m := asMessage(p.AsValueOf(ft).Elem())
   382  				return appendGroup(b, m, f.wiretag, opts)
   383  			},
   384  			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
   385  				mp := p.AsValueOf(ft).Elem()
   386  				if mp.IsNil() {
   387  					mp.Set(reflect.New(ft.Elem()))
   388  				}
   389  				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
   390  			},
   391  			isInit: func(p pointer, f *coderFieldInfo) error {
   392  				m := asMessage(p.AsValueOf(ft).Elem())
   393  				return proto.CheckInitialized(m)
   394  			},
   395  			merge: mergeMessage,
   396  		}
   397  	}
   398  }
   399  
   400  func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   401  	return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
   402  }
   403  
   404  func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   405  	b = protowire.AppendVarint(b, f.wiretag) // start group
   406  	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
   407  	b = protowire.AppendVarint(b, f.wiretag+1) // end group
   408  	return b, err
   409  }
   410  
   411  func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
   412  	if wtyp != protowire.StartGroupType {
   413  		return out, errUnknown
   414  	}
   415  	if p.Elem().IsNil() {
   416  		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
   417  	}
   418  	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
   419  }
   420  
   421  func sizeGroup(m proto.Message, tagsize int, opts marshalOptions) int {
   422  	return 2*tagsize + opts.Options().Size(m)
   423  }
   424  
   425  func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
   426  	b = protowire.AppendVarint(b, wiretag) // start group
   427  	b, err := opts.Options().MarshalAppend(b, m)
   428  	b = protowire.AppendVarint(b, wiretag+1) // end group
   429  	return b, err
   430  }
   431  
   432  func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
   433  	if wtyp != protowire.StartGroupType {
   434  		return out, errUnknown
   435  	}
   436  	b, n := protowire.ConsumeGroup(num, b)
   437  	if n < 0 {
   438  		return out, errDecode
   439  	}
   440  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   441  		Buf:     b,
   442  		Message: m.ProtoReflect(),
   443  	})
   444  	if err != nil {
   445  		return out, err
   446  	}
   447  	out.n = n
   448  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   449  	return out, nil
   450  }
   451  
   452  func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
   453  	if mi := getMessageInfo(ft); mi != nil {
   454  		funcs := pointerCoderFuncs{
   455  			size:      sizeMessageSliceInfo,
   456  			marshal:   appendMessageSliceInfo,
   457  			unmarshal: consumeMessageSliceInfo,
   458  			merge:     mergeMessageSlice,
   459  		}
   460  		if needsInitCheck(mi.Desc) {
   461  			funcs.isInit = isInitMessageSliceInfo
   462  		}
   463  		return funcs
   464  	}
   465  	return pointerCoderFuncs{
   466  		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   467  			return sizeMessageSlice(p, ft, f.tagsize, opts)
   468  		},
   469  		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   470  			return appendMessageSlice(b, p, f.wiretag, ft, opts)
   471  		},
   472  		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
   473  			return consumeMessageSlice(b, p, ft, wtyp, opts)
   474  		},
   475  		isInit: func(p pointer, f *coderFieldInfo) error {
   476  			return isInitMessageSlice(p, ft)
   477  		},
   478  		merge: mergeMessageSlice,
   479  	}
   480  }
   481  
   482  func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   483  	s := p.PointerSlice()
   484  	n := 0
   485  	for _, v := range s {
   486  		n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
   487  	}
   488  	return n
   489  }
   490  
   491  func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   492  	s := p.PointerSlice()
   493  	var err error
   494  	for _, v := range s {
   495  		b = protowire.AppendVarint(b, f.wiretag)
   496  		siz := f.mi.sizePointer(v, opts)
   497  		b = protowire.AppendVarint(b, uint64(siz))
   498  		before := len(b)
   499  		b, err = f.mi.marshalAppendPointer(b, v, opts)
   500  		if err != nil {
   501  			return b, err
   502  		}
   503  		if measuredSize := len(b) - before; siz != measuredSize {
   504  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
   505  		}
   506  	}
   507  	return b, nil
   508  }
   509  
   510  func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
   511  	if wtyp != protowire.BytesType {
   512  		return out, errUnknown
   513  	}
   514  	v, n := protowire.ConsumeBytes(b)
   515  	if n < 0 {
   516  		return out, errDecode
   517  	}
   518  	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
   519  	mp := pointerOfIface(m)
   520  	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
   521  	if err != nil {
   522  		return out, err
   523  	}
   524  	p.AppendPointerSlice(mp)
   525  	out.n = n
   526  	out.initialized = o.initialized
   527  	return out, nil
   528  }
   529  
   530  func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
   531  	s := p.PointerSlice()
   532  	for _, v := range s {
   533  		if err := f.mi.checkInitializedPointer(v); err != nil {
   534  			return err
   535  		}
   536  	}
   537  	return nil
   538  }
   539  
   540  func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, opts marshalOptions) int {
   541  	mopts := opts.Options()
   542  	s := p.PointerSlice()
   543  	n := 0
   544  	for _, v := range s {
   545  		m := asMessage(v.AsValueOf(goType.Elem()))
   546  		n += protowire.SizeBytes(mopts.Size(m)) + tagsize
   547  	}
   548  	return n
   549  }
   550  
   551  func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
   552  	mopts := opts.Options()
   553  	s := p.PointerSlice()
   554  	var err error
   555  	for _, v := range s {
   556  		m := asMessage(v.AsValueOf(goType.Elem()))
   557  		b = protowire.AppendVarint(b, wiretag)
   558  		siz := mopts.Size(m)
   559  		b = protowire.AppendVarint(b, uint64(siz))
   560  		before := len(b)
   561  		b, err = mopts.MarshalAppend(b, m)
   562  		if err != nil {
   563  			return b, err
   564  		}
   565  		if measuredSize := len(b) - before; siz != measuredSize {
   566  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
   567  		}
   568  	}
   569  	return b, nil
   570  }
   571  
   572  func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
   573  	if wtyp != protowire.BytesType {
   574  		return out, errUnknown
   575  	}
   576  	v, n := protowire.ConsumeBytes(b)
   577  	if n < 0 {
   578  		return out, errDecode
   579  	}
   580  	mp := reflect.New(goType.Elem())
   581  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   582  		Buf:     v,
   583  		Message: asMessage(mp).ProtoReflect(),
   584  	})
   585  	if err != nil {
   586  		return out, err
   587  	}
   588  	p.AppendPointerSlice(pointerOfValue(mp))
   589  	out.n = n
   590  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   591  	return out, nil
   592  }
   593  
   594  func isInitMessageSlice(p pointer, goType reflect.Type) error {
   595  	s := p.PointerSlice()
   596  	for _, v := range s {
   597  		m := asMessage(v.AsValueOf(goType.Elem()))
   598  		if err := proto.CheckInitialized(m); err != nil {
   599  			return err
   600  		}
   601  	}
   602  	return nil
   603  }
   604  
   605  // Slices of messages
   606  
   607  func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
   608  	mopts := opts.Options()
   609  	list := listv.List()
   610  	n := 0
   611  	for i, llen := 0, list.Len(); i < llen; i++ {
   612  		m := list.Get(i).Message().Interface()
   613  		n += protowire.SizeBytes(mopts.Size(m)) + tagsize
   614  	}
   615  	return n
   616  }
   617  
   618  func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   619  	list := listv.List()
   620  	mopts := opts.Options()
   621  	for i, llen := 0, list.Len(); i < llen; i++ {
   622  		m := list.Get(i).Message().Interface()
   623  		b = protowire.AppendVarint(b, wiretag)
   624  		siz := mopts.Size(m)
   625  		b = protowire.AppendVarint(b, uint64(siz))
   626  		before := len(b)
   627  		var err error
   628  		b, err = mopts.MarshalAppend(b, m)
   629  		if err != nil {
   630  			return b, err
   631  		}
   632  		if measuredSize := len(b) - before; siz != measuredSize {
   633  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
   634  		}
   635  	}
   636  	return b, nil
   637  }
   638  
   639  func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
   640  	list := listv.List()
   641  	if wtyp != protowire.BytesType {
   642  		return protoreflect.Value{}, out, errUnknown
   643  	}
   644  	v, n := protowire.ConsumeBytes(b)
   645  	if n < 0 {
   646  		return protoreflect.Value{}, out, errDecode
   647  	}
   648  	m := list.NewElement()
   649  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   650  		Buf:     v,
   651  		Message: m.Message(),
   652  	})
   653  	if err != nil {
   654  		return protoreflect.Value{}, out, err
   655  	}
   656  	list.Append(m)
   657  	out.n = n
   658  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   659  	return listv, out, nil
   660  }
   661  
   662  func isInitMessageSliceValue(listv protoreflect.Value) error {
   663  	list := listv.List()
   664  	for i, llen := 0, list.Len(); i < llen; i++ {
   665  		m := list.Get(i).Message().Interface()
   666  		if err := proto.CheckInitialized(m); err != nil {
   667  			return err
   668  		}
   669  	}
   670  	return nil
   671  }
   672  
   673  var coderMessageSliceValue = valueCoderFuncs{
   674  	size:      sizeMessageSliceValue,
   675  	marshal:   appendMessageSliceValue,
   676  	unmarshal: consumeMessageSliceValue,
   677  	isInit:    isInitMessageSliceValue,
   678  	merge:     mergeMessageListValue,
   679  }
   680  
   681  func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
   682  	mopts := opts.Options()
   683  	list := listv.List()
   684  	n := 0
   685  	for i, llen := 0, list.Len(); i < llen; i++ {
   686  		m := list.Get(i).Message().Interface()
   687  		n += 2*tagsize + mopts.Size(m)
   688  	}
   689  	return n
   690  }
   691  
   692  func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   693  	list := listv.List()
   694  	mopts := opts.Options()
   695  	for i, llen := 0, list.Len(); i < llen; i++ {
   696  		m := list.Get(i).Message().Interface()
   697  		b = protowire.AppendVarint(b, wiretag) // start group
   698  		var err error
   699  		b, err = mopts.MarshalAppend(b, m)
   700  		if err != nil {
   701  			return b, err
   702  		}
   703  		b = protowire.AppendVarint(b, wiretag+1) // end group
   704  	}
   705  	return b, nil
   706  }
   707  
   708  func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
   709  	list := listv.List()
   710  	if wtyp != protowire.StartGroupType {
   711  		return protoreflect.Value{}, out, errUnknown
   712  	}
   713  	b, n := protowire.ConsumeGroup(num, b)
   714  	if n < 0 {
   715  		return protoreflect.Value{}, out, errDecode
   716  	}
   717  	m := list.NewElement()
   718  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   719  		Buf:     b,
   720  		Message: m.Message(),
   721  	})
   722  	if err != nil {
   723  		return protoreflect.Value{}, out, err
   724  	}
   725  	list.Append(m)
   726  	out.n = n
   727  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   728  	return listv, out, nil
   729  }
   730  
   731  var coderGroupSliceValue = valueCoderFuncs{
   732  	size:      sizeGroupSliceValue,
   733  	marshal:   appendGroupSliceValue,
   734  	unmarshal: consumeGroupSliceValue,
   735  	isInit:    isInitMessageSliceValue,
   736  	merge:     mergeMessageListValue,
   737  }
   738  
   739  func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
   740  	num := fd.Number()
   741  	if mi := getMessageInfo(ft); mi != nil {
   742  		funcs := pointerCoderFuncs{
   743  			size:      sizeGroupSliceInfo,
   744  			marshal:   appendGroupSliceInfo,
   745  			unmarshal: consumeGroupSliceInfo,
   746  			merge:     mergeMessageSlice,
   747  		}
   748  		if needsInitCheck(mi.Desc) {
   749  			funcs.isInit = isInitMessageSliceInfo
   750  		}
   751  		return funcs
   752  	}
   753  	return pointerCoderFuncs{
   754  		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   755  			return sizeGroupSlice(p, ft, f.tagsize, opts)
   756  		},
   757  		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   758  			return appendGroupSlice(b, p, f.wiretag, ft, opts)
   759  		},
   760  		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
   761  			return consumeGroupSlice(b, p, num, wtyp, ft, opts)
   762  		},
   763  		isInit: func(p pointer, f *coderFieldInfo) error {
   764  			return isInitMessageSlice(p, ft)
   765  		},
   766  		merge: mergeMessageSlice,
   767  	}
   768  }
   769  
   770  func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, opts marshalOptions) int {
   771  	mopts := opts.Options()
   772  	s := p.PointerSlice()
   773  	n := 0
   774  	for _, v := range s {
   775  		m := asMessage(v.AsValueOf(messageType.Elem()))
   776  		n += 2*tagsize + mopts.Size(m)
   777  	}
   778  	return n
   779  }
   780  
   781  func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
   782  	s := p.PointerSlice()
   783  	var err error
   784  	for _, v := range s {
   785  		m := asMessage(v.AsValueOf(messageType.Elem()))
   786  		b = protowire.AppendVarint(b, wiretag) // start group
   787  		b, err = opts.Options().MarshalAppend(b, m)
   788  		if err != nil {
   789  			return b, err
   790  		}
   791  		b = protowire.AppendVarint(b, wiretag+1) // end group
   792  	}
   793  	return b, nil
   794  }
   795  
   796  func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
   797  	if wtyp != protowire.StartGroupType {
   798  		return out, errUnknown
   799  	}
   800  	b, n := protowire.ConsumeGroup(num, b)
   801  	if n < 0 {
   802  		return out, errDecode
   803  	}
   804  	mp := reflect.New(goType.Elem())
   805  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
   806  		Buf:     b,
   807  		Message: asMessage(mp).ProtoReflect(),
   808  	})
   809  	if err != nil {
   810  		return out, err
   811  	}
   812  	p.AppendPointerSlice(pointerOfValue(mp))
   813  	out.n = n
   814  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
   815  	return out, nil
   816  }
   817  
   818  func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
   819  	s := p.PointerSlice()
   820  	n := 0
   821  	for _, v := range s {
   822  		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
   823  	}
   824  	return n
   825  }
   826  
   827  func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   828  	s := p.PointerSlice()
   829  	var err error
   830  	for _, v := range s {
   831  		b = protowire.AppendVarint(b, f.wiretag) // start group
   832  		b, err = f.mi.marshalAppendPointer(b, v, opts)
   833  		if err != nil {
   834  			return b, err
   835  		}
   836  		b = protowire.AppendVarint(b, f.wiretag+1) // end group
   837  	}
   838  	return b, nil
   839  }
   840  
   841  func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
   842  	if wtyp != protowire.StartGroupType {
   843  		return unmarshalOutput{}, errUnknown
   844  	}
   845  	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
   846  	mp := pointerOfIface(m)
   847  	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
   848  	if err != nil {
   849  		return out, err
   850  	}
   851  	p.AppendPointerSlice(mp)
   852  	return out, nil
   853  }
   854  
   855  func asMessage(v reflect.Value) protoreflect.ProtoMessage {
   856  	if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
   857  		return m
   858  	}
   859  	return legacyWrapMessage(v).Interface()
   860  }
   861  

View as plain text