diff --git a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/PackedArrayEncoder.kt b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/PackedArrayEncoder.kt index 812ca3074a..34a4885188 100644 --- a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/PackedArrayEncoder.kt +++ b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/PackedArrayEncoder.kt @@ -25,6 +25,12 @@ internal class PackedArrayEncoder( throw SerializationException("Packing only supports primitive number types") } + override fun endEncode(descriptor: SerialDescriptor) { + if (stream.size() > 0) { + super.endEncode(descriptor) + } + } + override fun encodeTaggedString(tag: ProtoDesc, value: String) { throw SerializationException("Packing only supports primitive number types") } diff --git a/formats/protobuf/commonTest/src/kotlinx/serialization/protobuf/PackedArraySerializerTest.kt b/formats/protobuf/commonTest/src/kotlinx/serialization/protobuf/PackedArraySerializerTest.kt index d6e604fd11..630602b13d 100644 --- a/formats/protobuf/commonTest/src/kotlinx/serialization/protobuf/PackedArraySerializerTest.kt +++ b/formats/protobuf/commonTest/src/kotlinx/serialization/protobuf/PackedArraySerializerTest.kt @@ -51,6 +51,12 @@ class PackedArraySerializerTest { val s: List ) + @Serializable + data class PackedIntCarrier( + @ProtoPacked + val i: List + ) + /** * Test that when packing is specified the array is encoded as packed */ @@ -132,4 +138,30 @@ class PackedArraySerializerTest { assertEquals(listData, decoded) } + /** + * Test that empty packed repeated field is not presented in a message. + */ + @Test + fun testEncodeEmptyPackedList() { + val obj = PackedIntCarrier(emptyList()) + val encoded = ProtoBuf.encodeToHexString(obj) + assertEquals("", encoded) + } + + /** + * Test that absence of packed field and explicit presence with a length 0 are decoded an empty list. + */ + @Test + fun testDecodeEmptyPackedList() { + val explicitlyEmpty = "0a00" + + val obj = PackedIntCarrier(emptyList()) + + val decodedExplicitEmpty = ProtoBuf.decodeFromHexString(explicitlyEmpty) + val decodedAbsentField = ProtoBuf.decodeFromHexString("") + + assertEquals(obj, decodedExplicitEmpty) + assertEquals(obj, decodedAbsentField) + } + }