summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoğaç Eldenk <dogac@carbonhealth.com>2023-10-10 19:17:05 +0300
committerGitHub <noreply@github.com>2023-10-10 18:17:05 +0200
commita675cb3f3d7ae1d49243f36c99e5a18ba3cf1bd5 (patch)
tree1dc59d48967741f30b81d95a4970c29c6e2eb6da
parent79ecba6e813cc0d59758c9d3f229288b6bd90e8a (diff)
downloadkotlinx.serialization-a675cb3f3d7ae1d49243f36c99e5a18ba3cf1bd5.tar.gz
Add protobuf conformance tests (#2404)
Add conformance tests using test_messages_proto3 construct google provides
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3EnumTest.kt90
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MapTest.kt154
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MessageTest.kt65
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3OneofTest.kt131
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PackedTest.kt99
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PrimitiveTest.kt77
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3RepeatedTest.kt133
-rw-r--r--formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3UnpackedTest.kt84
-rw-r--r--formats/protobuf/testProto/test_messages_proto3.proto289
9 files changed, 1122 insertions, 0 deletions
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3EnumTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3EnumTest.kt
new file mode 100644
index 00000000..7b2dda22
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3EnumTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Enum(
+ @ProtoNumber(21) val optionalNestedEnum: KNestedEnum = KNestedEnum.FOO,
+ @ProtoNumber(22) val optionalForeignEnum: KForeignEnum = KForeignEnum.FOREIGN_FOO,
+ @ProtoNumber(23) val optionalAliasedEnum: KAliasedEnum = KAliasedEnum.ALIAS_FOO,
+) {
+ enum class KNestedEnum {
+ @ProtoNumber(0)
+ FOO,
+
+ @ProtoNumber(1)
+ BAR,
+
+ @ProtoNumber(2)
+ BAZ,
+
+ @ProtoNumber(-1)
+ NEG;
+
+ fun toProto() = TestMessagesProto3.TestAllTypesProto3.NestedEnum.valueOf(this.name)
+ }
+
+
+ enum class KAliasedEnum {
+ @ProtoNumber(0)
+ ALIAS_FOO,
+
+ @ProtoNumber(1)
+ ALIAS_BAR,
+
+ @ProtoNumber(2)
+ ALIAS_BAZ,
+
+ @ProtoNumber(2)
+ MOO,
+
+ @ProtoNumber(2)
+ moo,
+
+ @ProtoNumber(2)
+ bAz;
+
+ fun toProto() = TestMessagesProto3.TestAllTypesProto3.AliasedEnum.valueOf(this.name)
+ }
+}
+
+enum class KForeignEnum {
+ @ProtoNumber(0)
+ FOREIGN_FOO,
+
+ @ProtoNumber(1)
+ FOREIGN_BAR,
+
+ @ProtoNumber(2)
+ FOREIGN_BAZ;
+
+ fun toProto() = TestMessagesProto3.ForeignEnum.valueOf(this.name)
+}
+
+class Proto3EnumTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Enum(
+ optionalNestedEnum = KTestMessagesProto3Enum.KNestedEnum.NEG,
+ optionalForeignEnum = KForeignEnum.FOREIGN_BAR,
+ optionalAliasedEnum = KTestMessagesProto3Enum.KAliasedEnum.ALIAS_BAR
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.optionalNestedEnum.toProto(), restored.optionalNestedEnum)
+ assertEquals(message.optionalForeignEnum.toProto(), restored.optionalForeignEnum)
+ assertEquals(message.optionalAliasedEnum.toProto(), restored.optionalAliasedEnum)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Enum>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MapTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MapTest.kt
new file mode 100644
index 00000000..a9614249
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MapTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import io.kotlintest.properties.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Map(
+ @ProtoNumber(56) val mapInt32Int32: Map<Int, Int> = emptyMap(),
+ @ProtoNumber(57) val mapInt64Int64: Map<Long, Long> = emptyMap(),
+ @ProtoNumber(58) val mapUint32Uint32: Map<UInt, UInt> = emptyMap(),
+ @ProtoNumber(59) val mapUint64Uint64: Map<ULong, ULong> = emptyMap(),
+ @ProtoNumber(60) val mapSint32Sint32: Map<Int, Int> = emptyMap(),
+ @ProtoNumber(61) val mapSint64Sint64: Map<Long, Long> = emptyMap(),
+ @ProtoNumber(62) val mapFixed32Fixed32: Map<Int, Int> = emptyMap(),
+ @ProtoNumber(63) val mapFixed64Fixed64: Map<Long, Long> = emptyMap(),
+ @ProtoNumber(64) val mapSfixed32Sfixed32: Map<Int, Int> = emptyMap(),
+ @ProtoNumber(65) val mapSfixed64Sfixed64: Map<Long, Long> = emptyMap(),
+ @ProtoNumber(66) val mapInt32Float: Map<Int, Float> = emptyMap(),
+ @ProtoNumber(67) val mapInt32Double: Map<Int, Double> = emptyMap(),
+ @ProtoNumber(68) val mapBoolBool: Map<Boolean, Boolean> = emptyMap(),
+ @ProtoNumber(69) val mapStringString: Map<String, String> = emptyMap(),
+ @ProtoNumber(70) val mapStringBytes: Map<String, ByteArray> = emptyMap(),
+ @ProtoNumber(71) val mapStringNestedMessage: Map<String, KTestMessagesProto3Message.KNestedMessage> = emptyMap(),
+ @ProtoNumber(72) val mapStringForeignMessage: Map<String, KForeignMessage> = emptyMap(),
+ @ProtoNumber(73) val mapStringNestedEnum: Map<String, KTestMessagesProto3Enum.KNestedEnum> = emptyMap(),
+ @ProtoNumber(74) val mapStringForeignEnum: Map<String, KForeignEnum> = emptyMap(),
+)
+
+class Proto3MapTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Map(
+ mapInt32Int32 = Gen.map(Gen.int(), Gen.int()).generate(),
+ mapInt64Int64 = Gen.map(Gen.long(), Gen.long()).generate(),
+ mapUint32Uint32 = Gen.map(Gen.int().map { it.toUInt() }, Gen.int().map { it.toUInt() }).generate(),
+ mapUint64Uint64 = Gen.map(Gen.int().map { it.toULong() }, Gen.int().map { it.toULong() }).generate(),
+ mapInt32Float = Gen.map(Gen.int(), Gen.float()).generate(),
+ mapInt32Double = Gen.map(Gen.int(), Gen.double()).generate(),
+ mapBoolBool = Gen.map(Gen.bool(), Gen.bool()).generate(),
+ mapStringString = Gen.map(Gen.string(), Gen.string()).generate(),
+ mapStringBytes = Gen.map(Gen.string(), Gen.string().map { it.toByteArray() }).generate(),
+ mapStringNestedMessage = mapOf(
+ "asd_1" to KTestMessagesProto3Message.KNestedMessage(
+ 1,
+ null
+ ),
+ "asi_#" to KTestMessagesProto3Message.KNestedMessage(
+ 2,
+ KTestMessagesProto3Message(
+ KTestMessagesProto3Message.KNestedMessage(3, null),
+ )
+ )
+ ),
+ mapStringForeignMessage = mapOf(
+ "" to KForeignMessage(1),
+ "-2" to KForeignMessage(-12),
+ ),
+ mapStringNestedEnum = Gen.map(
+ Gen.string(), Gen.oneOf(
+ KTestMessagesProto3Enum.KNestedEnum.entries,
+ )
+ ).generate(),
+ mapStringForeignEnum = Gen.map(
+ Gen.string(), Gen.oneOf(
+ KForeignEnum.entries,
+ )
+ ).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+
+ assertEquals(message.mapInt32Int32, restored.mapInt32Int32Map)
+ assertEquals(message.mapInt64Int64, restored.mapInt64Int64Map)
+ assertEquals(
+ message.mapUint32Uint32,
+ restored.mapUint32Uint32Map.map { it.key.toUInt() to it.value.toUInt() }.toMap()
+ )
+ assertEquals(
+ message.mapUint64Uint64,
+ restored.mapUint64Uint64Map.map { it.key.toULong() to it.value.toULong() }.toMap()
+ )
+ assertEquals(message.mapInt32Float, restored.mapInt32FloatMap)
+ assertEquals(message.mapInt32Double, restored.mapInt32DoubleMap)
+ assertEquals(message.mapBoolBool, restored.mapBoolBoolMap)
+ assertEquals(message.mapStringString, restored.mapStringStringMap)
+ assertContentEquals(
+ message.mapStringBytes.mapValues { it.value.toString(Charsets.UTF_32) }.entries.toList(),
+ restored.mapStringBytesMap.mapValues { it.value.toByteArray().toString(Charsets.UTF_32) }.entries.toList()
+ )
+ assertEquals(
+ message.mapStringNestedMessage.mapValues { it.value.toProto() },
+ restored.mapStringNestedMessageMap
+ )
+ assertEquals(
+ message.mapStringForeignMessage.mapValues { it.value.toProto() },
+ restored.mapStringForeignMessageMap
+ )
+ assertEquals(
+ message.mapStringNestedEnum.mapValues { it.value.name },
+ restored.mapStringNestedEnumMap.mapValues { it.value.name },
+ )
+ assertEquals(
+ message.mapStringForeignEnum.mapValues { it.value.name },
+ restored.mapStringForeignEnumMap.mapValues { it.value.name }
+ )
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Map>(restored.toByteArray())
+ assertEquals(message.copy(mapStringBytes = mapOf()), restoredMessage.copy(mapStringBytes = mapOf()))
+ }
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2417
+ fun signedAndFixed() {
+ val message = KTestMessagesProto3Map(
+ mapSint32Sint32 = Gen.map(Gen.int(), Gen.int()).generate(),
+ mapSint64Sint64 = Gen.map(Gen.long(), Gen.long()).generate(),
+ mapFixed32Fixed32 = Gen.map(Gen.int(), Gen.int()).generate(),
+ mapFixed64Fixed64 = Gen.map(Gen.long(), Gen.long()).generate(),
+ mapSfixed32Sfixed32 = Gen.map(Gen.int(), Gen.int()).generate(),
+ mapSfixed64Sfixed64 = Gen.map(Gen.long(), Gen.long()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+
+ assertContentEquals(message.mapSint32Sint32.entries.toList(), restored.mapSint32Sint32Map.entries.toList())
+ assertContentEquals(message.mapSint64Sint64.entries.toList(), restored.mapSint64Sint64Map.entries.toList())
+ assertContentEquals(message.mapFixed32Fixed32.entries.toList(), restored.mapFixed32Fixed32Map.entries.toList())
+ assertContentEquals(message.mapFixed64Fixed64.entries.toList(), restored.mapFixed64Fixed64Map.entries.toList())
+ assertContentEquals(
+ message.mapSfixed32Sfixed32.entries.toList(),
+ restored.mapSfixed32Sfixed32Map.entries.toList()
+ )
+ assertContentEquals(
+ message.mapSfixed64Sfixed64.entries.toList(),
+ restored.mapSfixed64Sfixed64Map.entries.toList()
+ )
+
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Map>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MessageTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MessageTest.kt
new file mode 100644
index 00000000..c369d6eb
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3MessageTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Message(
+ @ProtoNumber(18) val optionalNestedMessage: KNestedMessage? = null,
+ @ProtoNumber(19) val optionalForeignMessage: KForeignMessage? = null,
+) {
+ @Serializable
+ data class KNestedMessage(
+ @ProtoNumber(1) val a: Int = 0,
+ @ProtoNumber(2) val corecursive: KTestMessagesProto3Message? = null,
+ ) {
+ fun toProto(): TestMessagesProto3.TestAllTypesProto3.NestedMessage =
+ TestMessagesProto3.TestAllTypesProto3.NestedMessage.parseFrom(
+ ProtoBuf.encodeToByteArray(this)
+ )
+ }
+}
+
+@Serializable
+data class KForeignMessage(
+ @ProtoNumber(1) val c: Int = 0,
+) {
+ fun toProto(): TestMessagesProto3.ForeignMessage =
+ TestMessagesProto3.ForeignMessage.parseFrom(
+ ProtoBuf.encodeToByteArray(this)
+ )
+}
+
+class Proto3MessageTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Message(
+ optionalNestedMessage = KTestMessagesProto3Message.KNestedMessage(
+ a = 150,
+ corecursive = KTestMessagesProto3Message(
+ optionalNestedMessage = KTestMessagesProto3Message.KNestedMessage(
+ a = 42,
+ )
+ )
+ ),
+ optionalForeignMessage = KForeignMessage(
+ c = 150,
+ )
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+ assertEquals(message.optionalNestedMessage?.a, restored.optionalNestedMessage.a)
+ assertEquals(
+ message.optionalNestedMessage?.corecursive?.optionalNestedMessage?.a,
+ restored.optionalNestedMessage.corecursive.optionalNestedMessage.a
+ )
+ assertEquals(message.optionalForeignMessage?.c, restored.optionalForeignMessage.c)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3OneofTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3OneofTest.kt
new file mode 100644
index 00000000..fda811ea
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3OneofTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessageProto3Oneof(
+ @ProtoNumber(111) val oneofUint32: UInt? = null,
+ @ProtoNumber(112) val oneofNestedMessage: KTestMessagesProto3Message.KNestedMessage? = null,
+ @ProtoNumber(113) val oneofString: String? = null,
+ @ProtoNumber(114) val oneofBytes: ByteArray? = null,
+ @ProtoNumber(115) val oneofBool: Boolean? = null,
+ @ProtoNumber(116) val oneofUint64: ULong? = null,
+ @ProtoNumber(117) val oneofFloat: Float? = null,
+ @ProtoNumber(118) val oneofDouble: Double? = null,
+ @ProtoNumber(119) val oneofEnum: KTestMessagesProto3Enum.KNestedEnum? = null,
+) {
+ init {
+ require(
+ listOf(
+ oneofUint32,
+ oneofNestedMessage,
+ oneofString,
+ oneofBytes,
+ oneofBool,
+ oneofUint64,
+ oneofFloat,
+ oneofDouble,
+ oneofEnum,
+ ).count { it != null } == 1
+ )
+ }
+}
+
+class Proto3OneofTest {
+
+ /**
+ * Verify that the given [KTestMessageProto3Oneof] is correctly encoded and decoded as
+ * [TestMessagesProto3.TestAllTypesProto3] by running the [verificationFunction]. This
+ * method also verifies that the encoded and decoded message is equal to the original message.
+ *
+ * @param verificationFunction a function that verifies the encoded and decoded message. First parameter
+ * is the original message and the second parameter is the decoded protobuf library message.
+ * @receiver the [KTestMessageProto3Oneof] to verify
+ */
+ private fun KTestMessageProto3Oneof.verify(
+ verificationFunction: (KTestMessageProto3Oneof, TestMessagesProto3.TestAllTypesProto3) -> Unit,
+ ) {
+ val bytes = ProtoBuf.encodeToByteArray(this)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ verificationFunction.invoke(this, restored)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessageProto3Oneof>(restored.toByteArray())
+
+ // [equals] method is not implemented for [ByteArray] so we need to compare it separately.
+ assertEquals(this, restoredMessage.copy(oneofBytes = this.oneofBytes))
+ assertContentEquals(this.oneofBytes, restoredMessage.oneofBytes)
+ }
+
+ @Test
+ fun uint32() {
+ KTestMessageProto3Oneof(oneofUint32 = 150u).verify { self, restored ->
+ assertEquals(self.oneofUint32, restored.oneofUint32.toUInt())
+ }
+ }
+
+ @Test
+ fun nestedMessage() {
+ KTestMessageProto3Oneof(
+ oneofNestedMessage = KTestMessagesProto3Message.KNestedMessage(a = 150),
+ ).verify { self, restored ->
+ assertEquals(self.oneofNestedMessage?.a, restored.oneofNestedMessage.a)
+ }
+ }
+
+ @Test
+ fun string() {
+ KTestMessageProto3Oneof(oneofString = "150").verify { self, restored ->
+ assertEquals(self.oneofString, restored.oneofString)
+ }
+ }
+
+ @Test
+ fun bytes() {
+ KTestMessageProto3Oneof(oneofBytes = "150".toByteArray()).verify { self, restored ->
+ assertContentEquals(self.oneofBytes, restored.oneofBytes.toByteArray())
+ }
+ }
+
+ @Test
+ fun bool() {
+ KTestMessageProto3Oneof(oneofBool = true).verify { self, restored ->
+ assertEquals(self.oneofBool, restored.oneofBool)
+ }
+ }
+
+ @Test
+ fun uint64() {
+ KTestMessageProto3Oneof(oneofUint64 = 150uL).verify { self, restored ->
+ assertEquals(self.oneofUint64, restored.oneofUint64.toULong())
+ }
+ }
+
+ @Test
+ fun float() {
+ KTestMessageProto3Oneof(oneofFloat = 150f).verify { self, restored ->
+ assertEquals(self.oneofFloat, restored.oneofFloat)
+ }
+ }
+
+ @Test
+ fun double() {
+ KTestMessageProto3Oneof(oneofDouble = 150.0).verify { self, restored ->
+ assertEquals(self.oneofDouble, restored.oneofDouble)
+ }
+ }
+
+ @Test
+ fun enum() {
+ KTestMessageProto3Oneof(oneofEnum = KTestMessagesProto3Enum.KNestedEnum.BAR).verify { self, restored ->
+ assertEquals(self.oneofEnum?.name, restored.oneofEnum.name)
+ }
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PackedTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PackedTest.kt
new file mode 100644
index 00000000..e0da0bb8
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PackedTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import io.kotlintest.properties.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Packed(
+ @ProtoNumber(75) @ProtoPacked val packedInt32: List<Int> = emptyList(),
+ @ProtoNumber(76) @ProtoPacked val packedInt64: List<Long> = emptyList(),
+ @ProtoNumber(77) @ProtoPacked val packedUint32: List<UInt> = emptyList(),
+ @ProtoNumber(78) @ProtoPacked val packedUint64: List<ULong> = emptyList(),
+ @ProtoNumber(79) @ProtoPacked val packedSint32: List<Int> = emptyList(),
+ @ProtoNumber(80) @ProtoPacked val packedSint64: List<Long> = emptyList(),
+ @ProtoNumber(81) @ProtoPacked val packedFixed32: List<Int> = emptyList(),
+ @ProtoNumber(82) @ProtoPacked val packedFixed64: List<Long> = emptyList(),
+ @ProtoNumber(83) @ProtoPacked val packedSfixed32: List<Int> = emptyList(),
+ @ProtoNumber(84) @ProtoPacked val packedSfixed64: List<Long> = emptyList(),
+ @ProtoNumber(85) @ProtoPacked val packedFloat: List<Float> = emptyList(),
+ @ProtoNumber(86) @ProtoPacked val packedDouble: List<Double> = emptyList(),
+ @ProtoNumber(87) @ProtoPacked val packedBool: List<Boolean> = emptyList(),
+)
+
+class Proto3PackedTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Packed(
+ packedInt32 = Gen.list(Gen.int()).generate(),
+ packedInt64 = Gen.list(Gen.long()).generate(),
+ packedFloat = Gen.list(Gen.float()).generate(),
+ packedDouble = Gen.list(Gen.double()).generate(),
+ packedBool = Gen.list(Gen.bool()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.packedInt32, restored.packedInt32List)
+ assertEquals(message.packedInt64, restored.packedInt64List)
+ assertEquals(message.packedFloat, restored.packedFloatList)
+ assertEquals(message.packedDouble, restored.packedDoubleList)
+ assertEquals(message.packedBool, restored.packedBoolList)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Packed>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2419
+ fun signedAndFixed() {
+ val message = KTestMessagesProto3Packed(
+ packedSint32 = Gen.list(Gen.int()).generate(),
+ packedSint64 = Gen.list(Gen.long()).generate(),
+ packedFixed32 = Gen.list(Gen.int()).generate(),
+ packedFixed64 = Gen.list(Gen.long()).generate(),
+ packedSfixed32 = Gen.list(Gen.int()).generate(),
+ packedSfixed64 = Gen.list(Gen.long()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.packedSint32, restored.packedSint32List)
+ assertEquals(message.packedSint64, restored.packedSint64List)
+ assertEquals(message.packedFixed32, restored.packedFixed32List)
+ assertEquals(message.packedFixed64, restored.packedFixed64List)
+ assertEquals(message.packedSfixed32, restored.packedSfixed32List)
+ assertEquals(message.packedSfixed64, restored.packedSfixed64List)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Packed>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2418
+ fun unsigned() {
+ val message = KTestMessagesProto3Packed(
+ packedUint32 = Gen.list(Gen.int().map { it.toUInt() }).generate(),
+ packedUint64 = Gen.list(Gen.long().map { it.toULong() }).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.packedUint32, restored.packedUint32List.map { it.toUInt() })
+ assertEquals(message.packedUint64, restored.packedUint64List.map { it.toULong() })
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Packed>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PrimitiveTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PrimitiveTest.kt
new file mode 100644
index 00000000..a7363f8f
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3PrimitiveTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Primitive(
+ @ProtoNumber(1) val optionalInt32: Int = 0,
+ @ProtoNumber(2) val optionalInt64: Long = 0,
+ @ProtoNumber(3) val optionalUint32: UInt = 0U,
+ @ProtoNumber(4) val optionalUint64: ULong = 0UL,
+ @ProtoNumber(5) @ProtoType(ProtoIntegerType.SIGNED) val optionalSint32: Int = 0,
+ @ProtoNumber(6) @ProtoType(ProtoIntegerType.SIGNED) val optionalSint64: Long = 0,
+ @ProtoNumber(7) @ProtoType(ProtoIntegerType.FIXED) val optionalFixed32: Int = 0,
+ @ProtoNumber(8) @ProtoType(ProtoIntegerType.FIXED) val optionalFixed64: Long = 0,
+ @ProtoNumber(9) @ProtoType(ProtoIntegerType.FIXED) val optionalSfixed32: Int = 0,
+ @ProtoNumber(10) @ProtoType(ProtoIntegerType.FIXED) val optionalSfixed64: Long = 0,
+ @ProtoNumber(11) val optionalFloat: Float = 0.0f,
+ @ProtoNumber(12) val optionalDouble: Double = 0.0,
+ @ProtoNumber(13) val optionalBool: Boolean = false,
+ @ProtoNumber(14) val optionalString: String = "",
+ @ProtoNumber(15) val optionalBytes: ByteArray = byteArrayOf(),
+)
+
+class Proto3PrimitiveTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Primitive(
+ optionalInt32 = Int.MAX_VALUE,
+ optionalInt64 = Long.MAX_VALUE,
+ optionalUint32 = UInt.MAX_VALUE,
+ optionalUint64 = ULong.MAX_VALUE,
+ optionalSint32 = Int.MAX_VALUE,
+ optionalSint64 = Long.MAX_VALUE,
+ optionalFixed32 = Int.MAX_VALUE,
+ optionalFixed64 = Long.MAX_VALUE,
+ optionalSfixed32 = Int.MAX_VALUE,
+ optionalSfixed64 = Long.MAX_VALUE,
+ optionalFloat = Float.MAX_VALUE,
+ optionalDouble = Double.MAX_VALUE,
+ optionalBool = true,
+ optionalString = "string",
+ optionalBytes = byteArrayOf(1, 2, 3, 4, 5)
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.optionalInt32, restored.optionalInt32)
+ assertEquals(message.optionalInt64, restored.optionalInt64)
+ assertEquals(message.optionalUint32, restored.optionalUint32.toUInt())
+ assertEquals(message.optionalUint64, restored.optionalUint64.toULong())
+ assertEquals(message.optionalSint32, restored.optionalSint32)
+ assertEquals(message.optionalSint64, restored.optionalSint64)
+ assertEquals(message.optionalFixed32, restored.optionalFixed32)
+ assertEquals(message.optionalFixed64, restored.optionalFixed64)
+ assertEquals(message.optionalSfixed32, restored.optionalSfixed32)
+ assertEquals(message.optionalSfixed64, restored.optionalSfixed64)
+ assertEquals(message.optionalFloat, restored.optionalFloat)
+ assertEquals(message.optionalDouble, restored.optionalDouble)
+ assertEquals(message.optionalBool, restored.optionalBool)
+ assertEquals(message.optionalString, restored.optionalString)
+ assertContentEquals(message.optionalBytes, restored.optionalBytes.toByteArray())
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Primitive>(restored.toByteArray())
+
+ // [equals] method is not implemented for [ByteArray] so we need to compare it separately.
+ assertEquals(message, restoredMessage.copy(optionalBytes = message.optionalBytes))
+ assertContentEquals(message.optionalBytes, restoredMessage.optionalBytes)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3RepeatedTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3RepeatedTest.kt
new file mode 100644
index 00000000..b3dab8c7
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3RepeatedTest.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import io.kotlintest.properties.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Repeated(
+ @ProtoNumber(31) @ProtoPacked val repeatedInt32: List<Int> = emptyList(),
+ @ProtoNumber(32) @ProtoPacked val repeatedInt64: List<Long> = emptyList(),
+ @ProtoNumber(33) @ProtoPacked val repeatedUint32: List<UInt> = emptyList(),
+ @ProtoNumber(34) @ProtoPacked val repeatedUint64: List<ULong> = emptyList(),
+ @ProtoNumber(35) @ProtoPacked val repeatedSint32: List<Int> = emptyList(),
+ @ProtoNumber(36) @ProtoPacked val repeatedSint64: List<Long> = emptyList(),
+ @ProtoNumber(37) @ProtoPacked val repeatedFixed32: List<Int> = emptyList(),
+ @ProtoNumber(38) @ProtoPacked val repeatedFixed64: List<Long> = emptyList(),
+ @ProtoNumber(39) @ProtoPacked val repeatedSfixed32: List<Int> = emptyList(),
+ @ProtoNumber(40) @ProtoPacked val repeatedSfixed64: List<Long> = emptyList(),
+ @ProtoNumber(41) @ProtoPacked val repeatedFloat: List<Float> = emptyList(),
+ @ProtoNumber(42) @ProtoPacked val repeatedDouble: List<Double> = emptyList(),
+ @ProtoNumber(43) @ProtoPacked val repeatedBool: List<Boolean> = emptyList(),
+ @ProtoNumber(44) val repeatedString: List<String> = emptyList(),
+ @ProtoNumber(45) val repeatedBytes: List<ByteArray> = emptyList(),
+ @ProtoNumber(48) val repeatedNestedMessages: List<KTestMessagesProto3Message.KNestedMessage> = emptyList(),
+ @ProtoNumber(49) val repeatedForeignMessages: List<KForeignMessage> = emptyList(),
+)
+
+class Proto3RepeatedTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Repeated(
+ repeatedInt32 = Gen.list(Gen.int()).generate(),
+ repeatedInt64 = Gen.list(Gen.long()).generate(),
+ repeatedFloat = Gen.list(Gen.float()).generate(),
+ repeatedDouble = Gen.list(Gen.double()).generate(),
+ repeatedBool = Gen.list(Gen.bool()).generate(),
+ repeatedString = Gen.list(Gen.string()).generate(),
+ repeatedBytes = Gen.list(Gen.string().map { it.toByteArray() }).generate(),
+ repeatedNestedMessages = listOf(
+ KTestMessagesProto3Message.KNestedMessage(
+ 1,
+ null
+ ),
+ KTestMessagesProto3Message.KNestedMessage(
+ 2,
+ KTestMessagesProto3Message(
+ KTestMessagesProto3Message.KNestedMessage(3, null),
+ )
+ )
+ ),
+ repeatedForeignMessages = listOf(
+ KForeignMessage(1),
+ KForeignMessage(-12),
+ )
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.repeatedInt32, restored.repeatedInt32List)
+ assertEquals(message.repeatedInt64, restored.repeatedInt64List)
+ assertEquals(message.repeatedFloat, restored.repeatedFloatList)
+ assertEquals(message.repeatedDouble, restored.repeatedDoubleList)
+ assertEquals(message.repeatedBool, restored.repeatedBoolList)
+ assertEquals(message.repeatedString, restored.repeatedStringList)
+ assertEquals(message.repeatedNestedMessages.map { it.toProto() }, restored.repeatedNestedMessageList)
+ assertEquals(message.repeatedForeignMessages.map { it.toProto() }, restored.repeatedForeignMessageList)
+ assertEquals(message.repeatedBytes.map { it.toList() }, restored.repeatedBytesList.map { it.toList() })
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray())
+ // [equals] method is not implemented for [ByteArray] so we need to compare it separately.
+ assertEquals(message, restoredMessage.copy(repeatedBytes = message.repeatedBytes))
+ assertContentEquals(
+ message.repeatedBytes.flatMap { it.toList() },
+ restoredMessage.repeatedBytes.flatMap { it.toList() },
+ )
+ }
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2419
+ fun signedAndFixed() {
+ val message = KTestMessagesProto3Repeated(
+ repeatedSint32 = Gen.list(Gen.int()).generate(),
+ repeatedSint64 = Gen.list(Gen.long()).generate(),
+ repeatedFixed32 = Gen.list(Gen.int()).generate(),
+ repeatedFixed64 = Gen.list(Gen.long()).generate(),
+ repeatedSfixed32 = Gen.list(Gen.int()).generate(),
+ repeatedSfixed64 = Gen.list(Gen.long()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.repeatedUint32, restored.repeatedUint32List.map { it.toUInt() })
+ assertEquals(message.repeatedUint64, restored.repeatedUint64List.map { it.toULong() })
+ assertEquals(message.repeatedSint32, restored.repeatedSint32List)
+ assertEquals(message.repeatedSint64, restored.repeatedSint64List)
+ assertEquals(message.repeatedFixed32, restored.repeatedFixed32List)
+ assertEquals(message.repeatedFixed64, restored.repeatedFixed64List)
+ assertEquals(message.repeatedSfixed32, restored.repeatedSfixed32List)
+ assertEquals(message.repeatedSfixed64, restored.repeatedSfixed64List)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2418
+ fun unsigned() {
+ val message = KTestMessagesProto3Repeated(
+ repeatedUint32 = Gen.list(Gen.int().map { it.toUInt() }).generate(),
+ repeatedUint64 = Gen.list(Gen.long().map { it.toULong() }).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.repeatedUint32, restored.repeatedUint32List.map { it.toUInt() })
+ assertEquals(message.repeatedUint64, restored.repeatedUint64List.map { it.toULong() })
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+}
diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3UnpackedTest.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3UnpackedTest.kt
new file mode 100644
index 00000000..dad773d9
--- /dev/null
+++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/conformance/Proto3UnpackedTest.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.protobuf.conformance
+
+import com.google.protobuf_test_messages.proto3.*
+import io.kotlintest.properties.*
+import kotlinx.serialization.*
+import kotlinx.serialization.protobuf.*
+import kotlin.test.*
+
+@Serializable
+data class KTestMessagesProto3Unpacked(
+ @ProtoNumber(89) val unpackedInt32: List<Int> = emptyList(),
+ @ProtoNumber(90) val unpackedInt64: List<Long> = emptyList(),
+ @ProtoNumber(91) val unpackedUint32: List<UInt> = emptyList(),
+ @ProtoNumber(92) val unpackedUint64: List<ULong> = emptyList(),
+ @ProtoNumber(93) val unpackedSint32: List<Int> = emptyList(),
+ @ProtoNumber(94) val unpackedSint64: List<Long> = emptyList(),
+ @ProtoNumber(95) val unpackedFixed32: List<Int> = emptyList(),
+ @ProtoNumber(96) val unpackedFixed64: List<Long> = emptyList(),
+ @ProtoNumber(97) val unpackedSfixed32: List<Int> = emptyList(),
+ @ProtoNumber(98) val unpackedSfixed64: List<Long> = emptyList(),
+ @ProtoNumber(99) val unpackedFloat: List<Float> = emptyList(),
+ @ProtoNumber(100) val unpackedDouble: List<Double> = emptyList(),
+ @ProtoNumber(101) val unpackedBool: List<Boolean> = emptyList(),
+)
+
+class Proto3UnpackedTest {
+ @Test
+ fun default() {
+ val message = KTestMessagesProto3Unpacked(
+ unpackedInt32 = Gen.list(Gen.int()).generate(),
+ unpackedInt64 = Gen.list(Gen.long()).generate(),
+ unpackedUint32 = Gen.list(Gen.int().map { it.toUInt() }).generate(),
+ unpackedUint64 = Gen.list(Gen.long().map { it.toULong() }).generate(),
+ unpackedFloat = Gen.list(Gen.float()).generate(),
+ unpackedDouble = Gen.list(Gen.double()).generate(),
+ unpackedBool = Gen.list(Gen.bool()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.unpackedInt32, restored.unpackedInt32List)
+ assertEquals(message.unpackedInt64, restored.unpackedInt64List)
+ assertEquals(message.unpackedUint32, restored.unpackedUint32List.map { it.toUInt() })
+ assertEquals(message.unpackedUint64, restored.unpackedUint64List.map { it.toULong() })
+ assertEquals(message.unpackedFloat, restored.unpackedFloatList)
+ assertEquals(message.unpackedDouble, restored.unpackedDoubleList)
+ assertEquals(message.unpackedBool, restored.unpackedBoolList)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Unpacked>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+
+ @Test
+ @Ignore
+ // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2419
+ fun signedAndFixed() {
+ val message = KTestMessagesProto3Unpacked(
+ unpackedSint32 = Gen.list(Gen.int()).generate(),
+ unpackedSint64 = Gen.list(Gen.long()).generate(),
+ unpackedFixed32 = Gen.list(Gen.int()).generate(),
+ unpackedFixed64 = Gen.list(Gen.long()).generate(),
+ unpackedSfixed32 = Gen.list(Gen.int()).generate(),
+ unpackedSfixed64 = Gen.list(Gen.long()).generate(),
+ )
+
+ val bytes = ProtoBuf.encodeToByteArray(message)
+ val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
+
+ assertEquals(message.unpackedSint32, restored.unpackedSint32List)
+ assertEquals(message.unpackedSint64, restored.unpackedSint64List)
+ assertEquals(message.unpackedFixed32, restored.unpackedFixed32List)
+ assertEquals(message.unpackedFixed64, restored.unpackedFixed64List)
+ assertEquals(message.unpackedSfixed32, restored.unpackedSfixed32List)
+ assertEquals(message.unpackedSfixed64, restored.unpackedSfixed64List)
+
+ val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Unpacked>(restored.toByteArray())
+ assertEquals(message, restoredMessage)
+ }
+}
diff --git a/formats/protobuf/testProto/test_messages_proto3.proto b/formats/protobuf/testProto/test_messages_proto3.proto
new file mode 100644
index 00000000..6b279957
--- /dev/null
+++ b/formats/protobuf/testProto/test_messages_proto3.proto
@@ -0,0 +1,289 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Test schema for proto3 messages. This test schema is used by:
+//
+// - benchmarks
+// - fuzz tests
+// - conformance tests
+//
+// https://github.com/protocolbuffers/protobuf/blob/5e03386555544e39c21236dca0097123edec8769/src/google/protobuf/test_messages_proto3.proto
+
+syntax = "proto3";
+
+package protobuf_test_messages.proto3;
+
+option java_package = "com.google.protobuf_test_messages.proto3";
+option objc_class_prefix = "Proto3";
+
+// This is the default, but we specify it here explicitly.
+option optimize_for = SPEED;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+
+option cc_enable_arenas = true;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+//
+// Also, crucially, all messages and enums in this file are eventually
+// submessages of this message. So for example, a fuzz test of TestAllTypes
+// could trigger bugs that occur in any message type in this file. We verify
+// this stays true in a unit test.
+message TestAllTypesProto3 {
+ message NestedMessage {
+ int32 a = 1;
+ TestAllTypesProto3 corecursive = 2;
+ }
+
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ NEG = -1; // Intentionally negative.
+ }
+
+ enum AliasedEnum {
+ option allow_alias = true;
+
+ ALIAS_FOO = 0;
+ ALIAS_BAR = 1;
+ ALIAS_BAZ = 2;
+ MOO = 2;
+ moo = 2;
+ bAz = 2;
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+ AliasedEnum optional_aliased_enum = 23;
+
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
+ string optional_cord = 25 [ctype = CORD];
+
+ TestAllTypesProto3 recursive_message = 27;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ // Packed
+ repeated int32 packed_int32 = 75 [packed = true];
+ repeated int64 packed_int64 = 76 [packed = true];
+ repeated uint32 packed_uint32 = 77 [packed = true];
+ repeated uint64 packed_uint64 = 78 [packed = true];
+ repeated sint32 packed_sint32 = 79 [packed = true];
+ repeated sint64 packed_sint64 = 80 [packed = true];
+ repeated fixed32 packed_fixed32 = 81 [packed = true];
+ repeated fixed64 packed_fixed64 = 82 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 83 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 84 [packed = true];
+ repeated float packed_float = 85 [packed = true];
+ repeated double packed_double = 86 [packed = true];
+ repeated bool packed_bool = 87 [packed = true];
+ repeated NestedEnum packed_nested_enum = 88 [packed = true];
+
+ // Unpacked
+ repeated int32 unpacked_int32 = 89 [packed = false];
+ repeated int64 unpacked_int64 = 90 [packed = false];
+ repeated uint32 unpacked_uint32 = 91 [packed = false];
+ repeated uint64 unpacked_uint64 = 92 [packed = false];
+ repeated sint32 unpacked_sint32 = 93 [packed = false];
+ repeated sint64 unpacked_sint64 = 94 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 95 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 96 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 97 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 98 [packed = false];
+ repeated float unpacked_float = 99 [packed = false];
+ repeated double unpacked_double = 100 [packed = false];
+ repeated bool unpacked_bool = 101 [packed = false];
+ repeated NestedEnum unpacked_nested_enum = 102 [packed = false];
+
+ // Map
+ map<int32, int32> map_int32_int32 = 56;
+ map<int64, int64> map_int64_int64 = 57;
+ map<uint32, uint32> map_uint32_uint32 = 58;
+ map<uint64, uint64> map_uint64_uint64 = 59;
+ map<sint32, sint32> map_sint32_sint32 = 60;
+ map<sint64, sint64> map_sint64_sint64 = 61;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 62;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 63;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
+ map<int32, float> map_int32_float = 66;
+ map<int32, double> map_int32_double = 67;
+ map<bool, bool> map_bool_bool = 68;
+ map<string, string> map_string_string = 69;
+ map<string, bytes> map_string_bytes = 70;
+ map<string, NestedMessage> map_string_nested_message = 71;
+ map<string, ForeignMessage> map_string_foreign_message = 72;
+ map<string, NestedEnum> map_string_nested_enum = 73;
+ map<string, ForeignEnum> map_string_foreign_enum = 74;
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ bool oneof_bool = 115;
+ uint64 oneof_uint64 = 116;
+ float oneof_float = 117;
+ double oneof_double = 118;
+ NestedEnum oneof_enum = 119;
+ google.protobuf.NullValue oneof_null_value = 120;
+ }
+
+ // Well-known types
+ google.protobuf.BoolValue optional_bool_wrapper = 201;
+ google.protobuf.Int32Value optional_int32_wrapper = 202;
+ google.protobuf.Int64Value optional_int64_wrapper = 203;
+ google.protobuf.UInt32Value optional_uint32_wrapper = 204;
+ google.protobuf.UInt64Value optional_uint64_wrapper = 205;
+ google.protobuf.FloatValue optional_float_wrapper = 206;
+ google.protobuf.DoubleValue optional_double_wrapper = 207;
+ google.protobuf.StringValue optional_string_wrapper = 208;
+ google.protobuf.BytesValue optional_bytes_wrapper = 209;
+
+ repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
+ repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
+ repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
+ repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
+ repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
+ repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
+ repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
+ repeated google.protobuf.StringValue repeated_string_wrapper = 218;
+ repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
+
+ google.protobuf.Duration optional_duration = 301;
+ google.protobuf.Timestamp optional_timestamp = 302;
+ google.protobuf.FieldMask optional_field_mask = 303;
+ google.protobuf.Struct optional_struct = 304;
+ google.protobuf.Any optional_any = 305;
+ google.protobuf.Value optional_value = 306;
+ google.protobuf.NullValue optional_null_value = 307;
+
+ repeated google.protobuf.Duration repeated_duration = 311;
+ repeated google.protobuf.Timestamp repeated_timestamp = 312;
+ repeated google.protobuf.FieldMask repeated_fieldmask = 313;
+ repeated google.protobuf.Struct repeated_struct = 324;
+ repeated google.protobuf.Any repeated_any = 315;
+ repeated google.protobuf.Value repeated_value = 316;
+ repeated google.protobuf.ListValue repeated_list_value = 317;
+
+ // Test field-name-to-JSON-name convention.
+ // (protobuf says names can be any valid C/C++ identifier.)
+ int32 fieldname1 = 401;
+ int32 field_name2 = 402;
+ int32 _field_name3 = 403;
+ int32 field__name4_ = 404;
+ int32 field0name5 = 405;
+ int32 field_0_name6 = 406;
+ int32 fieldName7 = 407;
+ int32 FieldName8 = 408;
+ int32 field_Name9 = 409;
+ int32 Field_Name10 = 410;
+ int32 FIELD_NAME11 = 411;
+ int32 FIELD_name12 = 412;
+ int32 __field_name13 = 413;
+ int32 __Field_name14 = 414;
+ int32 field__name15 = 415;
+ int32 field__Name16 = 416;
+ int32 field_name17__ = 417;
+ int32 Field_name18__ = 418;
+
+ // Reserved for testing unknown fields
+ reserved 501 to 510;
+}
+
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 0;
+ FOREIGN_BAR = 1;
+ FOREIGN_BAZ = 2;
+}
+
+message NullHypothesisProto3 {}
+
+message EnumOnlyProto3 {
+ enum Bool {
+ kFalse = 0;
+ kTrue = 1;
+ }
+}