mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-09 13:13:32 +00:00
internal/impl: pass *coderFieldInfo into fast-path functions
Refactor the fast-path size, marshal, unmarshal, and isinit functions to take the *coderFieldInfo for the field as input. This replaces a number of closures capturing field-specific information with functions taking that information as an explicit parameter. Change-Id: I8cb39701265edb7b673f6f04a0152d5f4dbb4d5d Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/218937 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
f26172248d
commit
316febd1ab
@ -92,23 +92,23 @@ v, n := wire.Consume{{.WireType}}(b)
|
||||
|
||||
{{- if .FromGoType }}
|
||||
// size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
|
||||
func size{{.Name}}(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func size{{.Name}}(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
{{if not .WireType.ConstSize -}}
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
{{- end}}
|
||||
return tagsize + {{template "Size" .}}
|
||||
return f.tagsize + {{template "Size" .}}
|
||||
}
|
||||
|
||||
// append{{.Name}} wire encodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
func append{{.Name}}(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// consume{{.Name}} wire decodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
func consume{{.Name}}(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -129,9 +129,9 @@ var coder{{.Name}} = pointerCoderFuncs{
|
||||
|
||||
{{if or (eq .Name "Bytes") (eq .Name "String")}}
|
||||
// append{{.Name}}ValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
func append{{.Name}}ValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}ValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
@ -140,7 +140,7 @@ func append{{.Name}}ValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalO
|
||||
}
|
||||
|
||||
// consume{{.Name}}ValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
func consume{{.Name}}ValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}ValidateUTF8(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -165,22 +165,22 @@ var coder{{.Name}}ValidateUTF8 = pointerCoderFuncs{
|
||||
|
||||
// size{{.Name}}NoZero returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
|
||||
// The zero value is not encoded.
|
||||
func size{{.Name}}NoZero(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func size{{.Name}}NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
if {{template "IsZero" .}} {
|
||||
return 0
|
||||
}
|
||||
return tagsize + {{template "Size" .}}
|
||||
return f.tagsize + {{template "Size" .}}
|
||||
}
|
||||
|
||||
// append{{.Name}}NoZero wire encodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
// The zero value is not encoded.
|
||||
func append{{.Name}}NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
if {{template "IsZero" .}} {
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
return b, nil
|
||||
}
|
||||
@ -188,7 +188,7 @@ func append{{.Name}}NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions
|
||||
{{if .ToGoTypeNoZero}}
|
||||
// consume{{.Name}}NoZero wire decodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
// The zero value is not decoded.
|
||||
func consume{{.Name}}NoZero(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}NoZero(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -211,12 +211,12 @@ var coder{{.Name}}NoZero = pointerCoderFuncs{
|
||||
{{if or (eq .Name "Bytes") (eq .Name "String")}}
|
||||
// append{{.Name}}NoZeroValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
// The zero value is not encoded.
|
||||
func append{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.{{.GoType.PointerMethod}}()
|
||||
if {{template "IsZero" .}} {
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
@ -226,7 +226,7 @@ func append{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ ma
|
||||
|
||||
{{if .ToGoTypeNoZero}}
|
||||
// consume{{.Name}}NoZeroValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
|
||||
func consume{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -253,24 +253,24 @@ var coder{{.Name}}NoZeroValidateUTF8 = pointerCoderFuncs{
|
||||
{{- if not .NoPointer}}
|
||||
// size{{.Name}}Ptr returns the size of wire encoding a *{{.GoType}} pointer as a {{.Name}}.
|
||||
// It panics if the pointer is nil.
|
||||
func size{{.Name}}Ptr(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func size{{.Name}}Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
{{if not .WireType.ConstSize -}}
|
||||
v := **p.{{.GoType.PointerMethod}}Ptr()
|
||||
{{end -}}
|
||||
return tagsize + {{template "Size" .}}
|
||||
return f.tagsize + {{template "Size" .}}
|
||||
}
|
||||
|
||||
// append{{.Name}}Ptr wire encodes a *{{.GoType}} pointer as a {{.Name}}.
|
||||
// It panics if the pointer is nil.
|
||||
func append{{.Name}}Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
v := **p.{{.GoType.PointerMethod}}Ptr()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// consume{{.Name}}Ptr wire decodes a *{{.GoType}} pointer as a {{.Name}}.
|
||||
func consume{{.Name}}Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}Ptr(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -295,30 +295,30 @@ var coder{{.Name}}Ptr = pointerCoderFuncs{
|
||||
{{end}}
|
||||
|
||||
// size{{.Name}}Slice returns the size of wire encoding a []{{.GoType}} pointer as a repeated {{.Name}}.
|
||||
func size{{.Name}}Slice(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func size{{.Name}}Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
s := *p.{{.GoType.PointerMethod}}Slice()
|
||||
{{if .WireType.ConstSize -}}
|
||||
size = len(s) * (tagsize + {{template "Size" .}})
|
||||
size = len(s) * (f.tagsize + {{template "Size" .}})
|
||||
{{- else -}}
|
||||
for _, v := range s {
|
||||
size += tagsize + {{template "Size" .}}
|
||||
size += f.tagsize + {{template "Size" .}}
|
||||
}
|
||||
{{- end}}
|
||||
return size
|
||||
}
|
||||
|
||||
// append{{.Name}}Slice encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
|
||||
func append{{.Name}}Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
s := *p.{{.GoType.PointerMethod}}Slice()
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// consume{{.Name}}Slice wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
|
||||
func consume{{.Name}}Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}Slice(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
sp := p.{{.GoType.PointerMethod}}Slice()
|
||||
{{- if .WireType.Packable}}
|
||||
if wtyp == wire.BytesType {
|
||||
@ -360,10 +360,10 @@ var coder{{.Name}}Slice = pointerCoderFuncs{
|
||||
|
||||
{{if or (eq .Name "Bytes") (eq .Name "String")}}
|
||||
// append{{.Name}}SliceValidateUTF8 encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
|
||||
func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
s := *p.{{.GoType.PointerMethod}}Slice()
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{template "Append" .}}
|
||||
if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
@ -373,7 +373,7 @@ func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ mar
|
||||
}
|
||||
|
||||
// consume{{.Name}}SliceValidateUTF8 wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
|
||||
func consume{{.Name}}SliceValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consume{{.Name}}SliceValidateUTF8(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
sp := p.{{.GoType.PointerMethod}}Slice()
|
||||
if wtyp != {{.WireType.Expr}} {
|
||||
return out, errUnknown
|
||||
@ -399,7 +399,7 @@ var coder{{.Name}}SliceValidateUTF8 = pointerCoderFuncs{
|
||||
|
||||
{{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
|
||||
// size{{.Name}}PackedSlice returns the size of wire encoding a []{{.GoType}} pointer as a packed repeated {{.Name}}.
|
||||
func size{{.Name}}PackedSlice(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func size{{.Name}}PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
s := *p.{{.GoType.PointerMethod}}Slice()
|
||||
if len(s) == 0 {
|
||||
return 0
|
||||
@ -412,16 +412,16 @@ func size{{.Name}}PackedSlice(p pointer, tagsize int, _ marshalOptions) (size in
|
||||
n += {{template "Size" .}}
|
||||
}
|
||||
{{- end}}
|
||||
return tagsize + wire.SizeBytes(n)
|
||||
return f.tagsize + wire.SizeBytes(n)
|
||||
}
|
||||
|
||||
// append{{.Name}}PackedSlice encodes a []{{.GoType}} pointer as a packed repeated {{.Name}}.
|
||||
func append{{.Name}}PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
func append{{.Name}}PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
|
||||
s := *p.{{.GoType.PointerMethod}}Slice()
|
||||
if len(s) == 0 {
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
{{if .WireType.ConstSize -}}
|
||||
n := len(s) * {{template "Size" .}}
|
||||
{{- else -}}
|
||||
|
@ -29,31 +29,28 @@ func (errInvalidUTF8) InvalidUTF8() bool { return true }
|
||||
//
|
||||
// The unmarshal function is set on each field individually as usual.
|
||||
func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
|
||||
type oneofFieldInfo struct {
|
||||
wiretag uint64 // field tag (number + wire type)
|
||||
tagsize int // size of the varint-encoded tag
|
||||
funcs pointerCoderFuncs
|
||||
}
|
||||
fs := si.oneofsByName[od.Name()]
|
||||
ft := fs.Type
|
||||
oneofFields := make(map[reflect.Type]*oneofFieldInfo)
|
||||
oneofFields := make(map[reflect.Type]*coderFieldInfo)
|
||||
needIsInit := false
|
||||
fields := od.Fields()
|
||||
for i, lim := 0, fields.Len(); i < lim; i++ {
|
||||
fd := od.Fields().Get(i)
|
||||
num := fd.Number()
|
||||
cf := mi.coderFields[num]
|
||||
// Make a copy of the original coderFieldInfo for use in unmarshaling.
|
||||
//
|
||||
// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
|
||||
//
|
||||
// mi.coderFields[num].marshal is set on only the first field in the oneof,
|
||||
// and dispatches to the field-specific marshaler in oneofFields.
|
||||
cf := *mi.coderFields[num]
|
||||
ot := si.oneofWrappersByNumber[num]
|
||||
funcs := fieldCoder(fd, ot.Field(0).Type)
|
||||
oneofFields[ot] = &oneofFieldInfo{
|
||||
wiretag: cf.wiretag,
|
||||
tagsize: cf.tagsize,
|
||||
funcs: funcs,
|
||||
}
|
||||
if funcs.isInit != nil {
|
||||
cf.mi, cf.funcs = fieldCoder(fd, ot.Field(0).Type)
|
||||
oneofFields[ot] = &cf
|
||||
if cf.funcs.isInit != nil {
|
||||
needIsInit = true
|
||||
}
|
||||
cf.funcs.unmarshal = func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
var vw reflect.Value // pointer to wrapper type
|
||||
vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
|
||||
if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
|
||||
@ -61,7 +58,7 @@ func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structIn
|
||||
} else {
|
||||
vw = reflect.New(ot)
|
||||
}
|
||||
out, err := funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, opts)
|
||||
out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
@ -69,7 +66,7 @@ func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structIn
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
getInfo := func(p pointer) (pointer, *oneofFieldInfo) {
|
||||
getInfo := func(p pointer) (pointer, *coderFieldInfo) {
|
||||
v := p.AsValueOf(ft).Elem()
|
||||
if v.IsNil() {
|
||||
return pointer{}, nil
|
||||
@ -81,27 +78,27 @@ func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structIn
|
||||
return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
|
||||
}
|
||||
first := mi.coderFields[od.Fields().Get(0).Number()]
|
||||
first.funcs.size = func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.size == nil {
|
||||
return 0
|
||||
}
|
||||
return info.funcs.size(p, info.tagsize, opts)
|
||||
return info.funcs.size(p, info, opts)
|
||||
}
|
||||
first.funcs.marshal = func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.marshal == nil {
|
||||
return b, nil
|
||||
}
|
||||
return info.funcs.marshal(b, p, info.wiretag, opts)
|
||||
return info.funcs.marshal(b, p, info, opts)
|
||||
}
|
||||
if needIsInit {
|
||||
first.funcs.isInit = func(p pointer) error {
|
||||
first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.isInit == nil {
|
||||
return nil
|
||||
}
|
||||
return info.funcs.isInit(p)
|
||||
return info.funcs.isInit(p, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +115,7 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
|
||||
num := fd.Number()
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m, ok := p.WeakFields().get(num)
|
||||
if !ok {
|
||||
return 0
|
||||
@ -127,9 +124,9 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
|
||||
}
|
||||
return sizeMessage(m, tagsize, opts)
|
||||
return sizeMessage(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m, ok := p.WeakFields().get(num)
|
||||
if !ok {
|
||||
return b, nil
|
||||
@ -138,9 +135,9 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
|
||||
}
|
||||
return appendMessage(b, m, wiretag, opts)
|
||||
return appendMessage(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
fs := p.WeakFields()
|
||||
m, ok := fs.get(num)
|
||||
if !ok {
|
||||
@ -153,7 +150,7 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
}
|
||||
return consumeMessage(b, m, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer) error {
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m, ok := p.WeakFields().get(num)
|
||||
if !ok {
|
||||
return nil
|
||||
@ -166,40 +163,32 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeMessageInfo(p, mi, tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendMessageInfo(b, p, wiretag, mi, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeMessageInfo(b, p, mi, wtyp, opts)
|
||||
},
|
||||
size: sizeMessageInfo,
|
||||
marshal: appendMessageInfo,
|
||||
unmarshal: consumeMessageInfo,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = func(p pointer) error {
|
||||
return mi.isInitializedPointer(p.Elem())
|
||||
}
|
||||
funcs.isInit = isInitMessageInfo
|
||||
}
|
||||
return funcs
|
||||
} else {
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return sizeMessage(m, tagsize, opts)
|
||||
return sizeMessage(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return appendMessage(b, m, wiretag, opts)
|
||||
return appendMessage(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft).Elem()
|
||||
if mp.IsNil() {
|
||||
mp.Set(reflect.New(ft.Elem()))
|
||||
}
|
||||
return consumeMessage(b, asMessage(mp), wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer) error {
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return proto.IsInitialized(m)
|
||||
},
|
||||
@ -207,17 +196,17 @@ func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCode
|
||||
}
|
||||
}
|
||||
|
||||
func sizeMessageInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
|
||||
return wire.SizeBytes(mi.sizePointer(p.Elem(), opts)) + tagsize
|
||||
func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return wire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
|
||||
}
|
||||
|
||||
func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, uint64(mi.sizePointer(p.Elem(), opts)))
|
||||
return mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
b = wire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
|
||||
return f.mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
}
|
||||
|
||||
func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeMessageInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -226,9 +215,9 @@ func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, op
|
||||
return out, wire.ParseError(n)
|
||||
}
|
||||
if p.Elem().IsNil() {
|
||||
p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
|
||||
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
|
||||
}
|
||||
o, err := mi.unmarshalPointer(v, p.Elem(), 0, opts)
|
||||
o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
@ -237,6 +226,10 @@ func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, op
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
|
||||
return f.mi.isInitializedPointer(p.Elem())
|
||||
}
|
||||
|
||||
func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
|
||||
return wire.SizeBytes(proto.Size(m)) + tagsize
|
||||
}
|
||||
@ -321,40 +314,32 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF
|
||||
num := fd.Number()
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeGroupType(p, mi, tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendGroupType(b, p, wiretag, mi, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeGroupType(b, p, mi, num, wtyp, opts)
|
||||
},
|
||||
size: sizeGroupType,
|
||||
marshal: appendGroupType,
|
||||
unmarshal: consumeGroupType,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = func(p pointer) error {
|
||||
return mi.isInitializedPointer(p.Elem())
|
||||
}
|
||||
funcs.isInit = isInitMessageInfo
|
||||
}
|
||||
return funcs
|
||||
} else {
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return sizeGroup(m, tagsize, opts)
|
||||
return sizeGroup(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return appendGroup(b, m, wiretag, opts)
|
||||
return appendGroup(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft).Elem()
|
||||
if mp.IsNil() {
|
||||
mp.Set(reflect.New(ft.Elem()))
|
||||
}
|
||||
return consumeGroup(b, asMessage(mp), num, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer) error {
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return proto.IsInitialized(m)
|
||||
},
|
||||
@ -362,25 +347,25 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF
|
||||
}
|
||||
}
|
||||
|
||||
func sizeGroupType(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
|
||||
return 2*tagsize + mi.sizePointer(p.Elem(), opts)
|
||||
func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
|
||||
}
|
||||
|
||||
func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = wire.AppendVarint(b, wiretag) // start group
|
||||
b, err := mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
b = wire.AppendVarint(b, wiretag+1) // end group
|
||||
func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = wire.AppendVarint(b, f.wiretag) // start group
|
||||
b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
b = wire.AppendVarint(b, f.wiretag+1) // end group
|
||||
return b, err
|
||||
}
|
||||
|
||||
func consumeGroupType(b []byte, p pointer, mi *MessageInfo, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeGroupType(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.StartGroupType {
|
||||
return out, errUnknown
|
||||
}
|
||||
if p.Elem().IsNil() {
|
||||
p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
|
||||
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
|
||||
}
|
||||
return mi.unmarshalPointer(b, p.Elem(), num, opts)
|
||||
return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
|
||||
}
|
||||
|
||||
func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
|
||||
@ -416,56 +401,48 @@ func consumeGroup(b []byte, m proto.Message, num wire.Number, wtyp wire.Type, op
|
||||
func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeMessageSliceInfo(p, mi, tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendMessageSliceInfo(b, p, wiretag, mi, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeMessageSliceInfo(b, p, mi, wtyp, opts)
|
||||
},
|
||||
size: sizeMessageSliceInfo,
|
||||
marshal: appendMessageSliceInfo,
|
||||
unmarshal: consumeMessageSliceInfo,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = func(p pointer) error {
|
||||
return isInitMessageSliceInfo(p, mi)
|
||||
}
|
||||
funcs.isInit = isInitMessageSliceInfo
|
||||
}
|
||||
return funcs
|
||||
}
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeMessageSlice(p, ft, tagsize, opts)
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeMessageSlice(p, ft, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendMessageSlice(b, p, wiretag, ft, opts)
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendMessageSlice(b, p, f.wiretag, ft, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeMessageSlice(b, p, ft, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer) error {
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMessageSlice(p, ft)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
|
||||
func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
n += wire.SizeBytes(mi.sizePointer(v, opts)) + tagsize
|
||||
n += wire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
|
||||
func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
siz := mi.sizePointer(v, opts)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
siz := f.mi.sizePointer(v, opts)
|
||||
b = wire.AppendVarint(b, uint64(siz))
|
||||
b, err = mi.marshalAppendPointer(b, v, opts)
|
||||
b, err = f.mi.marshalAppendPointer(b, v, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
@ -473,7 +450,7 @@ func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeMessageSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -481,9 +458,9 @@ func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Typ
|
||||
if n < 0 {
|
||||
return out, wire.ParseError(n)
|
||||
}
|
||||
m := reflect.New(mi.GoReflectType.Elem()).Interface()
|
||||
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
|
||||
mp := pointerOfIface(m)
|
||||
o, err := mi.unmarshalPointer(v, mp, 0, opts)
|
||||
o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
@ -493,10 +470,10 @@ func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Typ
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func isInitMessageSliceInfo(p pointer, mi *MessageInfo) error {
|
||||
func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
|
||||
s := p.PointerSlice()
|
||||
for _, v := range s {
|
||||
if err := mi.isInitializedPointer(v); err != nil {
|
||||
if err := f.mi.isInitializedPointer(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -689,34 +666,26 @@ func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerC
|
||||
num := fd.Number()
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeGroupSliceInfo(p, mi, tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendGroupSliceInfo(b, p, wiretag, mi, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeGroupSliceInfo(b, p, num, wtyp, mi, opts)
|
||||
},
|
||||
size: sizeGroupSliceInfo,
|
||||
marshal: appendGroupSliceInfo,
|
||||
unmarshal: consumeGroupSliceInfo,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = func(p pointer) error {
|
||||
return isInitMessageSliceInfo(p, mi)
|
||||
}
|
||||
funcs.isInit = isInitMessageSliceInfo
|
||||
}
|
||||
return funcs
|
||||
}
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeGroupSlice(p, ft, tagsize, opts)
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeGroupSlice(p, ft, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendGroupSlice(b, p, wiretag, ft, opts)
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendGroupSlice(b, p, f.wiretag, ft, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeGroupSlice(b, p, num, wtyp, ft, opts)
|
||||
},
|
||||
isInit: func(p pointer) error {
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMessageSlice(p, ft)
|
||||
},
|
||||
}
|
||||
@ -768,36 +737,36 @@ func consumeGroupSlice(b []byte, p pointer, num wire.Number, wtyp wire.Type, goT
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
|
||||
func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
n += 2*tagsize + mi.sizePointer(v, opts)
|
||||
n += 2*f.tagsize + f.mi.sizePointer(v, opts)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
|
||||
func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag) // start group
|
||||
b, err = mi.marshalAppendPointer(b, v, opts)
|
||||
b = wire.AppendVarint(b, f.wiretag) // start group
|
||||
b, err = f.mi.marshalAppendPointer(b, v, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag+1) // end group
|
||||
b = wire.AppendVarint(b, f.wiretag+1) // end group
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeGroupSliceInfo(b []byte, p pointer, num wire.Number, wtyp wire.Type, mi *MessageInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
func consumeGroupSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
if wtyp != wire.StartGroupType {
|
||||
return unmarshalOutput{}, errUnknown
|
||||
}
|
||||
m := reflect.New(mi.GoReflectType.Elem()).Interface()
|
||||
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
|
||||
mp := pointerOfIface(m)
|
||||
out, err := mi.unmarshalPointer(b, mp, num, opts)
|
||||
out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,18 +14,17 @@ import (
|
||||
)
|
||||
|
||||
type mapInfo struct {
|
||||
goType reflect.Type
|
||||
keyWiretag uint64
|
||||
valWiretag uint64
|
||||
keyFuncs valueCoderFuncs
|
||||
valFuncs valueCoderFuncs
|
||||
keyZero pref.Value
|
||||
keyKind pref.Kind
|
||||
valMessageInfo *MessageInfo
|
||||
conv *mapConverter
|
||||
goType reflect.Type
|
||||
keyWiretag uint64
|
||||
valWiretag uint64
|
||||
keyFuncs valueCoderFuncs
|
||||
valFuncs valueCoderFuncs
|
||||
keyZero pref.Value
|
||||
keyKind pref.Kind
|
||||
conv *mapConverter
|
||||
}
|
||||
|
||||
func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointerCoderFuncs) {
|
||||
func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) {
|
||||
// TODO: Consider generating specialized map coders.
|
||||
keyField := fd.MapKey()
|
||||
valField := fd.MapValue()
|
||||
@ -46,34 +45,34 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointer
|
||||
conv: conv,
|
||||
}
|
||||
if valField.Kind() == pref.MessageKind {
|
||||
mapi.valMessageInfo = getMessageInfo(ft.Elem())
|
||||
valueMessage = getMessageInfo(ft.Elem())
|
||||
}
|
||||
|
||||
funcs = pointerCoderFuncs{
|
||||
size: func(p pointer, tagsize int, opts marshalOptions) int {
|
||||
return sizeMap(p.AsValueOf(ft).Elem(), tagsize, mapi, opts)
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeMap(p.AsValueOf(ft).Elem(), mapi, f, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendMap(b, p.AsValueOf(ft).Elem(), wiretag, mapi, opts)
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendMap(b, p.AsValueOf(ft).Elem(), mapi, f, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft)
|
||||
if mp.Elem().IsNil() {
|
||||
mp.Elem().Set(reflect.MakeMap(mapi.goType))
|
||||
}
|
||||
if mapi.valMessageInfo == nil {
|
||||
return consumeMap(b, mp.Elem(), wtyp, mapi, opts)
|
||||
if f.mi == nil {
|
||||
return consumeMap(b, mp.Elem(), wtyp, mapi, f, opts)
|
||||
} else {
|
||||
return consumeMapOfMessage(b, mp.Elem(), wtyp, mapi, opts)
|
||||
return consumeMapOfMessage(b, mp.Elem(), wtyp, mapi, f, opts)
|
||||
}
|
||||
},
|
||||
}
|
||||
if valFuncs.isInit != nil {
|
||||
funcs.isInit = func(p pointer) error {
|
||||
return isInitMap(p.AsValueOf(ft).Elem(), mapi)
|
||||
funcs.isInit = func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMap(p.AsValueOf(ft).Elem(), mapi, f)
|
||||
}
|
||||
}
|
||||
return funcs
|
||||
return valueMessage, funcs
|
||||
}
|
||||
|
||||
const (
|
||||
@ -81,7 +80,7 @@ const (
|
||||
mapValTagSize = 1 // field 2, tag size 2.
|
||||
)
|
||||
|
||||
func sizeMap(mapv reflect.Value, tagsize int, mapi *mapInfo, opts marshalOptions) int {
|
||||
func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) int {
|
||||
if mapv.Len() == 0 {
|
||||
return 0
|
||||
}
|
||||
@ -92,19 +91,19 @@ func sizeMap(mapv reflect.Value, tagsize int, mapi *mapInfo, opts marshalOptions
|
||||
keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
|
||||
var valSize int
|
||||
value := mapi.conv.valConv.PBValueOf(iter.Value())
|
||||
if mapi.valMessageInfo == nil {
|
||||
if f.mi == nil {
|
||||
valSize = mapi.valFuncs.size(value, mapValTagSize, opts)
|
||||
} else {
|
||||
p := pointerOfValue(iter.Value())
|
||||
valSize += mapValTagSize
|
||||
valSize += wire.SizeBytes(mapi.valMessageInfo.sizePointer(p, opts))
|
||||
valSize += wire.SizeBytes(f.mi.sizePointer(p, opts))
|
||||
}
|
||||
n += tagsize + wire.SizeBytes(keySize+valSize)
|
||||
n += f.tagsize + wire.SizeBytes(keySize+valSize)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func consumeMap(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *mapInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeMap(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -161,7 +160,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *mapInfo, opt
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *mapInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -171,7 +170,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *map
|
||||
}
|
||||
var (
|
||||
key = mapi.keyZero
|
||||
val = reflect.New(mapi.valMessageInfo.GoReflectType.Elem())
|
||||
val = reflect.New(f.mi.GoReflectType.Elem())
|
||||
)
|
||||
for len(b) > 0 {
|
||||
num, wtyp, n := wire.ConsumeTag(b)
|
||||
@ -203,7 +202,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *map
|
||||
return out, wire.ParseError(n)
|
||||
}
|
||||
var o unmarshalOutput
|
||||
o, err = mapi.valMessageInfo.unmarshalPointer(v, pointerOfValue(val), 0, opts)
|
||||
o, err = f.mi.unmarshalPointer(v, pointerOfValue(val), 0, opts)
|
||||
if o.initialized {
|
||||
// Consider this map item initialized so long as we see
|
||||
// an initialized value.
|
||||
@ -225,8 +224,8 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp wire.Type, mapi *map
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, opts marshalOptions) ([]byte, error) {
|
||||
if mapi.valMessageInfo == nil {
|
||||
func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if f.mi == nil {
|
||||
key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
|
||||
val := mapi.conv.valConv.PBValueOf(valrv)
|
||||
size := 0
|
||||
@ -241,7 +240,7 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, opts mar
|
||||
} else {
|
||||
key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
|
||||
val := pointerOfValue(valrv)
|
||||
valSize := mapi.valMessageInfo.sizePointer(val, opts)
|
||||
valSize := f.mi.sizePointer(val, opts)
|
||||
size := 0
|
||||
size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
|
||||
size += mapValTagSize + wire.SizeBytes(valSize)
|
||||
@ -252,22 +251,22 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, opts mar
|
||||
}
|
||||
b = wire.AppendVarint(b, mapi.valWiretag)
|
||||
b = wire.AppendVarint(b, uint64(valSize))
|
||||
return mapi.valMessageInfo.marshalAppendPointer(b, val, opts)
|
||||
return f.mi.marshalAppendPointer(b, val, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func appendMap(b []byte, mapv reflect.Value, wiretag uint64, mapi *mapInfo, opts marshalOptions) ([]byte, error) {
|
||||
func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if mapv.Len() == 0 {
|
||||
return b, nil
|
||||
}
|
||||
if opts.Deterministic() {
|
||||
return appendMapDeterministic(b, mapv, wiretag, mapi, opts)
|
||||
return appendMapDeterministic(b, mapv, mapi, f, opts)
|
||||
}
|
||||
iter := mapRange(mapv)
|
||||
for iter.Next() {
|
||||
var err error
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b, err = appendMapItem(b, iter.Key(), iter.Value(), mapi, opts)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
b, err = appendMapItem(b, iter.Key(), iter.Value(), mapi, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
@ -275,7 +274,7 @@ func appendMap(b []byte, mapv reflect.Value, wiretag uint64, mapi *mapInfo, opts
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func appendMapDeterministic(b []byte, mapv reflect.Value, wiretag uint64, mapi *mapInfo, opts marshalOptions) ([]byte, error) {
|
||||
func appendMapDeterministic(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
keys := mapv.MapKeys()
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
switch keys[i].Kind() {
|
||||
@ -295,8 +294,8 @@ func appendMapDeterministic(b []byte, mapv reflect.Value, wiretag uint64, mapi *
|
||||
})
|
||||
for _, key := range keys {
|
||||
var err error
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b, err = appendMapItem(b, key, mapv.MapIndex(key), mapi, opts)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
b, err = appendMapItem(b, key, mapv.MapIndex(key), mapi, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
@ -304,8 +303,8 @@ func appendMapDeterministic(b []byte, mapv reflect.Value, wiretag uint64, mapi *
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func isInitMap(mapv reflect.Value, mapi *mapInfo) error {
|
||||
if mi := mapi.valMessageInfo; mi != nil {
|
||||
func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error {
|
||||
if mi := f.mi; mi != nil {
|
||||
mi.init()
|
||||
if !mi.needsInitCheck {
|
||||
return nil
|
||||
|
@ -35,13 +35,15 @@ type coderMessageInfo struct {
|
||||
|
||||
type coderFieldInfo struct {
|
||||
funcs pointerCoderFuncs // fast-path per-field functions
|
||||
validation validationInfo // information used by message validation
|
||||
num pref.FieldNumber // field number
|
||||
offset offset // struct field offset
|
||||
wiretag uint64 // field tag (number + wire type)
|
||||
tagsize int // size of the varint-encoded tag
|
||||
isPointer bool // true if IsNil may be called on the struct field
|
||||
isRequired bool // true if field is required
|
||||
mi *MessageInfo // field's message
|
||||
ft reflect.Type
|
||||
validation validationInfo // information used by message validation
|
||||
num pref.FieldNumber // field number
|
||||
offset offset // struct field offset
|
||||
wiretag uint64 // field tag (number + wire type)
|
||||
tagsize int // size of the varint-encoded tag
|
||||
isPointer bool // true if IsNil may be called on the struct field
|
||||
isRequired bool // true if field is required
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
|
||||
@ -67,6 +69,7 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
|
||||
}
|
||||
var fieldOffset offset
|
||||
var funcs pointerCoderFuncs
|
||||
var childMessage *MessageInfo
|
||||
switch {
|
||||
case fd.ContainingOneof() != nil:
|
||||
fieldOffset = offsetOf(fs, mi.Exporter)
|
||||
@ -75,14 +78,16 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
|
||||
funcs = makeWeakMessageFieldCoder(fd)
|
||||
default:
|
||||
fieldOffset = offsetOf(fs, mi.Exporter)
|
||||
funcs = fieldCoder(fd, ft)
|
||||
childMessage, funcs = fieldCoder(fd, ft)
|
||||
}
|
||||
cf := &coderFieldInfo{
|
||||
num: fd.Number(),
|
||||
offset: fieldOffset,
|
||||
wiretag: wiretag,
|
||||
ft: ft,
|
||||
tagsize: wire.SizeVarint(wiretag),
|
||||
funcs: funcs,
|
||||
mi: childMessage,
|
||||
validation: newFieldValidationInfo(mi, si, fd, ft),
|
||||
isPointer: (fd.Cardinality() == pref.Repeated ||
|
||||
fd.Kind() == pref.MessageKind ||
|
||||
|
@ -12,19 +12,19 @@ import (
|
||||
"google.golang.org/protobuf/internal/encoding/wire"
|
||||
)
|
||||
|
||||
func sizeEnum(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
v := p.v.Elem().Int()
|
||||
return tagsize + wire.SizeVarint(uint64(v))
|
||||
return f.tagsize + wire.SizeVarint(uint64(v))
|
||||
}
|
||||
|
||||
func appendEnum(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
v := p.v.Elem().Int()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
b = wire.AppendVarint(b, uint64(v))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeEnum(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeEnum(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.VarintType {
|
||||
return out, errUnknown
|
||||
}
|
||||
@ -43,18 +43,18 @@ var coderEnum = pointerCoderFuncs{
|
||||
unmarshal: consumeEnum,
|
||||
}
|
||||
|
||||
func sizeEnumNoZero(p pointer, tagsize int, opts marshalOptions) (size int) {
|
||||
func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
if p.v.Elem().Int() == 0 {
|
||||
return 0
|
||||
}
|
||||
return sizeEnum(p, tagsize, opts)
|
||||
return sizeEnum(p, f, opts)
|
||||
}
|
||||
|
||||
func appendEnumNoZero(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if p.v.Elem().Int() == 0 {
|
||||
return b, nil
|
||||
}
|
||||
return appendEnum(b, p, wiretag, opts)
|
||||
return appendEnum(b, p, f, opts)
|
||||
}
|
||||
|
||||
var coderEnumNoZero = pointerCoderFuncs{
|
||||
@ -63,22 +63,22 @@ var coderEnumNoZero = pointerCoderFuncs{
|
||||
unmarshal: consumeEnum,
|
||||
}
|
||||
|
||||
func sizeEnumPtr(p pointer, tagsize int, opts marshalOptions) (size int) {
|
||||
return sizeEnum(pointer{p.v.Elem()}, tagsize, opts)
|
||||
func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
return sizeEnum(pointer{p.v.Elem()}, f, opts)
|
||||
}
|
||||
|
||||
func appendEnumPtr(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
return appendEnum(b, pointer{p.v.Elem()}, wiretag, opts)
|
||||
func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendEnum(b, pointer{p.v.Elem()}, f, opts)
|
||||
}
|
||||
|
||||
func consumeEnumPtr(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeEnumPtr(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != wire.VarintType {
|
||||
return out, errUnknown
|
||||
}
|
||||
if p.v.Elem().IsNil() {
|
||||
p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
|
||||
}
|
||||
return consumeEnum(b, pointer{p.v.Elem()}, wtyp, opts)
|
||||
return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
|
||||
}
|
||||
|
||||
var coderEnumPtr = pointerCoderFuncs{
|
||||
@ -87,24 +87,24 @@ var coderEnumPtr = pointerCoderFuncs{
|
||||
unmarshal: consumeEnumPtr,
|
||||
}
|
||||
|
||||
func sizeEnumSlice(p pointer, tagsize int, opts marshalOptions) (size int) {
|
||||
func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
s := p.v.Elem()
|
||||
for i, llen := 0, s.Len(); i < llen; i++ {
|
||||
size += wire.SizeVarint(uint64(s.Index(i).Int())) + tagsize
|
||||
size += wire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func appendEnumSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.v.Elem()
|
||||
for i, llen := 0, s.Len(); i < llen; i++ {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeEnumSlice(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
func consumeEnumSlice(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
s := p.v.Elem()
|
||||
if wtyp == wire.BytesType {
|
||||
b, n := wire.ConsumeBytes(b)
|
||||
@ -144,7 +144,7 @@ var coderEnumSlice = pointerCoderFuncs{
|
||||
unmarshal: consumeEnumSlice,
|
||||
}
|
||||
|
||||
func sizeEnumPackedSlice(p pointer, tagsize int, opts marshalOptions) (size int) {
|
||||
func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
s := p.v.Elem()
|
||||
llen := s.Len()
|
||||
if llen == 0 {
|
||||
@ -154,16 +154,16 @@ func sizeEnumPackedSlice(p pointer, tagsize int, opts marshalOptions) (size int)
|
||||
for i := 0; i < llen; i++ {
|
||||
n += wire.SizeVarint(uint64(s.Index(i).Int()))
|
||||
}
|
||||
return tagsize + wire.SizeBytes(n)
|
||||
return f.tagsize + wire.SizeBytes(n)
|
||||
}
|
||||
|
||||
func appendEnumPackedSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.v.Elem()
|
||||
llen := s.Len()
|
||||
if llen == 0 {
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendVarint(b, f.wiretag)
|
||||
n := 0
|
||||
for i := 0; i < llen; i++ {
|
||||
n += wire.SizeVarint(uint64(s.Index(i).Int()))
|
||||
|
@ -15,10 +15,11 @@ import (
|
||||
|
||||
// pointerCoderFuncs is a set of pointer encoding functions.
|
||||
type pointerCoderFuncs struct {
|
||||
size func(p pointer, tagsize int, opts marshalOptions) int
|
||||
marshal func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error)
|
||||
unmarshal func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (unmarshalOutput, error)
|
||||
isInit func(p pointer) error
|
||||
mi *MessageInfo
|
||||
size func(p pointer, f *coderFieldInfo, opts marshalOptions) int
|
||||
marshal func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error)
|
||||
unmarshal func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
|
||||
isInit func(p pointer, f *coderFieldInfo) error
|
||||
}
|
||||
|
||||
// valueCoderFuncs is a set of protoreflect.Value encoding functions.
|
||||
@ -31,7 +32,7 @@ type valueCoderFuncs struct {
|
||||
|
||||
// fieldCoder returns pointer functions for a field, used for operating on
|
||||
// struct fields.
|
||||
func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
|
||||
switch {
|
||||
case fd.IsMap():
|
||||
return encoderFuncsForMap(fd, ft)
|
||||
@ -44,84 +45,84 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return coderBoolSlice
|
||||
return nil, coderBoolSlice
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderEnumSlice
|
||||
return nil, coderEnumSlice
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderInt32Slice
|
||||
return nil, coderInt32Slice
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSint32Slice
|
||||
return nil, coderSint32Slice
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderUint32Slice
|
||||
return nil, coderUint32Slice
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderInt64Slice
|
||||
return nil, coderInt64Slice
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSint64Slice
|
||||
return nil, coderSint64Slice
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderUint64Slice
|
||||
return nil, coderUint64Slice
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSfixed32Slice
|
||||
return nil, coderSfixed32Slice
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderFixed32Slice
|
||||
return nil, coderFixed32Slice
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return coderFloatSlice
|
||||
return nil, coderFloatSlice
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSfixed64Slice
|
||||
return nil, coderSfixed64Slice
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderFixed64Slice
|
||||
return nil, coderFixed64Slice
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return coderDoubleSlice
|
||||
return nil, coderDoubleSlice
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return coderStringSliceValidateUTF8
|
||||
return nil, coderStringSliceValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringSlice
|
||||
return nil, coderStringSlice
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return coderBytesSliceValidateUTF8
|
||||
return nil, coderBytesSliceValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytesSlice
|
||||
return nil, coderBytesSlice
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringSlice
|
||||
return nil, coderStringSlice
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytesSlice
|
||||
return nil, coderBytesSlice
|
||||
}
|
||||
case pref.MessageKind:
|
||||
return makeMessageSliceFieldCoder(fd, ft)
|
||||
return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
|
||||
case pref.GroupKind:
|
||||
return makeGroupSliceFieldCoder(fd, ft)
|
||||
return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
|
||||
}
|
||||
case fd.Cardinality() == pref.Repeated && fd.IsPacked():
|
||||
// Packed repeated fields.
|
||||
@ -135,144 +136,144 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return coderBoolPackedSlice
|
||||
return nil, coderBoolPackedSlice
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderEnumPackedSlice
|
||||
return nil, coderEnumPackedSlice
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderInt32PackedSlice
|
||||
return nil, coderInt32PackedSlice
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSint32PackedSlice
|
||||
return nil, coderSint32PackedSlice
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderUint32PackedSlice
|
||||
return nil, coderUint32PackedSlice
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderInt64PackedSlice
|
||||
return nil, coderInt64PackedSlice
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSint64PackedSlice
|
||||
return nil, coderSint64PackedSlice
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderUint64PackedSlice
|
||||
return nil, coderUint64PackedSlice
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSfixed32PackedSlice
|
||||
return nil, coderSfixed32PackedSlice
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderFixed32PackedSlice
|
||||
return nil, coderFixed32PackedSlice
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return coderFloatPackedSlice
|
||||
return nil, coderFloatPackedSlice
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSfixed64PackedSlice
|
||||
return nil, coderSfixed64PackedSlice
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderFixed64PackedSlice
|
||||
return nil, coderFixed64PackedSlice
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return coderDoublePackedSlice
|
||||
return nil, coderDoublePackedSlice
|
||||
}
|
||||
}
|
||||
case fd.Kind() == pref.MessageKind:
|
||||
return makeMessageFieldCoder(fd, ft)
|
||||
return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
|
||||
case fd.Kind() == pref.GroupKind:
|
||||
return makeGroupFieldCoder(fd, ft)
|
||||
return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
|
||||
case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
|
||||
// Populated oneof fields always encode even if set to the zero value,
|
||||
// which normally are not encoded in proto3.
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return coderBoolNoZero
|
||||
return nil, coderBoolNoZero
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderEnumNoZero
|
||||
return nil, coderEnumNoZero
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderInt32NoZero
|
||||
return nil, coderInt32NoZero
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSint32NoZero
|
||||
return nil, coderSint32NoZero
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderUint32NoZero
|
||||
return nil, coderUint32NoZero
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderInt64NoZero
|
||||
return nil, coderInt64NoZero
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSint64NoZero
|
||||
return nil, coderSint64NoZero
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderUint64NoZero
|
||||
return nil, coderUint64NoZero
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSfixed32NoZero
|
||||
return nil, coderSfixed32NoZero
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderFixed32NoZero
|
||||
return nil, coderFixed32NoZero
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return coderFloatNoZero
|
||||
return nil, coderFloatNoZero
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSfixed64NoZero
|
||||
return nil, coderSfixed64NoZero
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderFixed64NoZero
|
||||
return nil, coderFixed64NoZero
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return coderDoubleNoZero
|
||||
return nil, coderDoubleNoZero
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return coderStringNoZeroValidateUTF8
|
||||
return nil, coderStringNoZeroValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringNoZero
|
||||
return nil, coderStringNoZero
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return coderBytesNoZeroValidateUTF8
|
||||
return nil, coderBytesNoZeroValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytesNoZero
|
||||
return nil, coderBytesNoZero
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringNoZero
|
||||
return nil, coderStringNoZero
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytesNoZero
|
||||
return nil, coderBytesNoZero
|
||||
}
|
||||
}
|
||||
case ft.Kind() == reflect.Ptr:
|
||||
@ -280,146 +281,146 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return coderBoolPtr
|
||||
return nil, coderBoolPtr
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderEnumPtr
|
||||
return nil, coderEnumPtr
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderInt32Ptr
|
||||
return nil, coderInt32Ptr
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSint32Ptr
|
||||
return nil, coderSint32Ptr
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderUint32Ptr
|
||||
return nil, coderUint32Ptr
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderInt64Ptr
|
||||
return nil, coderInt64Ptr
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSint64Ptr
|
||||
return nil, coderSint64Ptr
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderUint64Ptr
|
||||
return nil, coderUint64Ptr
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSfixed32Ptr
|
||||
return nil, coderSfixed32Ptr
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderFixed32Ptr
|
||||
return nil, coderFixed32Ptr
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return coderFloatPtr
|
||||
return nil, coderFloatPtr
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSfixed64Ptr
|
||||
return nil, coderSfixed64Ptr
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderFixed64Ptr
|
||||
return nil, coderFixed64Ptr
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return coderDoublePtr
|
||||
return nil, coderDoublePtr
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringPtr
|
||||
return nil, coderStringPtr
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderStringPtr
|
||||
return nil, coderStringPtr
|
||||
}
|
||||
}
|
||||
default:
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return coderBool
|
||||
return nil, coderBool
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderEnum
|
||||
return nil, coderEnum
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderInt32
|
||||
return nil, coderInt32
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSint32
|
||||
return nil, coderSint32
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderUint32
|
||||
return nil, coderUint32
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderInt64
|
||||
return nil, coderInt64
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSint64
|
||||
return nil, coderSint64
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderUint64
|
||||
return nil, coderUint64
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return coderSfixed32
|
||||
return nil, coderSfixed32
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return coderFixed32
|
||||
return nil, coderFixed32
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return coderFloat
|
||||
return nil, coderFloat
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return coderSfixed64
|
||||
return nil, coderSfixed64
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return coderFixed64
|
||||
return nil, coderFixed64
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return coderDouble
|
||||
return nil, coderDouble
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return coderStringValidateUTF8
|
||||
return nil, coderStringValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderString
|
||||
return nil, coderString
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return coderBytesValidateUTF8
|
||||
return nil, coderBytesValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytes
|
||||
return nil, coderBytes
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return coderString
|
||||
return nil, coderString
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return coderBytes
|
||||
return nil, coderBytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag wire.Numbe
|
||||
break
|
||||
}
|
||||
var o unmarshalOutput
|
||||
o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, opts)
|
||||
o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, f, opts)
|
||||
n = o.n
|
||||
if err != nil {
|
||||
break
|
||||
|
@ -69,7 +69,7 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int
|
||||
if f.isPointer && fptr.Elem().IsNil() {
|
||||
continue
|
||||
}
|
||||
size += f.funcs.size(fptr, f.tagsize, opts)
|
||||
size += f.funcs.size(fptr, f, opts)
|
||||
}
|
||||
if mi.unknownOffset.IsValid() {
|
||||
u := *p.Apply(mi.unknownOffset).Bytes()
|
||||
@ -119,7 +119,7 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
|
||||
if f.isPointer && fptr.Elem().IsNil() {
|
||||
continue
|
||||
}
|
||||
b, err = f.funcs.marshal(b, fptr, f.wiretag, opts)
|
||||
b, err = f.funcs.marshal(b, fptr, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (mi *MessageInfo) isInitializedPointer(p pointer) error {
|
||||
if f.funcs.isInit == nil {
|
||||
continue
|
||||
}
|
||||
if err := f.funcs.isInit(fptr); err != nil {
|
||||
if err := f.funcs.isInit(fptr, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user