diff --git a/internal/cmd/generate-types/impl.go b/internal/cmd/generate-types/impl.go index 700ae27b..bca586c1 100644 --- a/internal/cmd/generate-types/impl.go +++ b/internal/cmd/generate-types/impl.go @@ -556,11 +556,15 @@ var coder{{.Name}}SliceValue = valueCoderFuncs{ // size{{.Name}}PackedSliceValue returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}. func size{{.Name}}PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } {{if .WireType.ConstSize -}} - n := list.Len() * {{template "SizeValue" .}} + n := llen * {{template "SizeValue" .}} {{- else -}} n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += {{template "SizeValue" .}} } diff --git a/internal/impl/codec_gen.go b/internal/impl/codec_gen.go index bc7e4140..060d5bd8 100644 --- a/internal/impl/codec_gen.go +++ b/internal/impl/codec_gen.go @@ -296,8 +296,12 @@ var coderBoolSliceValue = valueCoderFuncs{ // sizeBoolPackedSliceValue returns the size of wire encoding a []bool value as a packed repeated Bool. func sizeBoolPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(wire.EncodeBool(v.Bool())) } @@ -420,8 +424,12 @@ var coderEnumSliceValue = valueCoderFuncs{ // sizeEnumPackedSliceValue returns the size of wire encoding a [] value as a packed repeated Enum. func sizeEnumPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(uint64(v.Enum())) } @@ -737,8 +745,12 @@ var coderInt32SliceValue = valueCoderFuncs{ // sizeInt32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Int32. func sizeInt32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(uint64(int32(v.Int()))) } @@ -1054,8 +1066,12 @@ var coderSint32SliceValue = valueCoderFuncs{ // sizeSint32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Sint32. func sizeSint32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(wire.EncodeZigZag(int64(int32(v.Int())))) } @@ -1371,8 +1387,12 @@ var coderUint32SliceValue = valueCoderFuncs{ // sizeUint32PackedSliceValue returns the size of wire encoding a []uint32 value as a packed repeated Uint32. func sizeUint32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(uint64(uint32(v.Uint()))) } @@ -1688,8 +1708,12 @@ var coderInt64SliceValue = valueCoderFuncs{ // sizeInt64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Int64. func sizeInt64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(uint64(v.Int())) } @@ -2005,8 +2029,12 @@ var coderSint64SliceValue = valueCoderFuncs{ // sizeSint64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Sint64. func sizeSint64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(wire.EncodeZigZag(v.Int())) } @@ -2322,8 +2350,12 @@ var coderUint64SliceValue = valueCoderFuncs{ // sizeUint64PackedSliceValue returns the size of wire encoding a []uint64 value as a packed repeated Uint64. func sizeUint64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() + llen := list.Len() + if llen == 0 { + return 0 + } n := 0 - for i, llen := 0, list.Len(); i < llen; i++ { + for i, llen := 0, llen; i < llen; i++ { v := list.Get(i) n += wire.SizeVarint(v.Uint()) } @@ -2627,7 +2659,11 @@ var coderSfixed32SliceValue = valueCoderFuncs{ // sizeSfixed32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Sfixed32. func sizeSfixed32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed32() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed32() return tagsize + wire.SizeBytes(n) } @@ -2924,7 +2960,11 @@ var coderFixed32SliceValue = valueCoderFuncs{ // sizeFixed32PackedSliceValue returns the size of wire encoding a []uint32 value as a packed repeated Fixed32. func sizeFixed32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed32() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed32() return tagsize + wire.SizeBytes(n) } @@ -3221,7 +3261,11 @@ var coderFloatSliceValue = valueCoderFuncs{ // sizeFloatPackedSliceValue returns the size of wire encoding a []float32 value as a packed repeated Float. func sizeFloatPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed32() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed32() return tagsize + wire.SizeBytes(n) } @@ -3518,7 +3562,11 @@ var coderSfixed64SliceValue = valueCoderFuncs{ // sizeSfixed64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Sfixed64. func sizeSfixed64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed64() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed64() return tagsize + wire.SizeBytes(n) } @@ -3815,7 +3863,11 @@ var coderFixed64SliceValue = valueCoderFuncs{ // sizeFixed64PackedSliceValue returns the size of wire encoding a []uint64 value as a packed repeated Fixed64. func sizeFixed64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed64() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed64() return tagsize + wire.SizeBytes(n) } @@ -4112,7 +4164,11 @@ var coderDoubleSliceValue = valueCoderFuncs{ // sizeDoublePackedSliceValue returns the size of wire encoding a []float64 value as a packed repeated Double. func sizeDoublePackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) { list := listv.List() - n := list.Len() * wire.SizeFixed64() + llen := list.Len() + if llen == 0 { + return 0 + } + n := llen * wire.SizeFixed64() return tagsize + wire.SizeBytes(n) } diff --git a/proto/testmessages_test.go b/proto/testmessages_test.go index 2e722f87..48c0c340 100644 --- a/proto/testmessages_test.go +++ b/proto/testmessages_test.go @@ -493,8 +493,23 @@ var testValidMessages = []testProto{ decodeTo: []proto.Message{ &testpb.TestAllTypes{}, &test3pb.TestAllTypes{}, - &testpb.TestAllExtensions{}, - }, + build( + &testpb.TestAllExtensions{}, + extend(testpb.E_RepeatedInt32Extension, []int32{}), + extend(testpb.E_RepeatedInt64Extension, []int64{}), + extend(testpb.E_RepeatedUint32Extension, []uint32{}), + extend(testpb.E_RepeatedUint64Extension, []uint64{}), + extend(testpb.E_RepeatedSint32Extension, []int32{}), + extend(testpb.E_RepeatedSint64Extension, []int64{}), + extend(testpb.E_RepeatedFixed32Extension, []uint32{}), + extend(testpb.E_RepeatedFixed64Extension, []uint64{}), + extend(testpb.E_RepeatedSfixed32Extension, []int32{}), + extend(testpb.E_RepeatedSfixed64Extension, []int64{}), + extend(testpb.E_RepeatedFloatExtension, []float32{}), + extend(testpb.E_RepeatedDoubleExtension, []float64{}), + extend(testpb.E_RepeatedBoolExtension, []bool{}), + extend(testpb.E_RepeatedNestedEnumExtension, []testpb.TestAllTypes_NestedEnum{}), + )}, wire: pack.Message{ pack.Tag{31, pack.BytesType}, pack.LengthPrefix{}, pack.Tag{32, pack.BytesType}, pack.LengthPrefix{}, @@ -602,8 +617,23 @@ var testValidMessages = []testProto{ desc: "packed repeated types (zero length)", decodeTo: []proto.Message{ &testpb.TestPackedTypes{}, - &testpb.TestPackedExtensions{}, - }, + build( + &testpb.TestPackedExtensions{}, + extend(testpb.E_PackedInt32Extension, []int32{}), + extend(testpb.E_PackedInt64Extension, []int64{}), + extend(testpb.E_PackedUint32Extension, []uint32{}), + extend(testpb.E_PackedUint64Extension, []uint64{}), + extend(testpb.E_PackedSint32Extension, []int32{}), + extend(testpb.E_PackedSint64Extension, []int64{}), + extend(testpb.E_PackedFixed32Extension, []uint32{}), + extend(testpb.E_PackedFixed64Extension, []uint64{}), + extend(testpb.E_PackedSfixed32Extension, []int32{}), + extend(testpb.E_PackedSfixed64Extension, []int64{}), + extend(testpb.E_PackedFloatExtension, []float32{}), + extend(testpb.E_PackedDoubleExtension, []float64{}), + extend(testpb.E_PackedBoolExtension, []bool{}), + extend(testpb.E_PackedEnumExtension, []testpb.ForeignEnum{}), + )}, wire: pack.Message{ pack.Tag{90, pack.BytesType}, pack.LengthPrefix{}, pack.Tag{91, pack.BytesType}, pack.LengthPrefix{},