diff --git a/internal/cmd/generate-types/impl.go b/internal/cmd/generate-types/impl.go index 6909994c..a2e2aa9d 100644 --- a/internal/cmd/generate-types/impl.go +++ b/internal/cmd/generate-types/impl.go @@ -50,6 +50,14 @@ b = wire.Append{{.WireType}}(b, {{.FromGoType}}) {{- end -}} {{- end -}} +{{- define "Consume" -}} +{{- if eq .Name "String" -}} +wire.ConsumeString(b) +{{- else -}} +wire.Consume{{.WireType}}(b) +{{- end -}} +{{- end -}} + {{- range .}} {{- if .FromGoType }} // size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}. @@ -68,9 +76,23 @@ func append{{.Name}}(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consume{{.Name}} wire decodes a {{.GoType}} pointer as a {{.Name}}. +func consume{{.Name}}(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != {{.WireType.Expr}} { + return 0, errUnknown + } + v, n := {{template "Consume" .}} + if n < 0 { + return 0, wire.ParseError(n) + } + *p.{{.GoType.PointerMethod}}() = {{.ToGoType}} + return n, nil +} + var coder{{.Name}} = pointerCoderFuncs{ - size: size{{.Name}}, - marshal: append{{.Name}}, + size: size{{.Name}}, + marshal: append{{.Name}}, + unmarshal: consume{{.Name}}, } // size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}. @@ -96,8 +118,9 @@ func append{{.Name}}NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions } var coder{{.Name}}NoZero = pointerCoderFuncs{ - size: size{{.Name}}NoZero, - marshal: append{{.Name}}NoZero, + size: size{{.Name}}NoZero, + marshal: append{{.Name}}NoZero, + unmarshal: consume{{.Name}}, } {{- if not .NoPointer}} @@ -110,7 +133,7 @@ func size{{.Name}}Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + {{template "Size" .}} } -// append{{.Name}} wire encodes a *{{.GoType}} pointer as a {{.Name}}. +// 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) { v := **p.{{.GoType.PointerMethod}}Ptr() @@ -119,9 +142,27 @@ func append{{.Name}}Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( 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) (n int, err error) { + if wtyp != {{.WireType.Expr}} { + return 0, errUnknown + } + v, n := {{template "Consume" .}} + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.{{.GoType.PointerMethod}}Ptr() + if *vp == nil { + *vp = new({{.GoType}}) + } + **vp = {{.ToGoType}} + return n, nil +} + var coder{{.Name}}Ptr = pointerCoderFuncs{ - size: size{{.Name}}Ptr, - marshal: append{{.Name}}Ptr, + size: size{{.Name}}Ptr, + marshal: append{{.Name}}Ptr, + unmarshal: consume{{.Name}}Ptr, } {{end}} @@ -148,9 +189,43 @@ func append{{.Name}}Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) 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) (n int, err error) { + sp := p.{{.GoType.PointerMethod}}Slice() + {{- if .WireType.Packable}} + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := {{template "Consume" .}} + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, {{.ToGoType}}) + b = b[n:] + } + *sp = s + return n, nil + } + {{- end}} + if wtyp != {{.WireType.Expr}} { + return 0, errUnknown + } + v, n := {{template "Consume" .}} + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, {{.ToGoType}}) + return n, nil +} + var coder{{.Name}}Slice = pointerCoderFuncs{ - size: size{{.Name}}Slice, - marshal: append{{.Name}}Slice, + size: size{{.Name}}Slice, + marshal: append{{.Name}}Slice, + unmarshal: consume{{.Name}}Slice, } {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}} @@ -194,8 +269,9 @@ func append{{.Name}}PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOp } var coder{{.Name}}PackedSlice = pointerCoderFuncs{ - size: size{{.Name}}PackedSlice, - marshal: append{{.Name}}PackedSlice, + size: size{{.Name}}PackedSlice, + marshal: append{{.Name}}PackedSlice, + unmarshal: consume{{.Name}}Slice, } {{end}} @@ -215,9 +291,22 @@ func append{{.Name}}Iface(b []byte, ival interface{}, wiretag uint64, _ marshalO return b, nil } +// consume{{.Name}}Iface decodes a {{.GoType}} value as a {{.Name}}. +func consume{{.Name}}Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != {{.WireType.Expr}} { + return nil, 0, errUnknown + } + v, n := {{template "Consume" .}} + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return {{.ToGoType}}, n, nil +} + var coder{{.Name}}Iface = ifaceCoderFuncs{ size: size{{.Name}}Iface, marshal: append{{.Name}}Iface, + unmarshal: consume{{.Name}}Iface, } // size{{.Name}}SliceIface returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}. @@ -243,9 +332,44 @@ func append{{.Name}}SliceIface(b []byte, ival interface{}, wiretag uint64, _ mar return b, nil } +// consume{{.Name}}SliceIface wire decodes a []{{.GoType}} value as a repeated {{.Name}}. +func consume{{.Name}}SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]{{.GoType}}) + {{- if .WireType.Packable}} + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := {{template "Consume" .}} + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, {{.ToGoType}}) + b = b[n:] + } + *sp = s + return ival, n, nil + } + {{- end}} + if wtyp != {{.WireType.Expr}} { + return nil, 0, errUnknown + } + v, n := {{template "Consume" .}} + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, {{.ToGoType}}) + return ival, n, nil +} + + var coder{{.Name}}SliceIface = ifaceCoderFuncs{ - size: size{{.Name}}SliceIface, - marshal: append{{.Name}}SliceIface, + size: size{{.Name}}SliceIface, + marshal: append{{.Name}}SliceIface, + unmarshal: consume{{.Name}}SliceIface, } {{end -}} diff --git a/internal/cmd/generate-types/proto.go b/internal/cmd/generate-types/proto.go index db20f0b4..e507b031 100644 --- a/internal/cmd/generate-types/proto.go +++ b/internal/cmd/generate-types/proto.go @@ -86,6 +86,7 @@ type ProtoKind struct { // Conversions to/from generated structures. GoType GoType + ToGoType Expr FromGoType Expr NoPointer bool } @@ -101,6 +102,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "wire.DecodeBool(v)", FromValue: "wire.EncodeBool(v.Bool())", GoType: GoBool, + ToGoType: "wire.DecodeBool(v)", FromGoType: "wire.EncodeBool(v)", }, { @@ -115,6 +117,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "int32(v)", FromValue: "uint64(int32(v.Int()))", GoType: GoInt32, + ToGoType: "int32(v)", FromGoType: "uint64(v)", }, { @@ -123,6 +126,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "int32(wire.DecodeZigZag(v & math.MaxUint32))", FromValue: "wire.EncodeZigZag(int64(int32(v.Int())))", GoType: GoInt32, + ToGoType: "int32(wire.DecodeZigZag(v & math.MaxUint32))", FromGoType: "wire.EncodeZigZag(int64(v))", }, { @@ -131,6 +135,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "uint32(v)", FromValue: "uint64(uint32(v.Uint()))", GoType: GoUint32, + ToGoType: "uint32(v)", FromGoType: "uint64(v)", }, { @@ -139,6 +144,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "int64(v)", FromValue: "uint64(v.Int())", GoType: GoInt64, + ToGoType: "int64(v)", FromGoType: "uint64(v)", }, { @@ -147,6 +153,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "wire.DecodeZigZag(v)", FromValue: "wire.EncodeZigZag(v.Int())", GoType: GoInt64, + ToGoType: "wire.DecodeZigZag(v)", FromGoType: "wire.EncodeZigZag(v)", }, { @@ -155,6 +162,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "v", FromValue: "v.Uint()", GoType: GoUint64, + ToGoType: "v", FromGoType: "v", }, { @@ -163,6 +171,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "int32(v)", FromValue: "uint32(v.Int())", GoType: GoInt32, + ToGoType: "int32(v)", FromGoType: "uint32(v)", }, { @@ -171,6 +180,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "uint32(v)", FromValue: "uint32(v.Uint())", GoType: GoUint32, + ToGoType: "v", FromGoType: "v", }, { @@ -179,6 +189,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "math.Float32frombits(uint32(v))", FromValue: "math.Float32bits(float32(v.Float()))", GoType: GoFloat32, + ToGoType: "math.Float32frombits(v)", FromGoType: "math.Float32bits(v)", }, { @@ -187,6 +198,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "int64(v)", FromValue: "uint64(v.Int())", GoType: GoInt64, + ToGoType: "int64(v)", FromGoType: "uint64(v)", }, { @@ -195,6 +207,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "v", FromValue: "v.Uint()", GoType: GoUint64, + ToGoType: "v", FromGoType: "v", }, { @@ -203,6 +216,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "math.Float64frombits(v)", FromValue: "math.Float64bits(v.Float())", GoType: GoFloat64, + ToGoType: "math.Float64frombits(v)", FromGoType: "math.Float64bits(v)", }, { @@ -211,6 +225,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "string(v)", FromValue: "v.String()", GoType: GoString, + ToGoType: "v", FromGoType: "v", }, { @@ -219,6 +234,7 @@ var ProtoKinds = []ProtoKind{ ToValue: "append(([]byte)(nil), v...)", FromValue: "v.Bytes()", GoType: GoBytes, + ToGoType: "append(([]byte)(nil), v...)", FromGoType: "v", NoPointer: true, }, diff --git a/internal/encoding/wire/wire.go b/internal/encoding/wire/wire.go index e66123a0..224ddf73 100644 --- a/internal/encoding/wire/wire.go +++ b/internal/encoding/wire/wire.go @@ -425,11 +425,6 @@ func AppendBytes(b []byte, v []byte) []byte { return append(AppendVarint(b, uint64(len(v))), v...) } -// AppendString appends v to b as a length-prefixed bytes value. -func AppendString(b []byte, v string) []byte { - return append(AppendVarint(b, uint64(len(v))), v...) -} - // ConsumeBytes parses b as a length-prefixed bytes value, reporting its length. // This returns a negative length upon an error (see ParseError). func ConsumeBytes(b []byte) (v []byte, n int) { @@ -449,6 +444,18 @@ func SizeBytes(n int) int { return SizeVarint(uint64(n)) + n } +// AppendString appends v to b as a length-prefixed bytes value. +func AppendString(b []byte, v string) []byte { + return append(AppendVarint(b, uint64(len(v))), v...) +} + +// ConsumeString parses b as a length-prefixed bytes value, reporting its length. +// This returns a negative length upon an error (see ParseError). +func ConsumeString(b []byte) (v string, n int) { + bb, n := ConsumeBytes(b) + return string(bb), n +} + // AppendGroup appends v to b as group value, with a trailing end group marker. // The value v must not contain the end marker. func AppendGroup(b []byte, num Number, v []byte) []byte { diff --git a/internal/impl/codec_extension.go b/internal/impl/codec_extension.go index 577f1df2..10a9fa25 100644 --- a/internal/impl/codec_extension.go +++ b/internal/impl/codec_extension.go @@ -13,9 +13,10 @@ import ( ) type extensionFieldInfo struct { - wiretag uint64 - tagsize int - funcs ifaceCoderFuncs + wiretag uint64 + tagsize int + unmarshalNeedsValue bool + funcs ifaceCoderFuncs } func (mi *MessageInfo) extensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { @@ -34,7 +35,17 @@ func (mi *MessageInfo) extensionFieldInfo(xt pref.ExtensionType) *extensionField tagsize: wire.SizeVarint(wiretag), funcs: encoderFuncsForValue(xt, xt.GoType()), } - + // Does the unmarshal function need a value passed to it? + // This is true for composite types, where we pass in a message, list, or map to fill in, + // and for enums, where we pass in a prototype value to specify the concrete enum type. + switch xt.Kind() { + case pref.MessageKind, pref.GroupKind, pref.EnumKind: + e.unmarshalNeedsValue = true + default: + if xt.Cardinality() == pref.Repeated { + e.unmarshalNeedsValue = true + } + } mi.extensionFieldInfosMu.Lock() if mi.extensionFieldInfos == nil { mi.extensionFieldInfos = make(map[pref.ExtensionType]*extensionFieldInfo) diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go index 15124c00..09389b02 100644 --- a/internal/impl/codec_field.go +++ b/internal/impl/codec_field.go @@ -5,7 +5,6 @@ package impl import ( - "fmt" "reflect" "unicode/utf8" @@ -19,61 +18,59 @@ type errInvalidUTF8 struct{} func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" } func (errInvalidUTF8) InvalidUTF8() bool { return true } -func makeOneofFieldCoder(fs reflect.StructField, od pref.OneofDescriptor, structFields map[pref.FieldNumber]reflect.StructField, otypes map[pref.FieldNumber]reflect.Type) pointerCoderFuncs { - type oneofFieldInfo struct { - wiretag uint64 - tagsize int - funcs pointerCoderFuncs - } - - oneofFieldInfos := make(map[reflect.Type]oneofFieldInfo) - for i, fields := 0, od.Fields(); i < fields.Len(); i++ { - fd := fields.Get(i) - ot := otypes[fd.Number()] - wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) - oneofFieldInfos[ot] = oneofFieldInfo{ - wiretag: wiretag, - tagsize: wire.SizeVarint(wiretag), - funcs: fieldCoder(fd, ot.Field(0).Type), - } - } +func makeOneofFieldCoder(si structInfo, fd pref.FieldDescriptor) pointerCoderFuncs { + ot := si.oneofWrappersByNumber[fd.Number()] + funcs := fieldCoder(fd, ot.Field(0).Type) + fs := si.oneofsByName[fd.ContainingOneof().Name()] ft := fs.Type - getInfo := func(p pointer) (pointer, oneofFieldInfo) { + wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) + tagsize := wire.SizeVarint(wiretag) + getInfo := func(p pointer) (pointer, bool) { v := p.AsValueOf(ft).Elem() if v.IsNil() { - return pointer{}, oneofFieldInfo{} + return pointer{}, false } v = v.Elem() // interface -> *struct - telem := v.Elem().Type() - info, ok := oneofFieldInfos[telem] - if !ok { - panic(fmt.Errorf("invalid oneof type %v", telem)) + if v.Elem().Type() != ot { + return pointer{}, false } - return pointerOfValue(v).Apply(zeroOffset), info + return pointerOfValue(v).Apply(zeroOffset), true } - return pointerCoderFuncs{ + pcf := pointerCoderFuncs{ size: func(p pointer, _ int, opts marshalOptions) int { - v, info := getInfo(p) - if info.funcs.size == nil { + v, ok := getInfo(p) + if !ok { return 0 } - return info.funcs.size(v, info.tagsize, opts) + return funcs.size(v, tagsize, opts) }, marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { - v, info := getInfo(p) - if info.funcs.marshal == nil { + v, ok := getInfo(p) + if !ok { return b, nil } - return info.funcs.marshal(b, v, info.wiretag, opts) + return funcs.marshal(b, v, wiretag, opts) }, - isInit: func(p pointer) error { - v, info := getInfo(p) - if info.funcs.isInit == nil { - return nil + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + v := reflect.New(ot) + n, err := funcs.unmarshal(b, pointerOfValue(v).Apply(zeroOffset), wtyp, opts) + if err != nil { + return 0, err } - return info.funcs.isInit(v) + p.AsValueOf(ft).Elem().Set(v) + return n, nil }, } + if funcs.isInit != nil { + pcf.isInit = func(p pointer) error { + v, ok := getInfo(p) + if !ok { + return nil + } + return funcs.isInit(v) + } + } + return pcf } func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { @@ -85,6 +82,9 @@ func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCode marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendMessageInfo(b, p, wiretag, fi, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeMessageInfo(b, p, fi, wtyp, opts) + }, isInit: func(p pointer) error { return fi.isInitializedPointer(p.Elem()) }, @@ -99,6 +99,13 @@ func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCode m := asMessage(p.AsValueOf(ft).Elem()) return appendMessage(b, m, wiretag, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, 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 { m := asMessage(p.AsValueOf(ft).Elem()) return proto.IsInitialized(m) @@ -117,6 +124,23 @@ func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opt return mi.marshalAppendPointer(b, p.Elem(), opts) } +func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + if p.Elem().IsNil() { + p.SetPointer(pointerOfValue(reflect.New(mi.GoType.Elem()))) + } + if _, err := mi.unmarshalPointer(v, p.Elem(), 0, opts); err != nil { + return 0, err + } + return n, nil +} + func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int { return wire.SizeBytes(proto.Size(m)) + tagsize } @@ -127,6 +151,20 @@ func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOption return opts.Options().MarshalAppend(b, m) } +func consumeMessage(b []byte, m proto.Message, wtyp wire.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + if err := opts.Options().Unmarshal(v, m); err != nil { + return 0, err + } + return n, nil +} + func sizeMessageIface(ival interface{}, tagsize int, opts marshalOptions) int { m := Export{}.MessageOf(ival).Interface() return sizeMessage(m, tagsize, opts) @@ -137,18 +175,26 @@ func appendMessageIface(b []byte, ival interface{}, wiretag uint64, opts marshal return appendMessage(b, m, wiretag, opts) } +func consumeMessageIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) { + m := Export{}.MessageOf(ival).Interface() + n, err := consumeMessage(b, m, wtyp, opts) + return ival, n, err +} + func isInitMessageIface(ival interface{}) error { m := Export{}.MessageOf(ival).Interface() return proto.IsInitialized(m) } var coderMessageIface = ifaceCoderFuncs{ - size: sizeMessageIface, - marshal: appendMessageIface, - isInit: isInitMessageIface, + size: sizeMessageIface, + marshal: appendMessageIface, + unmarshal: consumeMessageIface, + isInit: isInitMessageIface, } func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { + num := fd.Number() if fi, ok := getMessageInfo(ft); ok { return pointerCoderFuncs{ size: func(p pointer, tagsize int, opts marshalOptions) int { @@ -157,6 +203,9 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendGroupType(b, p, wiretag, fi, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeGroupType(b, p, fi, num, wtyp, opts) + }, isInit: func(p pointer) error { return fi.isInitializedPointer(p.Elem()) }, @@ -171,6 +220,13 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF m := asMessage(p.AsValueOf(ft).Elem()) return appendGroup(b, m, wiretag, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, 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 { m := asMessage(p.AsValueOf(ft).Elem()) return proto.IsInitialized(m) @@ -190,6 +246,16 @@ func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts return b, err } +func consumeGroupType(b []byte, p pointer, mi *MessageInfo, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.StartGroupType { + return 0, errUnknown + } + if p.Elem().IsNil() { + p.SetPointer(pointerOfValue(reflect.New(mi.GoType.Elem()))) + } + return mi.unmarshalPointer(b, p.Elem(), num, opts) +} + func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int { return 2*tagsize + proto.Size(m) } @@ -201,30 +267,47 @@ func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) return b, err } -func sizeGroupIface(ival interface{}, tagsize int, opts marshalOptions) int { - m := Export{}.MessageOf(ival).Interface() - return sizeGroup(m, tagsize, opts) +func consumeGroup(b []byte, m proto.Message, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.StartGroupType { + return 0, errUnknown + } + b, n := wire.ConsumeGroup(num, b) + if n < 0 { + return 0, wire.ParseError(n) + } + return n, opts.Options().Unmarshal(b, m) } -func appendGroupIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) { - m := Export{}.MessageOf(ival).Interface() - return appendGroup(b, m, wiretag, opts) -} - -var coderGroupIface = ifaceCoderFuncs{ - size: sizeGroupIface, - marshal: appendGroupIface, - isInit: isInitMessageIface, +func makeGroupValueCoder(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFuncs { + return ifaceCoderFuncs{ + size: func(ival interface{}, tagsize int, opts marshalOptions) int { + m := Export{}.MessageOf(ival).Interface() + return sizeGroup(m, tagsize, opts) + }, + marshal: func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) { + m := Export{}.MessageOf(ival).Interface() + return appendGroup(b, m, wiretag, opts) + }, + unmarshal: func(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) { + m := Export{}.MessageOf(ival).Interface() + n, err := consumeGroup(b, m, num, wtyp, opts) + return ival, n, err + }, + isInit: isInitMessageIface, + } } func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { if fi, ok := getMessageInfo(ft); ok { return pointerCoderFuncs{ + size: func(p pointer, tagsize int, opts marshalOptions) int { + return sizeMessageSliceInfo(p, fi, tagsize, opts) + }, marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendMessageSliceInfo(b, p, wiretag, fi, opts) }, - size: func(p pointer, tagsize int, opts marshalOptions) int { - return sizeMessageSliceInfo(p, fi, tagsize, opts) + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeMessageSliceInfo(b, p, fi, wtyp, opts) }, isInit: func(p pointer) error { return isInitMessageSliceInfo(p, fi) @@ -238,6 +321,9 @@ func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointe marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendMessageSlice(b, p, wiretag, ft, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeMessageSlice(b, p, ft, wtyp, opts) + }, isInit: func(p pointer) error { return isInitMessageSlice(p, ft) }, @@ -268,6 +354,23 @@ 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) (int, error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + m := reflect.New(mi.GoType.Elem()).Interface() + mp := pointerOfIface(m) + if _, err := mi.unmarshalPointer(v, mp, 0, opts); err != nil { + return 0, err + } + p.AppendPointerSlice(mp) + return n, nil +} + func isInitMessageSliceInfo(p pointer, mi *MessageInfo) error { s := p.PointerSlice() for _, v := range s { @@ -282,7 +385,7 @@ func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOpti s := p.PointerSlice() n := 0 for _, v := range s { - m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface() + m := asMessage(v.AsValueOf(goType.Elem())) n += wire.SizeBytes(proto.Size(m)) + tagsize } return n @@ -292,7 +395,7 @@ func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type s := p.PointerSlice() var err error for _, v := range s { - m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface() + m := asMessage(v.AsValueOf(goType.Elem())) b = wire.AppendVarint(b, wiretag) siz := proto.Size(m) b = wire.AppendVarint(b, uint64(siz)) @@ -304,10 +407,26 @@ func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type return b, nil } +func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp wire.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + mp := reflect.New(goType.Elem()) + if err := opts.Options().Unmarshal(v, asMessage(mp)); err != nil { + return 0, err + } + p.AppendPointerSlice(pointerOfValue(mp)) + return n, nil +} + func isInitMessageSlice(p pointer, goType reflect.Type) error { s := p.PointerSlice() for _, v := range s { - m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface() + m := asMessage(v.AsValueOf(goType.Elem())) if err := proto.IsInitialized(m); err != nil { return err } @@ -327,18 +446,26 @@ func appendMessageSliceIface(b []byte, ival interface{}, wiretag uint64, opts ma return appendMessageSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts) } +func consumeMessageSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) { + p := pointerOfIface(ival) + n, err := consumeMessageSlice(b, p, reflect.TypeOf(ival).Elem().Elem(), wtyp, opts) + return ival, n, err +} + func isInitMessageSliceIface(ival interface{}) error { p := pointerOfIface(ival) return isInitMessageSlice(p, reflect.TypeOf(ival).Elem().Elem()) } var coderMessageSliceIface = ifaceCoderFuncs{ - size: sizeMessageSliceIface, - marshal: appendMessageSliceIface, - isInit: isInitMessageSliceIface, + size: sizeMessageSliceIface, + marshal: appendMessageSliceIface, + unmarshal: consumeMessageSliceIface, + isInit: isInitMessageSliceIface, } func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { + num := fd.Number() if fi, ok := getMessageInfo(ft); ok { return pointerCoderFuncs{ size: func(p pointer, tagsize int, opts marshalOptions) int { @@ -347,6 +474,9 @@ func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerC marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendGroupSliceInfo(b, p, wiretag, fi, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeGroupSliceInfo(b, p, num, wtyp, fi, opts) + }, isInit: func(p pointer) error { return isInitMessageSliceInfo(p, fi) }, @@ -359,6 +489,9 @@ func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerC marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendGroupSlice(b, p, wiretag, ft, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeGroupSlice(b, p, num, wtyp, ft, opts) + }, isInit: func(p pointer) error { return isInitMessageSlice(p, ft) }, @@ -369,7 +502,7 @@ func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalO s := p.PointerSlice() n := 0 for _, v := range s { - m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface() + m := asMessage(v.AsValueOf(messageType.Elem())) n += 2*tagsize + proto.Size(m) } return n @@ -379,7 +512,7 @@ func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.T s := p.PointerSlice() var err error for _, v := range s { - m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface() + m := asMessage(v.AsValueOf(messageType.Elem())) b = wire.AppendVarint(b, wiretag) // start group b, err = opts.Options().MarshalAppend(b, m) if err != nil { @@ -390,6 +523,22 @@ func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.T return b, nil } +func consumeGroupSlice(b []byte, p pointer, num wire.Number, wtyp wire.Type, goType reflect.Type, opts unmarshalOptions) (int, error) { + if wtyp != wire.StartGroupType { + return 0, errUnknown + } + b, n := wire.ConsumeGroup(num, b) + if n < 0 { + return 0, wire.ParseError(n) + } + mp := reflect.New(goType.Elem()) + if err := opts.Options().Unmarshal(b, asMessage(mp)); err != nil { + return 0, err + } + p.AppendPointerSlice(pointerOfValue(mp)) + return n, nil +} + func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int { s := p.PointerSlice() n := 0 @@ -413,6 +562,20 @@ func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, return b, nil } +func consumeGroupSliceInfo(b []byte, p pointer, num wire.Number, wtyp wire.Type, mi *MessageInfo, opts unmarshalOptions) (int, error) { + if wtyp != wire.StartGroupType { + return 0, errUnknown + } + m := reflect.New(mi.GoType.Elem()).Interface() + mp := pointerOfIface(m) + n, err := mi.unmarshalPointer(b, mp, num, opts) + if err != nil { + return 0, err + } + p.AppendPointerSlice(mp) + return n, nil +} + func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int { p := pointerOfIface(ival) return sizeGroupSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts) @@ -423,10 +586,17 @@ func appendGroupSliceIface(b []byte, ival interface{}, wiretag uint64, opts mars return appendGroupSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts) } +func consumeGroupSliceIface(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) { + p := pointerOfIface(ival) + n, err := consumeGroupSlice(b, p, num, wtyp, reflect.TypeOf(ival).Elem().Elem(), opts) + return ival, n, err +} + var coderGroupSliceIface = ifaceCoderFuncs{ - size: sizeGroupSliceIface, - marshal: appendGroupSliceIface, - isInit: isInitMessageSliceIface, + size: sizeGroupSliceIface, + marshal: appendGroupSliceIface, + unmarshal: consumeGroupSliceIface, + isInit: isInitMessageSliceIface, } // Enums @@ -443,9 +613,23 @@ func appendEnumIface(b []byte, ival interface{}, wiretag uint64, _ marshalOption return b, nil } +func consumeEnumIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + rv := reflect.New(reflect.TypeOf(ival)).Elem() + rv.SetInt(int64(v)) + return rv.Interface(), n, nil +} + var coderEnumIface = ifaceCoderFuncs{ - size: sizeEnumIface, - marshal: appendEnumIface, + size: sizeEnumIface, + marshal: appendEnumIface, + unmarshal: consumeEnumIface, } func sizeEnumSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) { @@ -471,9 +655,47 @@ func appendEnumSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts mars return b, nil } +func consumeEnumSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) { + n, err := consumeEnumSliceReflect(b, reflect.ValueOf(ival), wtyp, opts) + return ival, n, err +} + +func consumeEnumSliceReflect(b []byte, s reflect.Value, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + s = s.Elem() // *[]E -> []E + if wtyp == wire.BytesType { + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + rv := reflect.New(s.Type().Elem()).Elem() + rv.SetInt(int64(v)) + s.Set(reflect.Append(s, rv)) + b = b[n:] + } + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + rv := reflect.New(s.Type().Elem()).Elem() + rv.SetInt(int64(v)) + s.Set(reflect.Append(s, rv)) + return n, nil +} + var coderEnumSliceIface = ifaceCoderFuncs{ - size: sizeEnumSliceIface, - marshal: appendEnumSliceIface, + size: sizeEnumSliceIface, + marshal: appendEnumSliceIface, + unmarshal: consumeEnumSliceIface, } // Strings with UTF8 validation. @@ -488,9 +710,25 @@ func appendStringValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOpti return b, nil } +func consumeStringValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return 0, wire.ParseError(n) + } + if !utf8.ValidString(v) { + return 0, errInvalidUTF8{} + } + *p.String() = v + return n, nil +} + var coderStringValidateUTF8 = pointerCoderFuncs{ - size: sizeString, - marshal: appendStringValidateUTF8, + size: sizeString, + marshal: appendStringValidateUTF8, + unmarshal: consumeStringValidateUTF8, } func appendStringNoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { @@ -507,8 +745,9 @@ func appendStringNoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marsh } var coderStringNoZeroValidateUTF8 = pointerCoderFuncs{ - size: sizeStringNoZero, - marshal: appendStringNoZeroValidateUTF8, + size: sizeStringNoZero, + marshal: appendStringNoZeroValidateUTF8, + unmarshal: consumeStringValidateUTF8, } func sizeStringSliceValidateUTF8(p pointer, tagsize int, _ marshalOptions) (size int) { @@ -526,15 +765,32 @@ func appendStringSliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marsha b = wire.AppendVarint(b, wiretag) b = wire.AppendString(b, v) if !utf8.ValidString(v) { - err = errInvalidUTF8{} + return b, errInvalidUTF8{} } } return b, err } +func consumeStringSliceValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + sp := p.StringSlice() + v, n := wire.ConsumeString(b) + if n < 0 { + return 0, wire.ParseError(n) + } + if !utf8.ValidString(v) { + return 0, errInvalidUTF8{} + } + *sp = append(*sp, v) + return n, nil +} + var coderStringSliceValidateUTF8 = pointerCoderFuncs{ - size: sizeStringSliceValidateUTF8, - marshal: appendStringSliceValidateUTF8, + size: sizeStringSliceValidateUTF8, + marshal: appendStringSliceValidateUTF8, + unmarshal: consumeStringSliceValidateUTF8, } func sizeStringIfaceValidateUTF8(ival interface{}, tagsize int, _ marshalOptions) int { @@ -552,9 +808,24 @@ func appendStringIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ return b, nil } +func consumeStringIfaceValidateUTF8(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.BytesType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + if !utf8.ValidString(v) { + return nil, 0, errInvalidUTF8{} + } + return v, n, nil +} + var coderStringIfaceValidateUTF8 = ifaceCoderFuncs{ - size: sizeStringIfaceValidateUTF8, - marshal: appendStringIfaceValidateUTF8, + size: sizeStringIfaceValidateUTF8, + marshal: appendStringIfaceValidateUTF8, + unmarshal: consumeStringIfaceValidateUTF8, } func asMessage(v reflect.Value) pref.ProtoMessage { diff --git a/internal/impl/codec_gen.go b/internal/impl/codec_gen.go index 7dbb0bc8..f04e3c52 100644 --- a/internal/impl/codec_gen.go +++ b/internal/impl/codec_gen.go @@ -27,9 +27,23 @@ func appendBool(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, return b, nil } +// consumeBool wire decodes a bool pointer as a Bool. +func consumeBool(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Bool() = wire.DecodeBool(v) + return n, nil +} + var coderBool = pointerCoderFuncs{ - size: sizeBool, - marshal: appendBool, + size: sizeBool, + marshal: appendBool, + unmarshal: consumeBool, } // sizeBool returns the size of wire encoding a bool pointer as a Bool. @@ -55,8 +69,9 @@ func appendBoolNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] } var coderBoolNoZero = pointerCoderFuncs{ - size: sizeBoolNoZero, - marshal: appendBoolNoZero, + size: sizeBoolNoZero, + marshal: appendBoolNoZero, + unmarshal: consumeBool, } // sizeBoolPtr returns the size of wire encoding a *bool pointer as a Bool. @@ -66,7 +81,7 @@ func sizeBoolPtr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(wire.EncodeBool(v)) } -// appendBool wire encodes a *bool pointer as a Bool. +// appendBoolPtr wire encodes a *bool pointer as a Bool. // It panics if the pointer is nil. func appendBoolPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.BoolPtr() @@ -75,9 +90,27 @@ func appendBoolPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byt return b, nil } +// consumeBoolPtr wire decodes a *bool pointer as a Bool. +func consumeBoolPtr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.BoolPtr() + if *vp == nil { + *vp = new(bool) + } + **vp = wire.DecodeBool(v) + return n, nil +} + var coderBoolPtr = pointerCoderFuncs{ - size: sizeBoolPtr, - marshal: appendBoolPtr, + size: sizeBoolPtr, + marshal: appendBoolPtr, + unmarshal: consumeBoolPtr, } // sizeBoolSlice returns the size of wire encoding a []bool pointer as a repeated Bool. @@ -99,9 +132,41 @@ func appendBoolSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeBoolSlice wire decodes a []bool pointer as a repeated Bool. +func consumeBoolSlice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.BoolSlice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, wire.DecodeBool(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, wire.DecodeBool(v)) + return n, nil +} + var coderBoolSlice = pointerCoderFuncs{ - size: sizeBoolSlice, - marshal: appendBoolSlice, + size: sizeBoolSlice, + marshal: appendBoolSlice, + unmarshal: consumeBoolSlice, } // sizeBoolPackedSlice returns the size of wire encoding a []bool pointer as a packed repeated Bool. @@ -136,8 +201,9 @@ func appendBoolPackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions } var coderBoolPackedSlice = pointerCoderFuncs{ - size: sizeBoolPackedSlice, - marshal: appendBoolPackedSlice, + size: sizeBoolPackedSlice, + marshal: appendBoolPackedSlice, + unmarshal: consumeBoolSlice, } // sizeBoolIface returns the size of wire encoding a bool value as a Bool. @@ -154,9 +220,22 @@ func appendBoolIface(b []byte, ival interface{}, wiretag uint64, _ marshalOption return b, nil } +// consumeBoolIface decodes a bool value as a Bool. +func consumeBoolIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return wire.DecodeBool(v), n, nil +} + var coderBoolIface = ifaceCoderFuncs{ - size: sizeBoolIface, - marshal: appendBoolIface, + size: sizeBoolIface, + marshal: appendBoolIface, + unmarshal: consumeBoolIface, } // sizeBoolSliceIface returns the size of wire encoding a []bool value as a repeated Bool. @@ -178,9 +257,41 @@ func appendBoolSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalO return b, nil } +// consumeBoolSliceIface wire decodes a []bool value as a repeated Bool. +func consumeBoolSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]bool) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, wire.DecodeBool(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, wire.DecodeBool(v)) + return ival, n, nil +} + var coderBoolSliceIface = ifaceCoderFuncs{ - size: sizeBoolSliceIface, - marshal: appendBoolSliceIface, + size: sizeBoolSliceIface, + marshal: appendBoolSliceIface, + unmarshal: consumeBoolSliceIface, } // sizeInt32 returns the size of wire encoding a int32 pointer as a Int32. @@ -197,9 +308,23 @@ func appendInt32(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, return b, nil } +// consumeInt32 wire decodes a int32 pointer as a Int32. +func consumeInt32(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int32() = int32(v) + return n, nil +} + var coderInt32 = pointerCoderFuncs{ - size: sizeInt32, - marshal: appendInt32, + size: sizeInt32, + marshal: appendInt32, + unmarshal: consumeInt32, } // sizeInt32 returns the size of wire encoding a int32 pointer as a Int32. @@ -225,8 +350,9 @@ func appendInt32NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ } var coderInt32NoZero = pointerCoderFuncs{ - size: sizeInt32NoZero, - marshal: appendInt32NoZero, + size: sizeInt32NoZero, + marshal: appendInt32NoZero, + unmarshal: consumeInt32, } // sizeInt32Ptr returns the size of wire encoding a *int32 pointer as a Int32. @@ -236,7 +362,7 @@ func sizeInt32Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(uint64(v)) } -// appendInt32 wire encodes a *int32 pointer as a Int32. +// appendInt32Ptr wire encodes a *int32 pointer as a Int32. // It panics if the pointer is nil. func appendInt32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int32Ptr() @@ -245,9 +371,27 @@ func appendInt32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]by return b, nil } +// consumeInt32Ptr wire decodes a *int32 pointer as a Int32. +func consumeInt32Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int32Ptr() + if *vp == nil { + *vp = new(int32) + } + **vp = int32(v) + return n, nil +} + var coderInt32Ptr = pointerCoderFuncs{ - size: sizeInt32Ptr, - marshal: appendInt32Ptr, + size: sizeInt32Ptr, + marshal: appendInt32Ptr, + unmarshal: consumeInt32Ptr, } // sizeInt32Slice returns the size of wire encoding a []int32 pointer as a repeated Int32. @@ -269,9 +413,41 @@ func appendInt32Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeInt32Slice wire decodes a []int32 pointer as a repeated Int32. +func consumeInt32Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, int32(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, int32(v)) + return n, nil +} + var coderInt32Slice = pointerCoderFuncs{ - size: sizeInt32Slice, - marshal: appendInt32Slice, + size: sizeInt32Slice, + marshal: appendInt32Slice, + unmarshal: consumeInt32Slice, } // sizeInt32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Int32. @@ -306,8 +482,9 @@ func appendInt32PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOption } var coderInt32PackedSlice = pointerCoderFuncs{ - size: sizeInt32PackedSlice, - marshal: appendInt32PackedSlice, + size: sizeInt32PackedSlice, + marshal: appendInt32PackedSlice, + unmarshal: consumeInt32Slice, } // sizeInt32Iface returns the size of wire encoding a int32 value as a Int32. @@ -324,9 +501,22 @@ func appendInt32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptio return b, nil } +// consumeInt32Iface decodes a int32 value as a Int32. +func consumeInt32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return int32(v), n, nil +} + var coderInt32Iface = ifaceCoderFuncs{ - size: sizeInt32Iface, - marshal: appendInt32Iface, + size: sizeInt32Iface, + marshal: appendInt32Iface, + unmarshal: consumeInt32Iface, } // sizeInt32SliceIface returns the size of wire encoding a []int32 value as a repeated Int32. @@ -348,9 +538,41 @@ func appendInt32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshal return b, nil } +// consumeInt32SliceIface wire decodes a []int32 value as a repeated Int32. +func consumeInt32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, int32(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, int32(v)) + return ival, n, nil +} + var coderInt32SliceIface = ifaceCoderFuncs{ - size: sizeInt32SliceIface, - marshal: appendInt32SliceIface, + size: sizeInt32SliceIface, + marshal: appendInt32SliceIface, + unmarshal: consumeInt32SliceIface, } // sizeSint32 returns the size of wire encoding a int32 pointer as a Sint32. @@ -367,9 +589,23 @@ func appendSint32(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeSint32 wire decodes a int32 pointer as a Sint32. +func consumeSint32(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int32() = int32(wire.DecodeZigZag(v & math.MaxUint32)) + return n, nil +} + var coderSint32 = pointerCoderFuncs{ - size: sizeSint32, - marshal: appendSint32, + size: sizeSint32, + marshal: appendSint32, + unmarshal: consumeSint32, } // sizeSint32 returns the size of wire encoding a int32 pointer as a Sint32. @@ -395,8 +631,9 @@ func appendSint32NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderSint32NoZero = pointerCoderFuncs{ - size: sizeSint32NoZero, - marshal: appendSint32NoZero, + size: sizeSint32NoZero, + marshal: appendSint32NoZero, + unmarshal: consumeSint32, } // sizeSint32Ptr returns the size of wire encoding a *int32 pointer as a Sint32. @@ -406,7 +643,7 @@ func sizeSint32Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(wire.EncodeZigZag(int64(v))) } -// appendSint32 wire encodes a *int32 pointer as a Sint32. +// appendSint32Ptr wire encodes a *int32 pointer as a Sint32. // It panics if the pointer is nil. func appendSint32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int32Ptr() @@ -415,9 +652,27 @@ func appendSint32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeSint32Ptr wire decodes a *int32 pointer as a Sint32. +func consumeSint32Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int32Ptr() + if *vp == nil { + *vp = new(int32) + } + **vp = int32(wire.DecodeZigZag(v & math.MaxUint32)) + return n, nil +} + var coderSint32Ptr = pointerCoderFuncs{ - size: sizeSint32Ptr, - marshal: appendSint32Ptr, + size: sizeSint32Ptr, + marshal: appendSint32Ptr, + unmarshal: consumeSint32Ptr, } // sizeSint32Slice returns the size of wire encoding a []int32 pointer as a repeated Sint32. @@ -439,9 +694,41 @@ func appendSint32Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeSint32Slice wire decodes a []int32 pointer as a repeated Sint32. +func consumeSint32Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, int32(wire.DecodeZigZag(v&math.MaxUint32))) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, int32(wire.DecodeZigZag(v&math.MaxUint32))) + return n, nil +} + var coderSint32Slice = pointerCoderFuncs{ - size: sizeSint32Slice, - marshal: appendSint32Slice, + size: sizeSint32Slice, + marshal: appendSint32Slice, + unmarshal: consumeSint32Slice, } // sizeSint32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Sint32. @@ -476,8 +763,9 @@ func appendSint32PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptio } var coderSint32PackedSlice = pointerCoderFuncs{ - size: sizeSint32PackedSlice, - marshal: appendSint32PackedSlice, + size: sizeSint32PackedSlice, + marshal: appendSint32PackedSlice, + unmarshal: consumeSint32Slice, } // sizeSint32Iface returns the size of wire encoding a int32 value as a Sint32. @@ -494,9 +782,22 @@ func appendSint32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeSint32Iface decodes a int32 value as a Sint32. +func consumeSint32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return int32(wire.DecodeZigZag(v & math.MaxUint32)), n, nil +} + var coderSint32Iface = ifaceCoderFuncs{ - size: sizeSint32Iface, - marshal: appendSint32Iface, + size: sizeSint32Iface, + marshal: appendSint32Iface, + unmarshal: consumeSint32Iface, } // sizeSint32SliceIface returns the size of wire encoding a []int32 value as a repeated Sint32. @@ -518,9 +819,41 @@ func appendSint32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeSint32SliceIface wire decodes a []int32 value as a repeated Sint32. +func consumeSint32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, int32(wire.DecodeZigZag(v&math.MaxUint32))) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, int32(wire.DecodeZigZag(v&math.MaxUint32))) + return ival, n, nil +} + var coderSint32SliceIface = ifaceCoderFuncs{ - size: sizeSint32SliceIface, - marshal: appendSint32SliceIface, + size: sizeSint32SliceIface, + marshal: appendSint32SliceIface, + unmarshal: consumeSint32SliceIface, } // sizeUint32 returns the size of wire encoding a uint32 pointer as a Uint32. @@ -537,9 +870,23 @@ func appendUint32(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeUint32 wire decodes a uint32 pointer as a Uint32. +func consumeUint32(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Uint32() = uint32(v) + return n, nil +} + var coderUint32 = pointerCoderFuncs{ - size: sizeUint32, - marshal: appendUint32, + size: sizeUint32, + marshal: appendUint32, + unmarshal: consumeUint32, } // sizeUint32 returns the size of wire encoding a uint32 pointer as a Uint32. @@ -565,8 +912,9 @@ func appendUint32NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderUint32NoZero = pointerCoderFuncs{ - size: sizeUint32NoZero, - marshal: appendUint32NoZero, + size: sizeUint32NoZero, + marshal: appendUint32NoZero, + unmarshal: consumeUint32, } // sizeUint32Ptr returns the size of wire encoding a *uint32 pointer as a Uint32. @@ -576,7 +924,7 @@ func sizeUint32Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(uint64(v)) } -// appendUint32 wire encodes a *uint32 pointer as a Uint32. +// appendUint32Ptr wire encodes a *uint32 pointer as a Uint32. // It panics if the pointer is nil. func appendUint32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Uint32Ptr() @@ -585,9 +933,27 @@ func appendUint32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeUint32Ptr wire decodes a *uint32 pointer as a Uint32. +func consumeUint32Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Uint32Ptr() + if *vp == nil { + *vp = new(uint32) + } + **vp = uint32(v) + return n, nil +} + var coderUint32Ptr = pointerCoderFuncs{ - size: sizeUint32Ptr, - marshal: appendUint32Ptr, + size: sizeUint32Ptr, + marshal: appendUint32Ptr, + unmarshal: consumeUint32Ptr, } // sizeUint32Slice returns the size of wire encoding a []uint32 pointer as a repeated Uint32. @@ -609,9 +975,41 @@ func appendUint32Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeUint32Slice wire decodes a []uint32 pointer as a repeated Uint32. +func consumeUint32Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Uint32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, uint32(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, uint32(v)) + return n, nil +} + var coderUint32Slice = pointerCoderFuncs{ - size: sizeUint32Slice, - marshal: appendUint32Slice, + size: sizeUint32Slice, + marshal: appendUint32Slice, + unmarshal: consumeUint32Slice, } // sizeUint32PackedSlice returns the size of wire encoding a []uint32 pointer as a packed repeated Uint32. @@ -646,8 +1044,9 @@ func appendUint32PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptio } var coderUint32PackedSlice = pointerCoderFuncs{ - size: sizeUint32PackedSlice, - marshal: appendUint32PackedSlice, + size: sizeUint32PackedSlice, + marshal: appendUint32PackedSlice, + unmarshal: consumeUint32Slice, } // sizeUint32Iface returns the size of wire encoding a uint32 value as a Uint32. @@ -664,9 +1063,22 @@ func appendUint32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeUint32Iface decodes a uint32 value as a Uint32. +func consumeUint32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return uint32(v), n, nil +} + var coderUint32Iface = ifaceCoderFuncs{ - size: sizeUint32Iface, - marshal: appendUint32Iface, + size: sizeUint32Iface, + marshal: appendUint32Iface, + unmarshal: consumeUint32Iface, } // sizeUint32SliceIface returns the size of wire encoding a []uint32 value as a repeated Uint32. @@ -688,9 +1100,41 @@ func appendUint32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeUint32SliceIface wire decodes a []uint32 value as a repeated Uint32. +func consumeUint32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]uint32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, uint32(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, uint32(v)) + return ival, n, nil +} + var coderUint32SliceIface = ifaceCoderFuncs{ - size: sizeUint32SliceIface, - marshal: appendUint32SliceIface, + size: sizeUint32SliceIface, + marshal: appendUint32SliceIface, + unmarshal: consumeUint32SliceIface, } // sizeInt64 returns the size of wire encoding a int64 pointer as a Int64. @@ -707,9 +1151,23 @@ func appendInt64(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, return b, nil } +// consumeInt64 wire decodes a int64 pointer as a Int64. +func consumeInt64(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int64() = int64(v) + return n, nil +} + var coderInt64 = pointerCoderFuncs{ - size: sizeInt64, - marshal: appendInt64, + size: sizeInt64, + marshal: appendInt64, + unmarshal: consumeInt64, } // sizeInt64 returns the size of wire encoding a int64 pointer as a Int64. @@ -735,8 +1193,9 @@ func appendInt64NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ } var coderInt64NoZero = pointerCoderFuncs{ - size: sizeInt64NoZero, - marshal: appendInt64NoZero, + size: sizeInt64NoZero, + marshal: appendInt64NoZero, + unmarshal: consumeInt64, } // sizeInt64Ptr returns the size of wire encoding a *int64 pointer as a Int64. @@ -746,7 +1205,7 @@ func sizeInt64Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(uint64(v)) } -// appendInt64 wire encodes a *int64 pointer as a Int64. +// appendInt64Ptr wire encodes a *int64 pointer as a Int64. // It panics if the pointer is nil. func appendInt64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int64Ptr() @@ -755,9 +1214,27 @@ func appendInt64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]by return b, nil } +// consumeInt64Ptr wire decodes a *int64 pointer as a Int64. +func consumeInt64Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int64Ptr() + if *vp == nil { + *vp = new(int64) + } + **vp = int64(v) + return n, nil +} + var coderInt64Ptr = pointerCoderFuncs{ - size: sizeInt64Ptr, - marshal: appendInt64Ptr, + size: sizeInt64Ptr, + marshal: appendInt64Ptr, + unmarshal: consumeInt64Ptr, } // sizeInt64Slice returns the size of wire encoding a []int64 pointer as a repeated Int64. @@ -779,9 +1256,41 @@ func appendInt64Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeInt64Slice wire decodes a []int64 pointer as a repeated Int64. +func consumeInt64Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, int64(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, int64(v)) + return n, nil +} + var coderInt64Slice = pointerCoderFuncs{ - size: sizeInt64Slice, - marshal: appendInt64Slice, + size: sizeInt64Slice, + marshal: appendInt64Slice, + unmarshal: consumeInt64Slice, } // sizeInt64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Int64. @@ -816,8 +1325,9 @@ func appendInt64PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOption } var coderInt64PackedSlice = pointerCoderFuncs{ - size: sizeInt64PackedSlice, - marshal: appendInt64PackedSlice, + size: sizeInt64PackedSlice, + marshal: appendInt64PackedSlice, + unmarshal: consumeInt64Slice, } // sizeInt64Iface returns the size of wire encoding a int64 value as a Int64. @@ -834,9 +1344,22 @@ func appendInt64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptio return b, nil } +// consumeInt64Iface decodes a int64 value as a Int64. +func consumeInt64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return int64(v), n, nil +} + var coderInt64Iface = ifaceCoderFuncs{ - size: sizeInt64Iface, - marshal: appendInt64Iface, + size: sizeInt64Iface, + marshal: appendInt64Iface, + unmarshal: consumeInt64Iface, } // sizeInt64SliceIface returns the size of wire encoding a []int64 value as a repeated Int64. @@ -858,9 +1381,41 @@ func appendInt64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshal return b, nil } +// consumeInt64SliceIface wire decodes a []int64 value as a repeated Int64. +func consumeInt64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, int64(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, int64(v)) + return ival, n, nil +} + var coderInt64SliceIface = ifaceCoderFuncs{ - size: sizeInt64SliceIface, - marshal: appendInt64SliceIface, + size: sizeInt64SliceIface, + marshal: appendInt64SliceIface, + unmarshal: consumeInt64SliceIface, } // sizeSint64 returns the size of wire encoding a int64 pointer as a Sint64. @@ -877,9 +1432,23 @@ func appendSint64(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeSint64 wire decodes a int64 pointer as a Sint64. +func consumeSint64(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int64() = wire.DecodeZigZag(v) + return n, nil +} + var coderSint64 = pointerCoderFuncs{ - size: sizeSint64, - marshal: appendSint64, + size: sizeSint64, + marshal: appendSint64, + unmarshal: consumeSint64, } // sizeSint64 returns the size of wire encoding a int64 pointer as a Sint64. @@ -905,8 +1474,9 @@ func appendSint64NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderSint64NoZero = pointerCoderFuncs{ - size: sizeSint64NoZero, - marshal: appendSint64NoZero, + size: sizeSint64NoZero, + marshal: appendSint64NoZero, + unmarshal: consumeSint64, } // sizeSint64Ptr returns the size of wire encoding a *int64 pointer as a Sint64. @@ -916,7 +1486,7 @@ func sizeSint64Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(wire.EncodeZigZag(v)) } -// appendSint64 wire encodes a *int64 pointer as a Sint64. +// appendSint64Ptr wire encodes a *int64 pointer as a Sint64. // It panics if the pointer is nil. func appendSint64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int64Ptr() @@ -925,9 +1495,27 @@ func appendSint64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeSint64Ptr wire decodes a *int64 pointer as a Sint64. +func consumeSint64Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int64Ptr() + if *vp == nil { + *vp = new(int64) + } + **vp = wire.DecodeZigZag(v) + return n, nil +} + var coderSint64Ptr = pointerCoderFuncs{ - size: sizeSint64Ptr, - marshal: appendSint64Ptr, + size: sizeSint64Ptr, + marshal: appendSint64Ptr, + unmarshal: consumeSint64Ptr, } // sizeSint64Slice returns the size of wire encoding a []int64 pointer as a repeated Sint64. @@ -949,9 +1537,41 @@ func appendSint64Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeSint64Slice wire decodes a []int64 pointer as a repeated Sint64. +func consumeSint64Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, wire.DecodeZigZag(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, wire.DecodeZigZag(v)) + return n, nil +} + var coderSint64Slice = pointerCoderFuncs{ - size: sizeSint64Slice, - marshal: appendSint64Slice, + size: sizeSint64Slice, + marshal: appendSint64Slice, + unmarshal: consumeSint64Slice, } // sizeSint64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Sint64. @@ -986,8 +1606,9 @@ func appendSint64PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptio } var coderSint64PackedSlice = pointerCoderFuncs{ - size: sizeSint64PackedSlice, - marshal: appendSint64PackedSlice, + size: sizeSint64PackedSlice, + marshal: appendSint64PackedSlice, + unmarshal: consumeSint64Slice, } // sizeSint64Iface returns the size of wire encoding a int64 value as a Sint64. @@ -1004,9 +1625,22 @@ func appendSint64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeSint64Iface decodes a int64 value as a Sint64. +func consumeSint64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return wire.DecodeZigZag(v), n, nil +} + var coderSint64Iface = ifaceCoderFuncs{ - size: sizeSint64Iface, - marshal: appendSint64Iface, + size: sizeSint64Iface, + marshal: appendSint64Iface, + unmarshal: consumeSint64Iface, } // sizeSint64SliceIface returns the size of wire encoding a []int64 value as a repeated Sint64. @@ -1028,9 +1662,41 @@ func appendSint64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeSint64SliceIface wire decodes a []int64 value as a repeated Sint64. +func consumeSint64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, wire.DecodeZigZag(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, wire.DecodeZigZag(v)) + return ival, n, nil +} + var coderSint64SliceIface = ifaceCoderFuncs{ - size: sizeSint64SliceIface, - marshal: appendSint64SliceIface, + size: sizeSint64SliceIface, + marshal: appendSint64SliceIface, + unmarshal: consumeSint64SliceIface, } // sizeUint64 returns the size of wire encoding a uint64 pointer as a Uint64. @@ -1047,9 +1713,23 @@ func appendUint64(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeUint64 wire decodes a uint64 pointer as a Uint64. +func consumeUint64(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Uint64() = v + return n, nil +} + var coderUint64 = pointerCoderFuncs{ - size: sizeUint64, - marshal: appendUint64, + size: sizeUint64, + marshal: appendUint64, + unmarshal: consumeUint64, } // sizeUint64 returns the size of wire encoding a uint64 pointer as a Uint64. @@ -1075,8 +1755,9 @@ func appendUint64NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderUint64NoZero = pointerCoderFuncs{ - size: sizeUint64NoZero, - marshal: appendUint64NoZero, + size: sizeUint64NoZero, + marshal: appendUint64NoZero, + unmarshal: consumeUint64, } // sizeUint64Ptr returns the size of wire encoding a *uint64 pointer as a Uint64. @@ -1086,7 +1767,7 @@ func sizeUint64Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeVarint(v) } -// appendUint64 wire encodes a *uint64 pointer as a Uint64. +// appendUint64Ptr wire encodes a *uint64 pointer as a Uint64. // It panics if the pointer is nil. func appendUint64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Uint64Ptr() @@ -1095,9 +1776,27 @@ func appendUint64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeUint64Ptr wire decodes a *uint64 pointer as a Uint64. +func consumeUint64Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Uint64Ptr() + if *vp == nil { + *vp = new(uint64) + } + **vp = v + return n, nil +} + var coderUint64Ptr = pointerCoderFuncs{ - size: sizeUint64Ptr, - marshal: appendUint64Ptr, + size: sizeUint64Ptr, + marshal: appendUint64Ptr, + unmarshal: consumeUint64Ptr, } // sizeUint64Slice returns the size of wire encoding a []uint64 pointer as a repeated Uint64. @@ -1119,9 +1818,41 @@ func appendUint64Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeUint64Slice wire decodes a []uint64 pointer as a repeated Uint64. +func consumeUint64Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Uint64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return n, nil +} + var coderUint64Slice = pointerCoderFuncs{ - size: sizeUint64Slice, - marshal: appendUint64Slice, + size: sizeUint64Slice, + marshal: appendUint64Slice, + unmarshal: consumeUint64Slice, } // sizeUint64PackedSlice returns the size of wire encoding a []uint64 pointer as a packed repeated Uint64. @@ -1156,8 +1887,9 @@ func appendUint64PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptio } var coderUint64PackedSlice = pointerCoderFuncs{ - size: sizeUint64PackedSlice, - marshal: appendUint64PackedSlice, + size: sizeUint64PackedSlice, + marshal: appendUint64PackedSlice, + unmarshal: consumeUint64Slice, } // sizeUint64Iface returns the size of wire encoding a uint64 value as a Uint64. @@ -1174,9 +1906,22 @@ func appendUint64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeUint64Iface decodes a uint64 value as a Uint64. +func consumeUint64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return v, n, nil +} + var coderUint64Iface = ifaceCoderFuncs{ - size: sizeUint64Iface, - marshal: appendUint64Iface, + size: sizeUint64Iface, + marshal: appendUint64Iface, + unmarshal: consumeUint64Iface, } // sizeUint64SliceIface returns the size of wire encoding a []uint64 value as a repeated Uint64. @@ -1198,9 +1943,41 @@ func appendUint64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeUint64SliceIface wire decodes a []uint64 value as a repeated Uint64. +func consumeUint64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]uint64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.VarintType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return ival, n, nil +} + var coderUint64SliceIface = ifaceCoderFuncs{ - size: sizeUint64SliceIface, - marshal: appendUint64SliceIface, + size: sizeUint64SliceIface, + marshal: appendUint64SliceIface, + unmarshal: consumeUint64SliceIface, } // sizeSfixed32 returns the size of wire encoding a int32 pointer as a Sfixed32. @@ -1217,9 +1994,23 @@ func appendSfixed32(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]by return b, nil } +// consumeSfixed32 wire decodes a int32 pointer as a Sfixed32. +func consumeSfixed32(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int32() = int32(v) + return n, nil +} + var coderSfixed32 = pointerCoderFuncs{ - size: sizeSfixed32, - marshal: appendSfixed32, + size: sizeSfixed32, + marshal: appendSfixed32, + unmarshal: consumeSfixed32, } // sizeSfixed32 returns the size of wire encoding a int32 pointer as a Sfixed32. @@ -1245,8 +2036,9 @@ func appendSfixed32NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) } var coderSfixed32NoZero = pointerCoderFuncs{ - size: sizeSfixed32NoZero, - marshal: appendSfixed32NoZero, + size: sizeSfixed32NoZero, + marshal: appendSfixed32NoZero, + unmarshal: consumeSfixed32, } // sizeSfixed32Ptr returns the size of wire encoding a *int32 pointer as a Sfixed32. @@ -1255,7 +2047,7 @@ func sizeSfixed32Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed32() } -// appendSfixed32 wire encodes a *int32 pointer as a Sfixed32. +// appendSfixed32Ptr wire encodes a *int32 pointer as a Sfixed32. // It panics if the pointer is nil. func appendSfixed32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int32Ptr() @@ -1264,9 +2056,27 @@ func appendSfixed32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeSfixed32Ptr wire decodes a *int32 pointer as a Sfixed32. +func consumeSfixed32Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int32Ptr() + if *vp == nil { + *vp = new(int32) + } + **vp = int32(v) + return n, nil +} + var coderSfixed32Ptr = pointerCoderFuncs{ - size: sizeSfixed32Ptr, - marshal: appendSfixed32Ptr, + size: sizeSfixed32Ptr, + marshal: appendSfixed32Ptr, + unmarshal: consumeSfixed32Ptr, } // sizeSfixed32Slice returns the size of wire encoding a []int32 pointer as a repeated Sfixed32. @@ -1286,9 +2096,41 @@ func appendSfixed32Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) return b, nil } +// consumeSfixed32Slice wire decodes a []int32 pointer as a repeated Sfixed32. +func consumeSfixed32Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, int32(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, int32(v)) + return n, nil +} + var coderSfixed32Slice = pointerCoderFuncs{ - size: sizeSfixed32Slice, - marshal: appendSfixed32Slice, + size: sizeSfixed32Slice, + marshal: appendSfixed32Slice, + unmarshal: consumeSfixed32Slice, } // sizeSfixed32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Sfixed32. @@ -1317,8 +2159,9 @@ func appendSfixed32PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOpt } var coderSfixed32PackedSlice = pointerCoderFuncs{ - size: sizeSfixed32PackedSlice, - marshal: appendSfixed32PackedSlice, + size: sizeSfixed32PackedSlice, + marshal: appendSfixed32PackedSlice, + unmarshal: consumeSfixed32Slice, } // sizeSfixed32Iface returns the size of wire encoding a int32 value as a Sfixed32. @@ -1334,9 +2177,22 @@ func appendSfixed32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOp return b, nil } +// consumeSfixed32Iface decodes a int32 value as a Sfixed32. +func consumeSfixed32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return int32(v), n, nil +} + var coderSfixed32Iface = ifaceCoderFuncs{ - size: sizeSfixed32Iface, - marshal: appendSfixed32Iface, + size: sizeSfixed32Iface, + marshal: appendSfixed32Iface, + unmarshal: consumeSfixed32Iface, } // sizeSfixed32SliceIface returns the size of wire encoding a []int32 value as a repeated Sfixed32. @@ -1356,9 +2212,41 @@ func appendSfixed32SliceIface(b []byte, ival interface{}, wiretag uint64, _ mars return b, nil } +// consumeSfixed32SliceIface wire decodes a []int32 value as a repeated Sfixed32. +func consumeSfixed32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, int32(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, int32(v)) + return ival, n, nil +} + var coderSfixed32SliceIface = ifaceCoderFuncs{ - size: sizeSfixed32SliceIface, - marshal: appendSfixed32SliceIface, + size: sizeSfixed32SliceIface, + marshal: appendSfixed32SliceIface, + unmarshal: consumeSfixed32SliceIface, } // sizeFixed32 returns the size of wire encoding a uint32 pointer as a Fixed32. @@ -1375,9 +2263,23 @@ func appendFixed32(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byt return b, nil } +// consumeFixed32 wire decodes a uint32 pointer as a Fixed32. +func consumeFixed32(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Uint32() = v + return n, nil +} + var coderFixed32 = pointerCoderFuncs{ - size: sizeFixed32, - marshal: appendFixed32, + size: sizeFixed32, + marshal: appendFixed32, + unmarshal: consumeFixed32, } // sizeFixed32 returns the size of wire encoding a uint32 pointer as a Fixed32. @@ -1403,8 +2305,9 @@ func appendFixed32NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) } var coderFixed32NoZero = pointerCoderFuncs{ - size: sizeFixed32NoZero, - marshal: appendFixed32NoZero, + size: sizeFixed32NoZero, + marshal: appendFixed32NoZero, + unmarshal: consumeFixed32, } // sizeFixed32Ptr returns the size of wire encoding a *uint32 pointer as a Fixed32. @@ -1413,7 +2316,7 @@ func sizeFixed32Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed32() } -// appendFixed32 wire encodes a *uint32 pointer as a Fixed32. +// appendFixed32Ptr wire encodes a *uint32 pointer as a Fixed32. // It panics if the pointer is nil. func appendFixed32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Uint32Ptr() @@ -1422,9 +2325,27 @@ func appendFixed32Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeFixed32Ptr wire decodes a *uint32 pointer as a Fixed32. +func consumeFixed32Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Uint32Ptr() + if *vp == nil { + *vp = new(uint32) + } + **vp = v + return n, nil +} + var coderFixed32Ptr = pointerCoderFuncs{ - size: sizeFixed32Ptr, - marshal: appendFixed32Ptr, + size: sizeFixed32Ptr, + marshal: appendFixed32Ptr, + unmarshal: consumeFixed32Ptr, } // sizeFixed32Slice returns the size of wire encoding a []uint32 pointer as a repeated Fixed32. @@ -1444,9 +2365,41 @@ func appendFixed32Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( return b, nil } +// consumeFixed32Slice wire decodes a []uint32 pointer as a repeated Fixed32. +func consumeFixed32Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Uint32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return n, nil +} + var coderFixed32Slice = pointerCoderFuncs{ - size: sizeFixed32Slice, - marshal: appendFixed32Slice, + size: sizeFixed32Slice, + marshal: appendFixed32Slice, + unmarshal: consumeFixed32Slice, } // sizeFixed32PackedSlice returns the size of wire encoding a []uint32 pointer as a packed repeated Fixed32. @@ -1475,8 +2428,9 @@ func appendFixed32PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOpti } var coderFixed32PackedSlice = pointerCoderFuncs{ - size: sizeFixed32PackedSlice, - marshal: appendFixed32PackedSlice, + size: sizeFixed32PackedSlice, + marshal: appendFixed32PackedSlice, + unmarshal: consumeFixed32Slice, } // sizeFixed32Iface returns the size of wire encoding a uint32 value as a Fixed32. @@ -1492,9 +2446,22 @@ func appendFixed32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpt return b, nil } +// consumeFixed32Iface decodes a uint32 value as a Fixed32. +func consumeFixed32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return v, n, nil +} + var coderFixed32Iface = ifaceCoderFuncs{ - size: sizeFixed32Iface, - marshal: appendFixed32Iface, + size: sizeFixed32Iface, + marshal: appendFixed32Iface, + unmarshal: consumeFixed32Iface, } // sizeFixed32SliceIface returns the size of wire encoding a []uint32 value as a repeated Fixed32. @@ -1514,9 +2481,41 @@ func appendFixed32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsh return b, nil } +// consumeFixed32SliceIface wire decodes a []uint32 value as a repeated Fixed32. +func consumeFixed32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]uint32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return ival, n, nil +} + var coderFixed32SliceIface = ifaceCoderFuncs{ - size: sizeFixed32SliceIface, - marshal: appendFixed32SliceIface, + size: sizeFixed32SliceIface, + marshal: appendFixed32SliceIface, + unmarshal: consumeFixed32SliceIface, } // sizeFloat returns the size of wire encoding a float32 pointer as a Float. @@ -1533,9 +2532,23 @@ func appendFloat(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, return b, nil } +// consumeFloat wire decodes a float32 pointer as a Float. +func consumeFloat(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Float32() = math.Float32frombits(v) + return n, nil +} + var coderFloat = pointerCoderFuncs{ - size: sizeFloat, - marshal: appendFloat, + size: sizeFloat, + marshal: appendFloat, + unmarshal: consumeFloat, } // sizeFloat returns the size of wire encoding a float32 pointer as a Float. @@ -1561,8 +2574,9 @@ func appendFloatNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ } var coderFloatNoZero = pointerCoderFuncs{ - size: sizeFloatNoZero, - marshal: appendFloatNoZero, + size: sizeFloatNoZero, + marshal: appendFloatNoZero, + unmarshal: consumeFloat, } // sizeFloatPtr returns the size of wire encoding a *float32 pointer as a Float. @@ -1571,7 +2585,7 @@ func sizeFloatPtr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed32() } -// appendFloat wire encodes a *float32 pointer as a Float. +// appendFloatPtr wire encodes a *float32 pointer as a Float. // It panics if the pointer is nil. func appendFloatPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Float32Ptr() @@ -1580,9 +2594,27 @@ func appendFloatPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]by return b, nil } +// consumeFloatPtr wire decodes a *float32 pointer as a Float. +func consumeFloatPtr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Float32Ptr() + if *vp == nil { + *vp = new(float32) + } + **vp = math.Float32frombits(v) + return n, nil +} + var coderFloatPtr = pointerCoderFuncs{ - size: sizeFloatPtr, - marshal: appendFloatPtr, + size: sizeFloatPtr, + marshal: appendFloatPtr, + unmarshal: consumeFloatPtr, } // sizeFloatSlice returns the size of wire encoding a []float32 pointer as a repeated Float. @@ -1602,9 +2634,41 @@ func appendFloatSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeFloatSlice wire decodes a []float32 pointer as a repeated Float. +func consumeFloatSlice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Float32Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, math.Float32frombits(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed32Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, math.Float32frombits(v)) + return n, nil +} + var coderFloatSlice = pointerCoderFuncs{ - size: sizeFloatSlice, - marshal: appendFloatSlice, + size: sizeFloatSlice, + marshal: appendFloatSlice, + unmarshal: consumeFloatSlice, } // sizeFloatPackedSlice returns the size of wire encoding a []float32 pointer as a packed repeated Float. @@ -1633,8 +2697,9 @@ func appendFloatPackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOption } var coderFloatPackedSlice = pointerCoderFuncs{ - size: sizeFloatPackedSlice, - marshal: appendFloatPackedSlice, + size: sizeFloatPackedSlice, + marshal: appendFloatPackedSlice, + unmarshal: consumeFloatSlice, } // sizeFloatIface returns the size of wire encoding a float32 value as a Float. @@ -1650,9 +2715,22 @@ func appendFloatIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptio return b, nil } +// consumeFloatIface decodes a float32 value as a Float. +func consumeFloatIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return math.Float32frombits(v), n, nil +} + var coderFloatIface = ifaceCoderFuncs{ - size: sizeFloatIface, - marshal: appendFloatIface, + size: sizeFloatIface, + marshal: appendFloatIface, + unmarshal: consumeFloatIface, } // sizeFloatSliceIface returns the size of wire encoding a []float32 value as a repeated Float. @@ -1672,9 +2750,41 @@ func appendFloatSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshal return b, nil } +// consumeFloatSliceIface wire decodes a []float32 value as a repeated Float. +func consumeFloatSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]float32) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, math.Float32frombits(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed32Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed32(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, math.Float32frombits(v)) + return ival, n, nil +} + var coderFloatSliceIface = ifaceCoderFuncs{ - size: sizeFloatSliceIface, - marshal: appendFloatSliceIface, + size: sizeFloatSliceIface, + marshal: appendFloatSliceIface, + unmarshal: consumeFloatSliceIface, } // sizeSfixed64 returns the size of wire encoding a int64 pointer as a Sfixed64. @@ -1691,9 +2801,23 @@ func appendSfixed64(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]by return b, nil } +// consumeSfixed64 wire decodes a int64 pointer as a Sfixed64. +func consumeSfixed64(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Int64() = int64(v) + return n, nil +} + var coderSfixed64 = pointerCoderFuncs{ - size: sizeSfixed64, - marshal: appendSfixed64, + size: sizeSfixed64, + marshal: appendSfixed64, + unmarshal: consumeSfixed64, } // sizeSfixed64 returns the size of wire encoding a int64 pointer as a Sfixed64. @@ -1719,8 +2843,9 @@ func appendSfixed64NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) } var coderSfixed64NoZero = pointerCoderFuncs{ - size: sizeSfixed64NoZero, - marshal: appendSfixed64NoZero, + size: sizeSfixed64NoZero, + marshal: appendSfixed64NoZero, + unmarshal: consumeSfixed64, } // sizeSfixed64Ptr returns the size of wire encoding a *int64 pointer as a Sfixed64. @@ -1729,7 +2854,7 @@ func sizeSfixed64Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed64() } -// appendSfixed64 wire encodes a *int64 pointer as a Sfixed64. +// appendSfixed64Ptr wire encodes a *int64 pointer as a Sfixed64. // It panics if the pointer is nil. func appendSfixed64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Int64Ptr() @@ -1738,9 +2863,27 @@ func appendSfixed64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeSfixed64Ptr wire decodes a *int64 pointer as a Sfixed64. +func consumeSfixed64Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Int64Ptr() + if *vp == nil { + *vp = new(int64) + } + **vp = int64(v) + return n, nil +} + var coderSfixed64Ptr = pointerCoderFuncs{ - size: sizeSfixed64Ptr, - marshal: appendSfixed64Ptr, + size: sizeSfixed64Ptr, + marshal: appendSfixed64Ptr, + unmarshal: consumeSfixed64Ptr, } // sizeSfixed64Slice returns the size of wire encoding a []int64 pointer as a repeated Sfixed64. @@ -1760,9 +2903,41 @@ func appendSfixed64Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) return b, nil } +// consumeSfixed64Slice wire decodes a []int64 pointer as a repeated Sfixed64. +func consumeSfixed64Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Int64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, int64(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, int64(v)) + return n, nil +} + var coderSfixed64Slice = pointerCoderFuncs{ - size: sizeSfixed64Slice, - marshal: appendSfixed64Slice, + size: sizeSfixed64Slice, + marshal: appendSfixed64Slice, + unmarshal: consumeSfixed64Slice, } // sizeSfixed64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Sfixed64. @@ -1791,8 +2966,9 @@ func appendSfixed64PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOpt } var coderSfixed64PackedSlice = pointerCoderFuncs{ - size: sizeSfixed64PackedSlice, - marshal: appendSfixed64PackedSlice, + size: sizeSfixed64PackedSlice, + marshal: appendSfixed64PackedSlice, + unmarshal: consumeSfixed64Slice, } // sizeSfixed64Iface returns the size of wire encoding a int64 value as a Sfixed64. @@ -1808,9 +2984,22 @@ func appendSfixed64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOp return b, nil } +// consumeSfixed64Iface decodes a int64 value as a Sfixed64. +func consumeSfixed64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return int64(v), n, nil +} + var coderSfixed64Iface = ifaceCoderFuncs{ - size: sizeSfixed64Iface, - marshal: appendSfixed64Iface, + size: sizeSfixed64Iface, + marshal: appendSfixed64Iface, + unmarshal: consumeSfixed64Iface, } // sizeSfixed64SliceIface returns the size of wire encoding a []int64 value as a repeated Sfixed64. @@ -1830,9 +3019,41 @@ func appendSfixed64SliceIface(b []byte, ival interface{}, wiretag uint64, _ mars return b, nil } +// consumeSfixed64SliceIface wire decodes a []int64 value as a repeated Sfixed64. +func consumeSfixed64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]int64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, int64(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, int64(v)) + return ival, n, nil +} + var coderSfixed64SliceIface = ifaceCoderFuncs{ - size: sizeSfixed64SliceIface, - marshal: appendSfixed64SliceIface, + size: sizeSfixed64SliceIface, + marshal: appendSfixed64SliceIface, + unmarshal: consumeSfixed64SliceIface, } // sizeFixed64 returns the size of wire encoding a uint64 pointer as a Fixed64. @@ -1849,9 +3070,23 @@ func appendFixed64(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byt return b, nil } +// consumeFixed64 wire decodes a uint64 pointer as a Fixed64. +func consumeFixed64(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Uint64() = v + return n, nil +} + var coderFixed64 = pointerCoderFuncs{ - size: sizeFixed64, - marshal: appendFixed64, + size: sizeFixed64, + marshal: appendFixed64, + unmarshal: consumeFixed64, } // sizeFixed64 returns the size of wire encoding a uint64 pointer as a Fixed64. @@ -1877,8 +3112,9 @@ func appendFixed64NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) } var coderFixed64NoZero = pointerCoderFuncs{ - size: sizeFixed64NoZero, - marshal: appendFixed64NoZero, + size: sizeFixed64NoZero, + marshal: appendFixed64NoZero, + unmarshal: consumeFixed64, } // sizeFixed64Ptr returns the size of wire encoding a *uint64 pointer as a Fixed64. @@ -1887,7 +3123,7 @@ func sizeFixed64Ptr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed64() } -// appendFixed64 wire encodes a *uint64 pointer as a Fixed64. +// appendFixed64Ptr wire encodes a *uint64 pointer as a Fixed64. // It panics if the pointer is nil. func appendFixed64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Uint64Ptr() @@ -1896,9 +3132,27 @@ func appendFixed64Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeFixed64Ptr wire decodes a *uint64 pointer as a Fixed64. +func consumeFixed64Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Uint64Ptr() + if *vp == nil { + *vp = new(uint64) + } + **vp = v + return n, nil +} + var coderFixed64Ptr = pointerCoderFuncs{ - size: sizeFixed64Ptr, - marshal: appendFixed64Ptr, + size: sizeFixed64Ptr, + marshal: appendFixed64Ptr, + unmarshal: consumeFixed64Ptr, } // sizeFixed64Slice returns the size of wire encoding a []uint64 pointer as a repeated Fixed64. @@ -1918,9 +3172,41 @@ func appendFixed64Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( return b, nil } +// consumeFixed64Slice wire decodes a []uint64 pointer as a repeated Fixed64. +func consumeFixed64Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Uint64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return n, nil +} + var coderFixed64Slice = pointerCoderFuncs{ - size: sizeFixed64Slice, - marshal: appendFixed64Slice, + size: sizeFixed64Slice, + marshal: appendFixed64Slice, + unmarshal: consumeFixed64Slice, } // sizeFixed64PackedSlice returns the size of wire encoding a []uint64 pointer as a packed repeated Fixed64. @@ -1949,8 +3235,9 @@ func appendFixed64PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOpti } var coderFixed64PackedSlice = pointerCoderFuncs{ - size: sizeFixed64PackedSlice, - marshal: appendFixed64PackedSlice, + size: sizeFixed64PackedSlice, + marshal: appendFixed64PackedSlice, + unmarshal: consumeFixed64Slice, } // sizeFixed64Iface returns the size of wire encoding a uint64 value as a Fixed64. @@ -1966,9 +3253,22 @@ func appendFixed64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOpt return b, nil } +// consumeFixed64Iface decodes a uint64 value as a Fixed64. +func consumeFixed64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return v, n, nil +} + var coderFixed64Iface = ifaceCoderFuncs{ - size: sizeFixed64Iface, - marshal: appendFixed64Iface, + size: sizeFixed64Iface, + marshal: appendFixed64Iface, + unmarshal: consumeFixed64Iface, } // sizeFixed64SliceIface returns the size of wire encoding a []uint64 value as a repeated Fixed64. @@ -1988,9 +3288,41 @@ func appendFixed64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marsh return b, nil } +// consumeFixed64SliceIface wire decodes a []uint64 value as a repeated Fixed64. +func consumeFixed64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]uint64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, v) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return ival, n, nil +} + var coderFixed64SliceIface = ifaceCoderFuncs{ - size: sizeFixed64SliceIface, - marshal: appendFixed64SliceIface, + size: sizeFixed64SliceIface, + marshal: appendFixed64SliceIface, + unmarshal: consumeFixed64SliceIface, } // sizeDouble returns the size of wire encoding a float64 pointer as a Double. @@ -2007,9 +3339,23 @@ func appendDouble(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeDouble wire decodes a float64 pointer as a Double. +func consumeDouble(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Float64() = math.Float64frombits(v) + return n, nil +} + var coderDouble = pointerCoderFuncs{ - size: sizeDouble, - marshal: appendDouble, + size: sizeDouble, + marshal: appendDouble, + unmarshal: consumeDouble, } // sizeDouble returns the size of wire encoding a float64 pointer as a Double. @@ -2035,8 +3381,9 @@ func appendDoubleNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderDoubleNoZero = pointerCoderFuncs{ - size: sizeDoubleNoZero, - marshal: appendDoubleNoZero, + size: sizeDoubleNoZero, + marshal: appendDoubleNoZero, + unmarshal: consumeDouble, } // sizeDoublePtr returns the size of wire encoding a *float64 pointer as a Double. @@ -2045,7 +3392,7 @@ func sizeDoublePtr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeFixed64() } -// appendDouble wire encodes a *float64 pointer as a Double. +// appendDoublePtr wire encodes a *float64 pointer as a Double. // It panics if the pointer is nil. func appendDoublePtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.Float64Ptr() @@ -2054,9 +3401,27 @@ func appendDoublePtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeDoublePtr wire decodes a *float64 pointer as a Double. +func consumeDoublePtr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.Float64Ptr() + if *vp == nil { + *vp = new(float64) + } + **vp = math.Float64frombits(v) + return n, nil +} + var coderDoublePtr = pointerCoderFuncs{ - size: sizeDoublePtr, - marshal: appendDoublePtr, + size: sizeDoublePtr, + marshal: appendDoublePtr, + unmarshal: consumeDoublePtr, } // sizeDoubleSlice returns the size of wire encoding a []float64 pointer as a repeated Double. @@ -2076,9 +3441,41 @@ func appendDoubleSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeDoubleSlice wire decodes a []float64 pointer as a repeated Double. +func consumeDoubleSlice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.Float64Slice() + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + s = append(s, math.Float64frombits(v)) + b = b[n:] + } + *sp = s + return n, nil + } + if wtyp != wire.Fixed64Type { + return 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, math.Float64frombits(v)) + return n, nil +} + var coderDoubleSlice = pointerCoderFuncs{ - size: sizeDoubleSlice, - marshal: appendDoubleSlice, + size: sizeDoubleSlice, + marshal: appendDoubleSlice, + unmarshal: consumeDoubleSlice, } // sizeDoublePackedSlice returns the size of wire encoding a []float64 pointer as a packed repeated Double. @@ -2107,8 +3504,9 @@ func appendDoublePackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptio } var coderDoublePackedSlice = pointerCoderFuncs{ - size: sizeDoublePackedSlice, - marshal: appendDoublePackedSlice, + size: sizeDoublePackedSlice, + marshal: appendDoublePackedSlice, + unmarshal: consumeDoubleSlice, } // sizeDoubleIface returns the size of wire encoding a float64 value as a Double. @@ -2124,9 +3522,22 @@ func appendDoubleIface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeDoubleIface decodes a float64 value as a Double. +func consumeDoubleIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return math.Float64frombits(v), n, nil +} + var coderDoubleIface = ifaceCoderFuncs{ - size: sizeDoubleIface, - marshal: appendDoubleIface, + size: sizeDoubleIface, + marshal: appendDoubleIface, + unmarshal: consumeDoubleIface, } // sizeDoubleSliceIface returns the size of wire encoding a []float64 value as a repeated Double. @@ -2146,9 +3557,41 @@ func appendDoubleSliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeDoubleSliceIface wire decodes a []float64 value as a repeated Double. +func consumeDoubleSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]float64) + if wtyp == wire.BytesType { + s := *sp + b, n = wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + for len(b) > 0 { + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + s = append(s, math.Float64frombits(v)) + b = b[n:] + } + *sp = s + return ival, n, nil + } + if wtyp != wire.Fixed64Type { + return nil, 0, errUnknown + } + v, n := wire.ConsumeFixed64(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, math.Float64frombits(v)) + return ival, n, nil +} + var coderDoubleSliceIface = ifaceCoderFuncs{ - size: sizeDoubleSliceIface, - marshal: appendDoubleSliceIface, + size: sizeDoubleSliceIface, + marshal: appendDoubleSliceIface, + unmarshal: consumeDoubleSliceIface, } // sizeString returns the size of wire encoding a string pointer as a String. @@ -2165,9 +3608,23 @@ func appendString(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte return b, nil } +// consumeString wire decodes a string pointer as a String. +func consumeString(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.String() = v + return n, nil +} + var coderString = pointerCoderFuncs{ - size: sizeString, - marshal: appendString, + size: sizeString, + marshal: appendString, + unmarshal: consumeString, } // sizeString returns the size of wire encoding a string pointer as a String. @@ -2193,8 +3650,9 @@ func appendStringNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ( } var coderStringNoZero = pointerCoderFuncs{ - size: sizeStringNoZero, - marshal: appendStringNoZero, + size: sizeStringNoZero, + marshal: appendStringNoZero, + unmarshal: consumeString, } // sizeStringPtr returns the size of wire encoding a *string pointer as a String. @@ -2204,7 +3662,7 @@ func sizeStringPtr(p pointer, tagsize int, _ marshalOptions) (size int) { return tagsize + wire.SizeBytes(len(v)) } -// appendString wire encodes a *string pointer as a String. +// appendStringPtr wire encodes a *string pointer as a String. // It panics if the pointer is nil. func appendStringPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) { v := **p.StringPtr() @@ -2213,9 +3671,27 @@ func appendStringPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]b return b, nil } +// consumeStringPtr wire decodes a *string pointer as a String. +func consumeStringPtr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return 0, wire.ParseError(n) + } + vp := p.StringPtr() + if *vp == nil { + *vp = new(string) + } + **vp = v + return n, nil +} + var coderStringPtr = pointerCoderFuncs{ - size: sizeStringPtr, - marshal: appendStringPtr, + size: sizeStringPtr, + marshal: appendStringPtr, + unmarshal: consumeStringPtr, } // sizeStringSlice returns the size of wire encoding a []string pointer as a repeated String. @@ -2237,9 +3713,24 @@ func appendStringSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ return b, nil } +// consumeStringSlice wire decodes a []string pointer as a repeated String. +func consumeStringSlice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.StringSlice() + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return n, nil +} + var coderStringSlice = pointerCoderFuncs{ - size: sizeStringSlice, - marshal: appendStringSlice, + size: sizeStringSlice, + marshal: appendStringSlice, + unmarshal: consumeStringSlice, } // sizeStringIface returns the size of wire encoding a string value as a String. @@ -2256,9 +3747,22 @@ func appendStringIface(b []byte, ival interface{}, wiretag uint64, _ marshalOpti return b, nil } +// consumeStringIface decodes a string value as a String. +func consumeStringIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.BytesType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return v, n, nil +} + var coderStringIface = ifaceCoderFuncs{ - size: sizeStringIface, - marshal: appendStringIface, + size: sizeStringIface, + marshal: appendStringIface, + unmarshal: consumeStringIface, } // sizeStringSliceIface returns the size of wire encoding a []string value as a repeated String. @@ -2280,9 +3784,24 @@ func appendStringSliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha return b, nil } +// consumeStringSliceIface wire decodes a []string value as a repeated String. +func consumeStringSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[]string) + if wtyp != wire.BytesType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeString(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, v) + return ival, n, nil +} + var coderStringSliceIface = ifaceCoderFuncs{ - size: sizeStringSliceIface, - marshal: appendStringSliceIface, + size: sizeStringSliceIface, + marshal: appendStringSliceIface, + unmarshal: consumeStringSliceIface, } // sizeBytes returns the size of wire encoding a []byte pointer as a Bytes. @@ -2299,9 +3818,23 @@ func appendBytes(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, return b, nil } +// consumeBytes wire decodes a []byte pointer as a Bytes. +func consumeBytes(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *p.Bytes() = append(([]byte)(nil), v...) + return n, nil +} + var coderBytes = pointerCoderFuncs{ - size: sizeBytes, - marshal: appendBytes, + size: sizeBytes, + marshal: appendBytes, + unmarshal: consumeBytes, } // sizeBytes returns the size of wire encoding a []byte pointer as a Bytes. @@ -2327,8 +3860,9 @@ func appendBytesNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([ } var coderBytesNoZero = pointerCoderFuncs{ - size: sizeBytesNoZero, - marshal: appendBytesNoZero, + size: sizeBytesNoZero, + marshal: appendBytesNoZero, + unmarshal: consumeBytes, } // sizeBytesSlice returns the size of wire encoding a [][]byte pointer as a repeated Bytes. @@ -2350,9 +3884,24 @@ func appendBytesSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([] return b, nil } +// consumeBytesSlice wire decodes a [][]byte pointer as a repeated Bytes. +func consumeBytesSlice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + sp := p.BytesSlice() + if wtyp != wire.BytesType { + return 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + *sp = append(*sp, append(([]byte)(nil), v...)) + return n, nil +} + var coderBytesSlice = pointerCoderFuncs{ - size: sizeBytesSlice, - marshal: appendBytesSlice, + size: sizeBytesSlice, + marshal: appendBytesSlice, + unmarshal: consumeBytesSlice, } // sizeBytesIface returns the size of wire encoding a []byte value as a Bytes. @@ -2369,9 +3918,22 @@ func appendBytesIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptio return b, nil } +// consumeBytesIface decodes a []byte value as a Bytes. +func consumeBytesIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) { + if wtyp != wire.BytesType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + return append(([]byte)(nil), v...), n, nil +} + var coderBytesIface = ifaceCoderFuncs{ - size: sizeBytesIface, - marshal: appendBytesIface, + size: sizeBytesIface, + marshal: appendBytesIface, + unmarshal: consumeBytesIface, } // sizeBytesSliceIface returns the size of wire encoding a [][]byte value as a repeated Bytes. @@ -2393,9 +3955,24 @@ func appendBytesSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshal return b, nil } +// consumeBytesSliceIface wire decodes a [][]byte value as a repeated Bytes. +func consumeBytesSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) { + sp := ival.(*[][]byte) + if wtyp != wire.BytesType { + return nil, 0, errUnknown + } + v, n := wire.ConsumeBytes(b) + if n < 0 { + return nil, 0, wire.ParseError(n) + } + *sp = append(*sp, append(([]byte)(nil), v...)) + return ival, n, nil +} + var coderBytesSliceIface = ifaceCoderFuncs{ - size: sizeBytesSliceIface, - marshal: appendBytesSliceIface, + size: sizeBytesSliceIface, + marshal: appendBytesSliceIface, + unmarshal: consumeBytesSliceIface, } var wireTypes = map[protoreflect.Kind]wire.Type{ diff --git a/internal/impl/codec_map.go b/internal/impl/codec_map.go index 5a02c34c..53a860b4 100644 --- a/internal/impl/codec_map.go +++ b/internal/impl/codec_map.go @@ -16,6 +16,17 @@ import ( var protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() +type mapInfo struct { + goType reflect.Type + keyWiretag uint64 + valWiretag uint64 + keyFuncs ifaceCoderFuncs + valFuncs ifaceCoderFuncs + keyZero interface{} + valZero interface{} + newVal func() interface{} +} + func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointerCoderFuncs) { // TODO: Consider generating specialized map coders. keyField := fd.MapKey() @@ -25,6 +36,22 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointer keyFuncs := encoderFuncsForValue(keyField, ft.Key()) valFuncs := encoderFuncsForValue(valField, ft.Elem()) + mapi := &mapInfo{ + goType: ft, + keyWiretag: keyWiretag, + valWiretag: valWiretag, + keyFuncs: keyFuncs, + valFuncs: valFuncs, + keyZero: reflect.Zero(ft.Key()).Interface(), + valZero: reflect.Zero(ft.Elem()).Interface(), + } + switch valField.Kind() { + case pref.GroupKind, pref.MessageKind: + mapi.newVal = func() interface{} { + return reflect.New(ft.Elem().Elem()).Interface() + } + } + funcs = pointerCoderFuncs{ size: func(p pointer, tagsize int, opts marshalOptions) int { return sizeMap(p, tagsize, ft, keyFuncs, valFuncs, opts) @@ -32,6 +59,9 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointer marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { return appendMap(b, p, wiretag, keyWiretag, valWiretag, ft, keyFuncs, valFuncs, opts) }, + unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) { + return consumeMap(b, p, wtyp, mapi, opts) + }, } if valFuncs.isInit != nil { funcs.isInit = func(p pointer) error { @@ -46,6 +76,64 @@ const ( mapValTagSize = 1 // field 2, tag size 2. ) +func consumeMap(b []byte, p pointer, wtyp wire.Type, mapi *mapInfo, opts unmarshalOptions) (int, error) { + mp := p.AsValueOf(mapi.goType) + if mp.Elem().IsNil() { + mp.Elem().Set(reflect.MakeMap(mapi.goType)) + } + m := mp.Elem() + + if wtyp != wire.BytesType { + return 0, errUnknown + } + b, n := wire.ConsumeBytes(b) + if n < 0 { + return 0, wire.ParseError(n) + } + var ( + key = mapi.keyZero + val = mapi.valZero + ) + if mapi.newVal != nil { + val = mapi.newVal() + } + for len(b) > 0 { + num, wtyp, n := wire.ConsumeTag(b) + if n < 0 { + return 0, wire.ParseError(n) + } + b = b[n:] + err := errUnknown + switch num { + case 1: + var v interface{} + v, n, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) + if err != nil { + break + } + key = v + case 2: + var v interface{} + v, n, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts) + if err != nil { + break + } + val = v + } + if err == errUnknown { + n = wire.ConsumeFieldValue(num, wtyp, b) + if n < 0 { + return 0, wire.ParseError(n) + } + } else if err != nil { + return 0, err + } + b = b[n:] + } + m.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(val)) + return n, nil +} + func sizeMap(p pointer, tagsize int, goType reflect.Type, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) int { m := p.AsValueOf(goType).Elem() n := 0 diff --git a/internal/impl/codec_message.go b/internal/impl/codec_message.go index e4e37060..61c88c1d 100644 --- a/internal/impl/codec_message.go +++ b/internal/impl/codec_message.go @@ -18,6 +18,8 @@ import ( // possible. type coderMessageInfo struct { orderedCoderFields []*coderFieldInfo + denseCoderFields []*coderFieldInfo + coderFields map[wire.Number]*coderFieldInfo sizecacheOffset offset unknownOffset offset extensionOffset offset @@ -39,13 +41,14 @@ func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) { mi.unknownOffset = si.unknownOffset mi.extensionOffset = si.extensionOffset + mi.coderFields = make(map[wire.Number]*coderFieldInfo) for i := 0; i < mi.PBType.Descriptor().Fields().Len(); i++ { fd := mi.PBType.Descriptor().Fields().Get(i) - if fd.ContainingOneof() != nil { - continue - } fs := si.fieldsByNumber[fd.Number()] + if fd.ContainingOneof() != nil { + fs = si.oneofsByName[fd.ContainingOneof().Name()] + } ft := fs.Type var wiretag uint64 if !fd.IsPacked() { @@ -53,37 +56,51 @@ func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) { } else { wiretag = wire.EncodeTag(fd.Number(), wire.BytesType) } - mi.orderedCoderFields = append(mi.orderedCoderFields, &coderFieldInfo{ + var funcs pointerCoderFuncs + if fd.ContainingOneof() != nil { + funcs = makeOneofFieldCoder(si, fd) + } else { + funcs = fieldCoder(fd, ft) + } + cf := &coderFieldInfo{ num: fd.Number(), offset: offsetOf(fs, mi.Exporter), wiretag: wiretag, tagsize: wire.SizeVarint(wiretag), - funcs: fieldCoder(fd, ft), + funcs: funcs, isPointer: (fd.Cardinality() == pref.Repeated || fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind || fd.Syntax() != pref.Proto3), isRequired: fd.Cardinality() == pref.Required, - }) - } - for i := 0; i < mi.PBType.Descriptor().Oneofs().Len(); i++ { - od := mi.PBType.Descriptor().Oneofs().Get(i) - fs := si.oneofsByName[od.Name()] - mi.orderedCoderFields = append(mi.orderedCoderFields, &coderFieldInfo{ - num: od.Fields().Get(0).Number(), - offset: offsetOf(fs, mi.Exporter), - funcs: makeOneofFieldCoder(fs, od, si.fieldsByNumber, si.oneofWrappersByNumber), - isPointer: true, - }) + } + mi.orderedCoderFields = append(mi.orderedCoderFields, cf) + mi.coderFields[cf.num] = cf } sort.Slice(mi.orderedCoderFields, func(i, j int) bool { return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num }) + var maxDense pref.FieldNumber + for _, cf := range mi.orderedCoderFields { + if cf.num >= 16 && cf.num >= 2*maxDense { + break + } + maxDense = cf.num + } + mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1) + for _, cf := range mi.orderedCoderFields { + if int(cf.num) > len(mi.denseCoderFields) { + break + } + mi.denseCoderFields[cf.num] = cf + } + mi.needsInitCheck = needsInitCheck(mi.PBType) mi.methods = piface.Methods{ Flags: piface.MethodFlagDeterministicMarshal, MarshalAppend: mi.marshalAppend, + Unmarshal: mi.unmarshal, Size: mi.size, IsInitialized: mi.isInitialized, } diff --git a/internal/impl/codec_reflect.go b/internal/impl/codec_reflect.go index 05ceb33b..d307efe9 100644 --- a/internal/impl/codec_reflect.go +++ b/internal/impl/codec_reflect.go @@ -7,6 +7,8 @@ package impl import ( + "reflect" + "google.golang.org/protobuf/internal/encoding/wire" ) @@ -22,9 +24,22 @@ func appendEnum(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byt return b, nil } +func consumeEnum(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, errUnknown + } + v, n := wire.ConsumeVarint(b) + if n < 0 { + return 0, wire.ParseError(n) + } + p.v.Elem().SetInt(int64(v)) + return n, nil +} + var coderEnum = pointerCoderFuncs{ - size: sizeEnum, - marshal: appendEnum, + size: sizeEnum, + marshal: appendEnum, + unmarshal: consumeEnum, } func sizeEnumNoZero(p pointer, tagsize int, opts marshalOptions) (size int) { @@ -42,8 +57,9 @@ func appendEnumNoZero(b []byte, p pointer, wiretag uint64, opts marshalOptions) } var coderEnumNoZero = pointerCoderFuncs{ - size: sizeEnumNoZero, - marshal: appendEnumNoZero, + size: sizeEnumNoZero, + marshal: appendEnumNoZero, + unmarshal: consumeEnum, } func sizeEnumPtr(p pointer, tagsize int, opts marshalOptions) (size int) { @@ -54,9 +70,20 @@ func appendEnumPtr(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([] return appendEnum(b, pointer{p.v.Elem()}, wiretag, opts) } +func consumeEnumPtr(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (n int, err error) { + if wtyp != wire.VarintType { + return 0, 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) +} + var coderEnumPtr = pointerCoderFuncs{ - size: sizeEnumPtr, - marshal: appendEnumPtr, + size: sizeEnumPtr, + marshal: appendEnumPtr, + unmarshal: consumeEnumPtr, } func sizeEnumSlice(p pointer, tagsize int, opts marshalOptions) (size int) { @@ -67,9 +94,14 @@ func appendEnumSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ( return appendEnumSliceReflect(b, p.v.Elem(), wiretag, opts) } +func consumeEnumSlice(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (n int, err error) { + return consumeEnumSliceReflect(b, p.v, wtyp, opts) +} + var coderEnumSlice = pointerCoderFuncs{ - size: sizeEnumSlice, - marshal: appendEnumSlice, + size: sizeEnumSlice, + marshal: appendEnumSlice, + unmarshal: consumeEnumSlice, } func sizeEnumPackedSlice(p pointer, tagsize int, _ marshalOptions) (size int) { @@ -104,6 +136,7 @@ func appendEnumPackedSlice(b []byte, p pointer, wiretag uint64, opts marshalOpti } var coderEnumPackedSlice = pointerCoderFuncs{ - size: sizeEnumPackedSlice, - marshal: appendEnumPackedSlice, + size: sizeEnumPackedSlice, + marshal: appendEnumPackedSlice, + unmarshal: consumeEnumSlice, } diff --git a/internal/impl/codec_tables.go b/internal/impl/codec_tables.go index 8acb10d2..3d492af6 100644 --- a/internal/impl/codec_tables.go +++ b/internal/impl/codec_tables.go @@ -8,21 +8,24 @@ import ( "fmt" "reflect" + "google.golang.org/protobuf/internal/encoding/wire" pref "google.golang.org/protobuf/reflect/protoreflect" ) // 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) - isInit func(p pointer) error + 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) (int, error) + isInit func(p pointer) error } // ifaceCoderFuncs is a set of interface{} encoding functions. type ifaceCoderFuncs struct { - size func(ival interface{}, tagsize int, opts marshalOptions) int - marshal func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) - isInit func(ival interface{}) error + size func(ival interface{}, tagsize int, opts marshalOptions) int + marshal func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) + unmarshal func(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) + isInit func(ival interface{}) error } // fieldCoder returns pointer functions for a field, used for operating on @@ -574,7 +577,7 @@ func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFu case pref.MessageKind: return coderMessageIface case pref.GroupKind: - return coderGroupIface + return makeGroupValueCoder(fd, ft) } } panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft)) diff --git a/internal/impl/decode.go b/internal/impl/decode.go new file mode 100644 index 00000000..5fdffe3a --- /dev/null +++ b/internal/impl/decode.go @@ -0,0 +1,162 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "google.golang.org/protobuf/internal/encoding/wire" + "google.golang.org/protobuf/internal/errors" + "google.golang.org/protobuf/proto" + pref "google.golang.org/protobuf/reflect/protoreflect" + preg "google.golang.org/protobuf/reflect/protoregistry" + piface "google.golang.org/protobuf/runtime/protoiface" +) + +// unmarshalOptions is a more efficient representation of UnmarshalOptions. +// +// We don't preserve the AllowPartial flag, because fast-path (un)marshal +// operations always allow partial messages. +type unmarshalOptions struct { + flags unmarshalOptionFlags + resolver preg.ExtensionTypeResolver +} + +type unmarshalOptionFlags uint8 + +const ( + unmarshalDiscardUnknown unmarshalOptionFlags = 1 << iota +) + +func newUnmarshalOptions(opts piface.UnmarshalOptions) unmarshalOptions { + o := unmarshalOptions{ + resolver: opts.Resolver, + } + if opts.DiscardUnknown { + o.flags |= unmarshalDiscardUnknown + } + return o +} + +func (o unmarshalOptions) Options() proto.UnmarshalOptions { + return proto.UnmarshalOptions{ + AllowPartial: true, + DiscardUnknown: o.DiscardUnknown(), + Resolver: o.Resolver(), + } +} + +func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&unmarshalDiscardUnknown != 0 } +func (o unmarshalOptions) Resolver() preg.ExtensionTypeResolver { return o.resolver } + +// unmarshal is protoreflect.Methods.Unmarshal. +func (mi *MessageInfo) unmarshal(b []byte, m pref.ProtoMessage, opts piface.UnmarshalOptions) error { + _, err := mi.unmarshalPointer(b, pointerOfIface(m), 0, newUnmarshalOptions(opts)) + return err +} + +// errUnknown is returned during unmarshaling to indicate a parse error that +// should result in a field being placed in the unknown fields section (for example, +// when the wire type doesn't match) as opposed to the entire unmarshal operation +// failing (for example, when a field extends past the available input). +// +// This is a sentinel error which should never be visible to the user. +var errUnknown = errors.New("unknown") + +func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag wire.Number, opts unmarshalOptions) (int, error) { + mi.init() + var exts *map[int32]ExtensionField + start := len(b) + for len(b) > 0 { + // Parse the tag (field number and wire type). + // TODO: inline 1 and 2 byte variants? + num, wtyp, n := wire.ConsumeTag(b) + if n < 0 { + return 0, wire.ParseError(n) + } + b = b[n:] + + var f *coderFieldInfo + if int(num) < len(mi.denseCoderFields) { + f = mi.denseCoderFields[num] + } else { + f = mi.coderFields[num] + } + err := errUnknown + switch { + case f != nil: + if f.funcs.unmarshal == nil { + break + } + n, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, opts) + case num == groupTag && wtyp == wire.EndGroupType: + // End of group. + return start - len(b), nil + default: + // Possible extension. + if exts == nil && mi.extensionOffset.IsValid() { + exts = p.Apply(mi.extensionOffset).Extensions() + if *exts == nil { + *exts = make(map[int32]ExtensionField) + } + } + if exts == nil { + break + } + n, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts) + } + if err != nil { + if err != errUnknown { + return 0, err + } + n = wire.ConsumeFieldValue(num, wtyp, b) + if n < 0 { + return 0, wire.ParseError(n) + } + if mi.unknownOffset.IsValid() { + u := p.Apply(mi.unknownOffset).Bytes() + *u = wire.AppendTag(*u, num, wtyp) + *u = append(*u, b[:n]...) + } + } + b = b[n:] + } + if groupTag != 0 { + return 0, errors.New("missing end group marker") + } + return start, nil +} + +func (mi *MessageInfo) unmarshalExtension(b []byte, num wire.Number, wtyp wire.Type, exts map[int32]ExtensionField, opts unmarshalOptions) (n int, err error) { + x := exts[int32(num)] + xt := x.GetType() + if xt == nil { + var err error + xt, err = opts.Resolver().FindExtensionByNumber(mi.PBType.FullName(), num) + if err != nil { + if err == preg.NotFound { + return 0, errUnknown + } + return 0, err + } + x.SetType(xt) + } + xi := mi.extensionFieldInfo(xt) + if xi.funcs.unmarshal == nil { + return 0, errUnknown + } + ival := x.GetValue() + if ival == nil && xi.unmarshalNeedsValue { + // Create a new message, list, or map value to fill in. + // For enums, create a prototype value to let the unmarshal func know the + // concrete type. + ival = xt.InterfaceOf(xt.New()) + } + v, n, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts) + if err != nil { + return 0, err + } + x.SetEagerValue(v) + exts[int32(num)] = x + return n, nil +} diff --git a/internal/impl/encode.go b/internal/impl/encode.go index c258d46c..bf7308a8 100644 --- a/internal/impl/encode.go +++ b/internal/impl/encode.go @@ -13,19 +13,19 @@ import ( piface "google.golang.org/protobuf/runtime/protoiface" ) +// marshalOptions is a more efficient representation of MarshalOptions. +// +// We don't preserve the AllowPartial flag, because fast-path (un)marshal +// operations always allow partial messages. type marshalOptions uint const ( - marshalAllowPartial marshalOptions = 1 << iota - marshalDeterministic + marshalDeterministic marshalOptions = 1 << iota marshalUseCachedSize ) func newMarshalOptions(opts piface.MarshalOptions) marshalOptions { var o marshalOptions - if opts.AllowPartial { - o |= marshalAllowPartial - } if opts.Deterministic { o |= marshalDeterministic } @@ -37,13 +37,12 @@ func newMarshalOptions(opts piface.MarshalOptions) marshalOptions { func (o marshalOptions) Options() proto.MarshalOptions { return proto.MarshalOptions{ - AllowPartial: o.AllowPartial(), + AllowPartial: true, Deterministic: o.Deterministic(), UseCachedSize: o.UseCachedSize(), } } -func (o marshalOptions) AllowPartial() bool { return o&marshalAllowPartial != 0 } func (o marshalOptions) Deterministic() bool { return o&marshalDeterministic != 0 } func (o marshalOptions) UseCachedSize() bool { return o&marshalUseCachedSize != 0 } diff --git a/internal/impl/message.go b/internal/impl/message.go index e9a38c21..fe7cd370 100644 --- a/internal/impl/message.go +++ b/internal/impl/message.go @@ -516,6 +516,7 @@ func (m *messageIfaceWrapper) XXX_Methods() *piface.Methods { return &piface.Methods{ Flags: piface.MethodFlagDeterministicMarshal, MarshalAppend: m.marshalAppend, + Unmarshal: m.unmarshal, Size: m.size, IsInitialized: m.isInitialized, } @@ -526,9 +527,13 @@ func (m *messageIfaceWrapper) ProtoUnwrap() interface{} { func (m *messageIfaceWrapper) marshalAppend(b []byte, _ pref.ProtoMessage, opts piface.MarshalOptions) ([]byte, error) { return m.mi.marshalAppendPointer(b, m.p, newMarshalOptions(opts)) } +func (m *messageIfaceWrapper) unmarshal(b []byte, _ pref.ProtoMessage, opts piface.UnmarshalOptions) error { + _, err := m.mi.unmarshalPointer(b, m.p, 0, newUnmarshalOptions(opts)) + return err +} func (m *messageIfaceWrapper) size(msg pref.ProtoMessage) (size int) { return m.mi.sizePointer(m.p, 0) } -func (m *messageIfaceWrapper) isInitialized(msg pref.ProtoMessage) error { +func (m *messageIfaceWrapper) isInitialized(_ pref.ProtoMessage) error { return m.mi.isInitializedPointer(m.p) } diff --git a/internal/impl/pointer_reflect.go b/internal/impl/pointer_reflect.go index 60601543..0a9c53ef 100644 --- a/internal/impl/pointer_reflect.go +++ b/internal/impl/pointer_reflect.go @@ -135,3 +135,14 @@ func (p pointer) PointerSlice() []pointer { } return s } + +// AppendPointerSlice appends v to p, which must be a []*T. +func (p pointer) AppendPointerSlice(v pointer) { + sp := p.v.Elem() + sp.Set(reflect.Append(sp, v.v)) +} + +// SetPointer sets *p to v. +func (p pointer) SetPointer(v pointer) { + p.v.Elem().Set(v.v) +} diff --git a/internal/impl/pointer_unsafe.go b/internal/impl/pointer_unsafe.go index bd5ab4bd..ceca3b2f 100644 --- a/internal/impl/pointer_unsafe.go +++ b/internal/impl/pointer_unsafe.go @@ -115,3 +115,13 @@ func (p pointer) PointerSlice() []pointer { // message type. We load it as []pointer. return *(*[]pointer)(p.p) } + +// AppendPointerSlice appends v to p, which must be a []*T. +func (p pointer) AppendPointerSlice(v pointer) { + *(*[]pointer)(p.p) = append(*(*[]pointer)(p.p), v) +} + +// SetPointer sets *p to v. +func (p pointer) SetPointer(v pointer) { + *(*unsafe.Pointer)(p.p) = (unsafe.Pointer)(v.p) +}