internal/impl: support packed extensions

Change-Id: I5a9e22f1c98f5db9caae1681775017da5aa67394
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185541
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Damien Neil 2019-07-10 15:23:29 -07:00
parent 3e6a39b3f1
commit 7492a09da9
9 changed files with 2269 additions and 467 deletions

View File

@ -365,13 +365,59 @@ func consume{{.Name}}SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp
return ival, n, nil
}
var coder{{.Name}}SliceIface = ifaceCoderFuncs{
size: size{{.Name}}SliceIface,
marshal: append{{.Name}}SliceIface,
unmarshal: consume{{.Name}}SliceIface,
}
{{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
// size{{.Name}}PackedSliceIface returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
func size{{.Name}}PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]{{.GoType}})
if len(s) == 0 {
return 0
}
{{if .WireType.ConstSize -}}
n := len(s) * {{template "Size" .}}
{{- else -}}
n := 0
for _, v := range s {
n += {{template "Size" .}}
}
{{- end}}
return tagsize + wire.SizeBytes(n)
}
// append{{.Name}}PackedSliceIface encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
func append{{.Name}}PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]{{.GoType}})
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
{{if .WireType.ConstSize -}}
n := len(s) * {{template "Size" .}}
{{- else -}}
n := 0
for _, v := range s {
n += {{template "Size" .}}
}
{{- end}}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
{{template "Append" .}}
}
return b, nil
}
var coder{{.Name}}PackedSliceIface = ifaceCoderFuncs{
size: size{{.Name}}PackedSliceIface,
marshal: append{{.Name}}PackedSliceIface,
unmarshal: consume{{.Name}}SliceIface,
}
{{end}}
{{end -}}
{{end -}}

View File

