Skip to content

Commit a7109d8

Browse files
authored
Fix negative enums in protobuf not serializing & de-serializing (#2400)
From language guide: Enumerator constants must be in the range of a 32-bit integer. Since enum values use varint encoding on the wire, negative values are inefficient and thus not recommended (but still possible).
1 parent 1e88d42 commit a7109d8

File tree

3 files changed

+4
-3
lines changed

3 files changed

+4
-3
lines changed

formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ internal open class ProtobufDecoder(
8080

8181
private fun findIndexByTag(descriptor: SerialDescriptor, protoTag: Int): Int {
8282
// Fast-path: tags are incremental, 1-based
83-
if (protoTag < descriptor.elementsCount) {
83+
if (protoTag < descriptor.elementsCount && protoTag >= 0) {
8484
val protoId = extractProtoId(descriptor, protoTag, true)
8585
if (protoId == protoTag) return protoTag
8686
}

formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/RandomTests.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,11 @@ class RandomTest : ShouldSpec() {
162162
}
163163
}
164164

165-
enum class KCoffee { AMERICANO, LATTE, CAPPUCCINO }
165+
enum class KCoffee(val value: Int) { AMERICANO(0), LATTE(1), CAPPUCCINO(2), @ProtoNumber(-1) NO_COFFEE(-1) }
166166

167167
@Serializable
168168
data class KTestEnum(@ProtoNumber(1) val a: KCoffee): IMessage {
169-
override fun toProtobufMessage() = TestEnum.newBuilder().setA(TestEnum.Coffee.forNumber(a.ordinal)).build()
169+
override fun toProtobufMessage() = TestEnum.newBuilder().setA(TestEnum.Coffee.forNumber(a.value)).build()
170170

171171
companion object : Gen<KTestEnum> {
172172
override fun generate(): KTestEnum = KTestEnum(Gen.oneOf<KCoffee>().generate())

formats/protobuf/testProto/test_data.proto

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ message TestEnum {
5959
Americano = 0;
6060
Latte = 1;
6161
Capuccino = 2;
62+
NoCoffee = -1;
6263
}
6364
required Coffee a = 1;
6465
}

0 commit comments

Comments
 (0)