@ -29,7 +29,12 @@ func (mi *MessageInfo) extensionFieldInfo(xt pref.ExtensionType) *extensionField
return e
}
wiretag := wire.EncodeTag(xt.Number(), wireTypes[xt.Kind()])
var wiretag uint64
if !xt.IsPacked() {
wiretag = wire.EncodeTag(xt.Number(), wireTypes[xt.Kind()])
} else {
wiretag = wire.EncodeTag(xt.Number(), wire.BytesType)
}
e = &extensionFieldInfo{
wiretag: wiretag,
tagsize: wire.SizeVarint(wiretag),

View File

@ -698,6 +698,49 @@ var coderEnumSliceIface = ifaceCoderFuncs{
unmarshal: consumeEnumSliceIface,
}
func sizeEnumPackedSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) {
return sizeEnumPackedSliceReflect(reflect.ValueOf(ival).Elem(), tagsize, opts)
}
func sizeEnumPackedSliceReflect(s reflect.Value, tagsize int, _ marshalOptions) (size int) {
llen := s.Len()
if llen == 0 {
return 0
}
n := 0
for i := 0; i < llen; i++ {
n += wire.SizeVarint(uint64(s.Index(i).Int()))
}
return tagsize + wire.SizeBytes(n)
}
func appendEnumPackedSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
return appendEnumPackedSliceReflect(b, reflect.ValueOf(ival).Elem(), wiretag, opts)
}
func appendEnumPackedSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
llen := s.Len()
if llen == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for i := 0; i < llen; i++ {
n += wire.SizeVarint(uint64(s.Index(i).Int()))
}
b = wire.AppendVarint(b, uint64(n))
for i := 0; i < llen; i++ {
b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
}
return b, nil
}
var coderEnumPackedSliceIface = ifaceCoderFuncs{
size: sizeEnumPackedSliceIface,
marshal: appendEnumPackedSliceIface,
unmarshal: consumeEnumSliceIface,
}
// Strings with UTF8 validation.
func appendStringValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {

View File

@ -294,6 +294,43 @@ var coderBoolSliceIface = ifaceCoderFuncs{
unmarshal: consumeBoolSliceIface,
}
// sizeBoolPackedSliceIface returns the size of wire encoding a []bool value as a packed repeated Bool.
func sizeBoolPackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]bool)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeBool(v))
}
return tagsize + wire.SizeBytes(n)
}
// appendBoolPackedSliceIface encodes a []bool value as a packed repeated Bool.
func appendBoolPackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]bool)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeBool(v))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, wire.EncodeBool(v))
}
return b, nil
}
var coderBoolPackedSliceIface = ifaceCoderFuncs{
size: sizeBoolPackedSliceIface,
marshal: appendBoolPackedSliceIface,
unmarshal: consumeBoolSliceIface,
}
// sizeInt32 returns the size of wire encoding a int32 pointer as a Int32.
func sizeInt32(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Int32()
@ -575,6 +612,43 @@ var coderInt32SliceIface = ifaceCoderFuncs{
unmarshal: consumeInt32SliceIface,
}
// sizeInt32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Int32.
func sizeInt32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int32)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
return tagsize + wire.SizeBytes(n)
}
// appendInt32PackedSliceIface encodes a []int32 value as a packed repeated Int32.
func appendInt32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, uint64(v))
}
return b, nil
}
var coderInt32PackedSliceIface = ifaceCoderFuncs{
size: sizeInt32PackedSliceIface,
marshal: appendInt32PackedSliceIface,
unmarshal: consumeInt32SliceIface,
}
// sizeSint32 returns the size of wire encoding a int32 pointer as a Sint32.
func sizeSint32(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Int32()
@ -856,6 +930,43 @@ var coderSint32SliceIface = ifaceCoderFuncs{
unmarshal: consumeSint32SliceIface,
}
// sizeSint32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Sint32.
func sizeSint32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int32)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeZigZag(int64(v)))
}
return tagsize + wire.SizeBytes(n)
}
// appendSint32PackedSliceIface encodes a []int32 value as a packed repeated Sint32.
func appendSint32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeZigZag(int64(v)))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, wire.EncodeZigZag(int64(v)))
}
return b, nil
}
var coderSint32PackedSliceIface = ifaceCoderFuncs{
size: sizeSint32PackedSliceIface,
marshal: appendSint32PackedSliceIface,
unmarshal: consumeSint32SliceIface,
}
// sizeUint32 returns the size of wire encoding a uint32 pointer as a Uint32.
func sizeUint32(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Uint32()
@ -1137,6 +1248,43 @@ var coderUint32SliceIface = ifaceCoderFuncs{
unmarshal: consumeUint32SliceIface,
}
// sizeUint32PackedSliceIface returns the size of wire encoding a []uint32 value as a packed repeated Uint32.
func sizeUint32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]uint32)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
return tagsize + wire.SizeBytes(n)
}
// appendUint32PackedSliceIface encodes a []uint32 value as a packed repeated Uint32.
func appendUint32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]uint32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, uint64(v))
}
return b, nil
}
var coderUint32PackedSliceIface = ifaceCoderFuncs{
size: sizeUint32PackedSliceIface,
marshal: appendUint32PackedSliceIface,
unmarshal: consumeUint32SliceIface,
}
// sizeInt64 returns the size of wire encoding a int64 pointer as a Int64.
func sizeInt64(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Int64()
@ -1418,6 +1566,43 @@ var coderInt64SliceIface = ifaceCoderFuncs{
unmarshal: consumeInt64SliceIface,
}
// sizeInt64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Int64.
func sizeInt64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int64)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
return tagsize + wire.SizeBytes(n)
}
// appendInt64PackedSliceIface encodes a []int64 value as a packed repeated Int64.
func appendInt64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(uint64(v))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, uint64(v))
}
return b, nil
}
var coderInt64PackedSliceIface = ifaceCoderFuncs{
size: sizeInt64PackedSliceIface,
marshal: appendInt64PackedSliceIface,
unmarshal: consumeInt64SliceIface,
}
// sizeSint64 returns the size of wire encoding a int64 pointer as a Sint64.
func sizeSint64(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Int64()
@ -1699,6 +1884,43 @@ var coderSint64SliceIface = ifaceCoderFuncs{
unmarshal: consumeSint64SliceIface,
}
// sizeSint64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Sint64.
func sizeSint64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int64)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeZigZag(v))
}
return tagsize + wire.SizeBytes(n)
}
// appendSint64PackedSliceIface encodes a []int64 value as a packed repeated Sint64.
func appendSint64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(wire.EncodeZigZag(v))
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, wire.EncodeZigZag(v))
}
return b, nil
}
var coderSint64PackedSliceIface = ifaceCoderFuncs{
size: sizeSint64PackedSliceIface,
marshal: appendSint64PackedSliceIface,
unmarshal: consumeSint64SliceIface,
}
// sizeUint64 returns the size of wire encoding a uint64 pointer as a Uint64.
func sizeUint64(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.Uint64()
@ -1980,6 +2202,43 @@ var coderUint64SliceIface = ifaceCoderFuncs{
unmarshal: consumeUint64SliceIface,
}
// sizeUint64PackedSliceIface returns the size of wire encoding a []uint64 value as a packed repeated Uint64.
func sizeUint64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]uint64)
if len(s) == 0 {
return 0
}
n := 0
for _, v := range s {
n += wire.SizeVarint(v)
}
return tagsize + wire.SizeBytes(n)
}
// appendUint64PackedSliceIface encodes a []uint64 value as a packed repeated Uint64.
func appendUint64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]uint64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for _, v := range s {
n += wire.SizeVarint(v)
}
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendVarint(b, v)
}
return b, nil
}
var coderUint64PackedSliceIface = ifaceCoderFuncs{
size: sizeUint64PackedSliceIface,
marshal: appendUint64PackedSliceIface,
unmarshal: consumeUint64SliceIface,
}
// sizeSfixed32 returns the size of wire encoding a int32 pointer as a Sfixed32.
func sizeSfixed32(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -2249,6 +2508,37 @@ var coderSfixed32SliceIface = ifaceCoderFuncs{
unmarshal: consumeSfixed32SliceIface,
}
// sizeSfixed32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Sfixed32.
func sizeSfixed32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int32)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed32()
return tagsize + wire.SizeBytes(n)
}
// appendSfixed32PackedSliceIface encodes a []int32 value as a packed repeated Sfixed32.
func appendSfixed32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed32()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed32(b, uint32(v))
}
return b, nil
}
var coderSfixed32PackedSliceIface = ifaceCoderFuncs{
size: sizeSfixed32PackedSliceIface,
marshal: appendSfixed32PackedSliceIface,
unmarshal: consumeSfixed32SliceIface,
}
// sizeFixed32 returns the size of wire encoding a uint32 pointer as a Fixed32.
func sizeFixed32(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -2518,6 +2808,37 @@ var coderFixed32SliceIface = ifaceCoderFuncs{
unmarshal: consumeFixed32SliceIface,
}
// sizeFixed32PackedSliceIface returns the size of wire encoding a []uint32 value as a packed repeated Fixed32.
func sizeFixed32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]uint32)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed32()
return tagsize + wire.SizeBytes(n)
}
// appendFixed32PackedSliceIface encodes a []uint32 value as a packed repeated Fixed32.
func appendFixed32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]uint32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed32()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed32(b, v)
}
return b, nil
}
var coderFixed32PackedSliceIface = ifaceCoderFuncs{
size: sizeFixed32PackedSliceIface,
marshal: appendFixed32PackedSliceIface,
unmarshal: consumeFixed32SliceIface,
}
// sizeFloat returns the size of wire encoding a float32 pointer as a Float.
func sizeFloat(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -2787,6 +3108,37 @@ var coderFloatSliceIface = ifaceCoderFuncs{
unmarshal: consumeFloatSliceIface,
}
// sizeFloatPackedSliceIface returns the size of wire encoding a []float32 value as a packed repeated Float.
func sizeFloatPackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]float32)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed32()
return tagsize + wire.SizeBytes(n)
}
// appendFloatPackedSliceIface encodes a []float32 value as a packed repeated Float.
func appendFloatPackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]float32)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed32()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed32(b, math.Float32bits(v))
}
return b, nil
}
var coderFloatPackedSliceIface = ifaceCoderFuncs{
size: sizeFloatPackedSliceIface,
marshal: appendFloatPackedSliceIface,
unmarshal: consumeFloatSliceIface,
}
// sizeSfixed64 returns the size of wire encoding a int64 pointer as a Sfixed64.
func sizeSfixed64(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -3056,6 +3408,37 @@ var coderSfixed64SliceIface = ifaceCoderFuncs{
unmarshal: consumeSfixed64SliceIface,
}
// sizeSfixed64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Sfixed64.
func sizeSfixed64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]int64)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed64()
return tagsize + wire.SizeBytes(n)
}
// appendSfixed64PackedSliceIface encodes a []int64 value as a packed repeated Sfixed64.
func appendSfixed64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]int64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed64()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed64(b, uint64(v))
}
return b, nil
}
var coderSfixed64PackedSliceIface = ifaceCoderFuncs{
size: sizeSfixed64PackedSliceIface,
marshal: appendSfixed64PackedSliceIface,
unmarshal: consumeSfixed64SliceIface,
}
// sizeFixed64 returns the size of wire encoding a uint64 pointer as a Fixed64.
func sizeFixed64(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -3325,6 +3708,37 @@ var coderFixed64SliceIface = ifaceCoderFuncs{
unmarshal: consumeFixed64SliceIface,
}
// sizeFixed64PackedSliceIface returns the size of wire encoding a []uint64 value as a packed repeated Fixed64.
func sizeFixed64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]uint64)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed64()
return tagsize + wire.SizeBytes(n)
}
// appendFixed64PackedSliceIface encodes a []uint64 value as a packed repeated Fixed64.
func appendFixed64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]uint64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed64()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed64(b, v)
}
return b, nil
}
var coderFixed64PackedSliceIface = ifaceCoderFuncs{
size: sizeFixed64PackedSliceIface,
marshal: appendFixed64PackedSliceIface,
unmarshal: consumeFixed64SliceIface,
}
// sizeDouble returns the size of wire encoding a float64 pointer as a Double.
func sizeDouble(p pointer, tagsize int, _ marshalOptions) (size int) {
@ -3594,6 +4008,37 @@ var coderDoubleSliceIface = ifaceCoderFuncs{
unmarshal: consumeDoubleSliceIface,
}
// sizeDoublePackedSliceIface returns the size of wire encoding a []float64 value as a packed repeated Double.
func sizeDoublePackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
s := *ival.(*[]float64)
if len(s) == 0 {
return 0
}
n := len(s) * wire.SizeFixed64()
return tagsize + wire.SizeBytes(n)
}
// appendDoublePackedSliceIface encodes a []float64 value as a packed repeated Double.
func appendDoublePackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
s := *ival.(*[]float64)
if len(s) == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := len(s) * wire.SizeFixed64()
b = wire.AppendVarint(b, uint64(n))
for _, v := range s {
b = wire.AppendFixed64(b, math.Float64bits(v))
}
return b, nil
}
var coderDoublePackedSliceIface = ifaceCoderFuncs{
size: sizeDoublePackedSliceIface,
marshal: appendDoublePackedSliceIface,
unmarshal: consumeDoubleSliceIface,
}
// sizeString returns the size of wire encoding a string pointer as a String.
func sizeString(p pointer, tagsize int, _ marshalOptions) (size int) {
v := *p.String()

View File

@ -104,35 +104,12 @@ var coderEnumSlice = pointerCoderFuncs{
unmarshal: consumeEnumSlice,
}
func sizeEnumPackedSlice(p pointer, tagsize int, _ marshalOptions) (size int) {
s := p.v.Elem()
slen := s.Len()
if slen == 0 {
return 0
}
n := 0
for i := 0; i < slen; i++ {
n += wire.SizeVarint(uint64(s.Index(i).Int()))
}
return tagsize + wire.SizeBytes(n)
func sizeEnumPackedSlice(p pointer, tagsize int, opts marshalOptions) (size int) {
return sizeEnumPackedSliceReflect(p.v.Elem(), tagsize, opts)
}
func appendEnumPackedSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
s := p.v.Elem()
slen := s.Len()
if slen == 0 {
return b, nil
}
b = wire.AppendVarint(b, wiretag)
n := 0
for i := 0; i < slen; i++ {
n += wire.SizeVarint(uint64(s.Index(i).Int()))
}
b = wire.AppendVarint(b, uint64(n))
for i := 0; i < slen; i++ {
b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
}
return b, nil
return appendEnumPackedSliceReflect(b, p.v.Elem(), wiretag, opts)
}
var coderEnumPackedSlice = pointerCoderFuncs{

View File

@ -499,6 +499,68 @@ func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFu
return coderGroupSliceIface
}
case fd.Cardinality() == pref.Repeated && fd.IsPacked():
if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
break
}
ft := ft.Elem().Elem()
switch fd.Kind() {
case pref.BoolKind:
if ft.Kind() == reflect.Bool {
return coderBoolPackedSliceIface
}
case pref.EnumKind:
if ft.Kind() == reflect.Int32 {
return coderEnumPackedSliceIface
}
case pref.Int32Kind:
if ft.Kind() == reflect.Int32 {
return coderInt32PackedSliceIface
}
case pref.Sint32Kind:
if ft.Kind() == reflect.Int32 {
return coderSint32PackedSliceIface
}
case pref.Uint32Kind:
if ft.Kind() == reflect.Uint32 {
return coderUint32PackedSliceIface
}
case pref.Int64Kind:
if ft.Kind() == reflect.Int64 {
return coderInt64PackedSliceIface
}
case pref.Sint64Kind:
if ft.Kind() == reflect.Int64 {
return coderSint64PackedSliceIface
}
case pref.Uint64Kind:
if ft.Kind() == reflect.Uint64 {
return coderUint64PackedSliceIface
}
case pref.Sfixed32Kind:
if ft.Kind() == reflect.Int32 {
return coderSfixed32PackedSliceIface
}
case pref.Fixed32Kind:
if ft.Kind() == reflect.Uint32 {
return coderFixed32PackedSliceIface
}
case pref.FloatKind:
if ft.Kind() == reflect.Float32 {
return coderFloatPackedSliceIface
}
case pref.Sfixed64Kind:
if ft.Kind() == reflect.Int64 {
return coderSfixed64PackedSliceIface
}
case pref.Fixed64Kind:
if ft.Kind() == reflect.Uint64 {
return coderFixed64PackedSliceIface
}
case pref.DoubleKind:
if ft.Kind() == reflect.Float64 {
return coderDoublePackedSliceIface
}
}
default:
switch fd.Kind() {
case pref.BoolKind:

File diff suppressed because it is too large Load Diff

View File

@ -265,6 +265,82 @@ message TestWeak {
optional goproto.proto.test.weak.WeakImportMessage weak_message = 1 [weak=true];
}
message TestPackedTypes {
repeated int32 packed_int32 = 90 [packed = true];
repeated int64 packed_int64 = 91 [packed = true];
repeated uint32 packed_uint32 = 92 [packed = true];
repeated uint64 packed_uint64 = 93 [packed = true];
repeated sint32 packed_sint32 = 94 [packed = true];
repeated sint64 packed_sint64 = 95 [packed = true];
repeated fixed32 packed_fixed32 = 96 [packed = true];
repeated fixed64 packed_fixed64 = 97 [packed = true];
repeated sfixed32 packed_sfixed32 = 98 [packed = true];
repeated sfixed64 packed_sfixed64 = 99 [packed = true];
repeated float packed_float = 100 [packed = true];
repeated double packed_double = 101 [packed = true];
repeated bool packed_bool = 102 [packed = true];
repeated ForeignEnum packed_enum = 103 [packed = true];
}
message TestUnpackedTypes {
repeated int32 unpacked_int32 = 90 [packed = false];
repeated int64 unpacked_int64 = 91 [packed = false];
repeated uint32 unpacked_uint32 = 92 [packed = false];
repeated uint64 unpacked_uint64 = 93 [packed = false];
repeated sint32 unpacked_sint32 = 94 [packed = false];
repeated sint64 unpacked_sint64 = 95 [packed = false];
repeated fixed32 unpacked_fixed32 = 96 [packed = false];
repeated fixed64 unpacked_fixed64 = 97 [packed = false];
repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
repeated float unpacked_float = 100 [packed = false];
repeated double unpacked_double = 101 [packed = false];
repeated bool unpacked_bool = 102 [packed = false];
repeated ForeignEnum unpacked_enum = 103 [packed = false];
}
message TestPackedExtensions {
extensions 1 to max;
}
extend TestPackedExtensions {
repeated int32 packed_int32_extension = 90 [packed = true];
repeated int64 packed_int64_extension = 91 [packed = true];
repeated uint32 packed_uint32_extension = 92 [packed = true];
repeated uint64 packed_uint64_extension = 93 [packed = true];
repeated sint32 packed_sint32_extension = 94 [packed = true];
repeated sint64 packed_sint64_extension = 95 [packed = true];
repeated fixed32 packed_fixed32_extension = 96 [packed = true];
repeated fixed64 packed_fixed64_extension = 97 [packed = true];
repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
repeated float packed_float_extension = 100 [packed = true];
repeated double packed_double_extension = 101 [packed = true];
repeated bool packed_bool_extension = 102 [packed = true];
repeated ForeignEnum packed_enum_extension = 103 [packed = true];
}
message TestUnpackedExtensions {
extensions 1 to max;
}
extend TestUnpackedExtensions {
repeated int32 unpacked_int32_extension = 90 [packed = false];
repeated int64 unpacked_int64_extension = 91 [packed = false];
repeated uint32 unpacked_uint32_extension = 92 [packed = false];
repeated uint64 unpacked_uint64_extension = 93 [packed = false];
repeated sint32 unpacked_sint32_extension = 94 [packed = false];
repeated sint64 unpacked_sint64_extension = 95 [packed = false];
repeated fixed32 unpacked_fixed32_extension = 96 [packed = false];
repeated fixed64 unpacked_fixed64_extension = 97 [packed = false];
repeated sfixed32 unpacked_sfixed32_extension = 98 [packed = false];
repeated sfixed64 unpacked_sfixed64_extension = 99 [packed = false];
repeated float unpacked_float_extension = 100 [packed = false];
repeated double unpacked_double_extension = 101 [packed = false];
repeated bool unpacked_bool_extension = 102 [packed = false];
repeated ForeignEnum unpacked_enum_extension = 103 [packed = false];
}
// Test that RPC services work.
message FooRequest {}
message FooResponse {}

View File

@ -508,6 +508,92 @@ var testProtos = []testProto{
},
}.Marshal(),
},
{
desc: "packed repeated types",
decodeTo: []proto.Message{&testpb.TestPackedTypes{
PackedInt32: []int32{1001, 2001},
PackedInt64: []int64{1002, 2002},
PackedUint32: []uint32{1003, 2003},
PackedUint64: []uint64{1004, 2004},
PackedSint32: []int32{1005, 2005},
PackedSint64: []int64{1006, 2006},
PackedFixed32: []uint32{1007, 2007},
PackedFixed64: []uint64{1008, 2008},
PackedSfixed32: []int32{1009, 2009},
PackedSfixed64: []int64{1010, 2010},
PackedFloat: []float32{1011.5, 2011.5},
PackedDouble: []float64{1012.5, 2012.5},
PackedBool: []bool{true, false},
PackedEnum: []testpb.ForeignEnum{
testpb.ForeignEnum_FOREIGN_FOO,
testpb.ForeignEnum_FOREIGN_BAR,
},
}, build(
&testpb.TestPackedExtensions{},
extend(testpb.E_PackedInt32Extension, []int32{1001, 2001}),
extend(testpb.E_PackedInt64Extension, []int64{1002, 2002}),
extend(testpb.E_PackedUint32Extension, []uint32{1003, 2003}),
extend(testpb.E_PackedUint64Extension, []uint64{1004, 2004}),
extend(testpb.E_PackedSint32Extension, []int32{1005, 2005}),
extend(testpb.E_PackedSint64Extension, []int64{1006, 2006}),
extend(testpb.E_PackedFixed32Extension, []uint32{1007, 2007}),
extend(testpb.E_PackedFixed64Extension, []uint64{1008, 2008}),
extend(testpb.E_PackedSfixed32Extension, []int32{1009, 2009}),
extend(testpb.E_PackedSfixed64Extension, []int64{1010, 2010}),
extend(testpb.E_PackedFloatExtension, []float32{1011.5, 2011.5}),
extend(testpb.E_PackedDoubleExtension, []float64{1012.5, 2012.5}),
extend(testpb.E_PackedBoolExtension, []bool{true, false}),
extend(testpb.E_PackedEnumExtension, []testpb.ForeignEnum{
testpb.ForeignEnum_FOREIGN_FOO,
testpb.ForeignEnum_FOREIGN_BAR,
}),
)},
wire: pack.Message{
pack.Tag{90, pack.BytesType}, pack.LengthPrefix{
pack.Varint(1001), pack.Varint(2001),
},
pack.Tag{91, pack.BytesType}, pack.LengthPrefix{
pack.Varint(1002), pack.Varint(2002),
},
pack.Tag{92, pack.BytesType}, pack.LengthPrefix{
pack.Uvarint(1003), pack.Uvarint(2003),
},
pack.Tag{93, pack.BytesType}, pack.LengthPrefix{
pack.Uvarint(1004), pack.Uvarint(2004),
},
pack.Tag{94, pack.BytesType}, pack.LengthPrefix{
pack.Svarint(1005), pack.Svarint(2005),
},
pack.Tag{95, pack.BytesType}, pack.LengthPrefix{
pack.Svarint(1006), pack.Svarint(2006),
},
pack.Tag{96, pack.BytesType}, pack.LengthPrefix{
pack.Uint32(1007), pack.Uint32(2007),
},
pack.Tag{97, pack.BytesType}, pack.LengthPrefix{
pack.Uint64(1008), pack.Uint64(2008),
},
pack.Tag{98, pack.BytesType}, pack.LengthPrefix{
pack.Int32(1009), pack.Int32(2009),
},
pack.Tag{99, pack.BytesType}, pack.LengthPrefix{
pack.Int64(1010), pack.Int64(2010),
},
pack.Tag{100, pack.BytesType}, pack.LengthPrefix{
pack.Float32(1011.5), pack.Float32(2011.5),
},
pack.Tag{101, pack.BytesType}, pack.LengthPrefix{
pack.Float64(1012.5), pack.Float64(2012.5),
},
pack.Tag{102, pack.BytesType}, pack.LengthPrefix{
pack.Bool(true), pack.Bool(false),
},
pack.Tag{103, pack.BytesType}, pack.LengthPrefix{
pack.Varint(int(testpb.ForeignEnum_FOREIGN_FOO)),
pack.Varint(int(testpb.ForeignEnum_FOREIGN_BAR)),
},
}.Marshal(),
},
{
desc: "repeated messages",
decodeTo: []proto.Message{&testpb.TestAllTypes{