From dd433ce64f6f35e69c02d6dde1e57023be9187de Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:08:00 +0100 Subject: [PATCH 1/8] pb: Add copy method generation --- .../rpc/protoc/gen/core/CodeGenerator.kt | 2 +- .../kotlinx/rpc/protoc/gen/core/comments.kt | 5 + .../ModelToProtobufKotlinCommonGenerator.kt | 93 +++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/CodeGenerator.kt b/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/CodeGenerator.kt index 6108076a2..0132571fd 100644 --- a/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/CodeGenerator.kt +++ b/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/CodeGenerator.kt @@ -126,7 +126,7 @@ open class CodeGenerator( condition: String, block: (CodeGenerator.() -> Unit), ) { - scope("$condition ->", block = block) + scope("$condition ->", block = block, nlAfterClosed = false) } private fun scopeWithSuffix( diff --git a/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/comments.kt b/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/comments.kt index a016ea546..781b3ec73 100644 --- a/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/comments.kt +++ b/protoc-gen/common/src/main/kotlin/kotlinx/rpc/protoc/gen/core/comments.kt @@ -82,8 +82,13 @@ class Comment( leading.isEmpty() && trailing.isEmpty() } + + companion object { + fun leading(comment: String): Comment = Comment(emptyList(), listOf(comment), emptyList()) + } } + fun Descriptors.FileDescriptor.extractComments(): Map { return toProto().sourceCodeInfo.locationList.associate { val leading = it.leadingComments ?: "" diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index d11d92a23..f1442ac85 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -10,6 +10,7 @@ import com.google.protobuf.ByteString import com.google.protobuf.Descriptors import kotlinx.rpc.protoc.gen.core.AModelToKotlinCommonGenerator import kotlinx.rpc.protoc.gen.core.CodeGenerator +import kotlinx.rpc.protoc.gen.core.Comment import kotlinx.rpc.protoc.gen.core.Config import kotlinx.rpc.protoc.gen.core.INTERNAL_RPC_API_ANNO import kotlinx.rpc.protoc.gen.core.PB_PKG @@ -93,6 +94,12 @@ class ModelToProtobufKotlinCommonGenerator( ) } + function("copy", + args = "body: ${declaration.internalClassFullName()}.() -> Unit = {}", + returnType = declaration.name.safeFullName(), + comment = Comment.leading("Copies the original message, including unknown fields.") + ) + if (declaration.actualFields.isNotEmpty()) { newLine() } @@ -179,6 +186,8 @@ class ModelToProtobufKotlinCommonGenerator( generateOneOfHashCode(declaration) generateEquals(declaration) generateToString(declaration) + generateCopy(declaration) + generateOneOfCopy(declaration) declaration.nestedDeclarations.forEach { nested -> generateInternalMessage(nested) @@ -378,6 +387,88 @@ class ModelToProtobufKotlinCommonGenerator( } } + private fun CodeGenerator.generateCopy(declaration: MessageDeclaration) { + if (!declaration.isUserFacing) { + // e.g., internal map entries don't need a copy() method + return + } + function( + name = "copy", + modifiers = "override", + args = "body: ${declaration.internalClassName()}.() -> Unit", + returnType = declaration.internalClassName(), + ) { + code("val copy = ${declaration.internalClassName()}()") + for (field in declaration.actualFields) { + // write each field to the new copy object + if (field.presenceIdx != null) { + // if the field has presence, we need to check if it was set in the original object. + // if it was set, we copy it to the new object, otherwise we leave it unset. + ifBranch(condition = "presenceMask[${field.presenceIdx}]", ifBlock = { + code("copy.${field.name} = ${field.type.copyCall(field.name)}") + }) + } else { + // by default, we copy the field value + code("copy.${field.name} = ${field.type.copyCall(field.name)}") + } + } + code("copy.apply(body)") + code("return copy") + } + } + + private fun FieldType.copyCall(varName: String): String { + return when (this) { + is FieldType.IntegralType -> varName + is FieldType.Enum -> varName + is FieldType.List -> "$varName.map { ${value.copyCall("it")} }" + is FieldType.Map -> "$varName.mapValues { ${entry.value.copyCall("it.value")} }" + is FieldType.Message -> "$varName.copy()" + is FieldType.OneOf -> "$varName?.oneOfCopy()" + } + } + + private fun CodeGenerator.generateOneOfCopy(declaration: MessageDeclaration) { + declaration.oneOfDeclarations.forEach { oneOf -> + val oneOfFullName = oneOf.name.safeFullName() + function( + name = "oneOfCopy", + returnType = oneOfFullName, + contextReceiver = oneOfFullName, + ) { + // check if the type is copy by value (no need for deep copy) + val copyByValue = { type: FieldType -> type is FieldType.IntegralType || type is FieldType.Enum } + + // if all variants are integral or enum types, we can just return this directly. + val fastPath = oneOf.variants.all { copyByValue(it.type) } + if (fastPath) { + code("return this") + } else { + // dispatch on all possible variants and copy its value + whenBlock( + prefix = "return", + condition = "this" + ) { + oneOf.variants.forEach { variant -> + val variantName = "$oneOfFullName.${variant.name}" + whenCase("is $variantName") { + if (copyByValue(variant.type)) { + // no need to reconstruct a new object, we can just return this + code("this") + } else { + code("$variantName(${variant.type.copyCall("this.value")})") + } + } + } + } + } + + } + } + } + + + private fun CodeGenerator.generatePresenceIndicesObject(declaration: MessageDeclaration) { if (declaration.presenceMaskSize == 0) { return @@ -1191,6 +1282,8 @@ class ModelToProtobufKotlinCommonGenerator( additionalPublicImports.add("kotlin.jvm.JvmInline") } + + } } From 0416a9c727d40766fc36ea7c8d515e7dfb1497f9 Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:08:08 +0100 Subject: [PATCH 2/8] pb: Add copy tests --- .../kotlinx/rpc/protobuf/test/CopyTest.kt | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt diff --git a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt new file mode 100644 index 000000000..5dc0ecdd1 --- /dev/null +++ b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt @@ -0,0 +1,161 @@ +/* + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +package kotlinx.rpc.protobuf.test + +import invoke +import kotlinx.rpc.protobuf.test.invoke +import test.submsg.Other +import test.submsg.invoke +import kotlin.collections.iterator +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class CopyTest { + + @Test + fun `test list copy - should be real copy`() { + val userList = mutableListOf(1,2,3) + val original = Repeated { + listInt32 = userList + } + val copy = original.copy() + userList.add(4) + + assertEquals(listOf(1,2,3,4), original.listInt32) + assertEquals(listOf(1,2,3), copy.listInt32) + } + + @Test + fun `copy primitives and bytes - equality and independence`() { + val bytesSrc = byteArrayOf(1, 2, 3) + val msg = AllPrimitives { + int32 = 42 + int64 = 123L + uint32 = 7u + uint64 = 9uL + sint32 = -5 + sint64 = -7L + fixed32 = 11u + fixed64 = 13uL + sfixed32 = -17 + sfixed64 = -19L + bool = true + float = 2.5f + double = 3.5 + string = "hello" + bytes = bytesSrc + } + + val copy = msg.copy() + + // verify all fields are copied + assertEquals(msg, copy) + + // bytes are copied + assertEquals(byteArrayOf(1, 2, 3).toList(), msg.bytes?.toList()) + assertEquals(byteArrayOf(1, 2, 3).toList(), copy.bytes?.toList()) + } + + @Test + fun `copy repeated messages - deep copy of list and elements`() { + val orig = Repeated { + listMessage = listOf( + Repeated.Other { a = 1 }, + Repeated.Other { a = 2 } + ) + } + val cp = orig.copy() + + // Lists are distinct instances + assertTrue(orig.listMessage !== cp.listMessage) + // Elements are deep-copied + for (i in orig.listMessage.indices) { + assertEquals(orig.listMessage[i].a, cp.listMessage[i].a) + assertTrue(orig.listMessage[i] !== cp.listMessage[i]) + } + + // Modify copy via copy { } and ensure original unaffected + val mutated = orig.copy { + listMessage = listMessage + Repeated.Other { a = 3 } + } + assertEquals(listOf(1, 2), orig.listMessage.map { it.a }) + assertEquals(listOf(1, 2, 3), mutated.listMessage.map { it.a }) + } + + @Test + fun `copy maps - deep copy keys and values`() { + val original = TestMap { + primitives = mapOf("a" to 10L, "b" to 20L) + messages = mapOf(1 to PresenceCheck { RequiredPresence = 1 }, 2 to PresenceCheck { RequiredPresence = 2 }) + } + + val copy = original.copy() + + // verify maps are copied + assertEquals(mapOf("a" to 10L, "b" to 20L), original.primitives) + assertEquals(mapOf("a" to 10L, "b" to 20L), copy.primitives) + + // deep copy for message map values + for ((k, v) in original.messages) { + val cv = copy.messages.getValue(k) + assertEquals(v.RequiredPresence, cv.RequiredPresence) + assertTrue(v !== cv) + } + + // copy { } change and ensure isolation + val mutated = original.copy { primitives = primitives + ("z" to 90L) } + assertEquals(setOf("a","b"), original.primitives.keys) + assertEquals(setOf("a","b","z"), mutated.primitives.keys) + } + + @Test + fun `copy oneof - preserve active case and allow mutation in lambda`() { + val o1 = OneOfMsg.Companion { field = OneOfMsg.Field.Sint(7) } + val c1 = o1.copy() + assertEquals(o1.field, c1.field) + + // mutate with copy-lambda (switch case) + val c2 = o1.copy { field = OneOfMsg.Field.Other(Other.Companion { arg1 = "x" }) } + // original unaffected + assertEquals(OneOfMsg.Field.Sint(7), o1.field) + // new case set + assertTrue(c2.field is OneOfMsg.Field.Other) + } + + @Test + fun `copy nested sub-message - deep copy and lambda modification`() { + val equals = Equals.Companion { + str1 = "root" + bytes1 = byteArrayOf(1, 2, 3) + someEnum2 = Equals.SomeEnum.VALUE1 + nested = Equals.Nested { content = "leaf" } + } + val copy = equals.copy() + // deep copy of nested + assertTrue(equals.nested !== copy.nested) + assertEquals(equals.nested.content, copy.nested.content) + + // modify nested in copy-lambda + val mutated = equals.copy { + nested = Equals.Nested { content = "mut" } + } + assertEquals("leaf", equals.nested.content) + assertEquals("mut", mutated.nested.content) + } + + @Test + fun `copy preserves presence and required fields`() { + val p = PresenceCheck { RequiredPresence = 1 } + val cp = p.copy() + assertEquals(1, cp.RequiredPresence) + assertNull(cp.OptionalPresence) + + val cp2 = p.copy { OptionalPresence = 5f } + assertEquals(1, cp2.RequiredPresence) + assertEquals(5f, cp2.OptionalPresence) + } +} \ No newline at end of file From dcb929f3d08addfdf0ab1536922845f40f756603 Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:22:25 +0100 Subject: [PATCH 3/8] pb: Fix equals condition for bytes --- .../rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index f1442ac85..7081e4d38 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -318,7 +318,7 @@ class ModelToProtobufKotlinCommonGenerator( is FieldType.IntegralType -> { if (t == FieldType.IntegralType.BYTES) { if (field.nullable) { - addLine("if ($presenceCheck((${field.name} != null && (other.${field.name} == null || !${field.name}!!.contentEquals(other.${field.name}!!))) || other.${field.name} != null)) return false") + addLine("if ($presenceCheck((${field.name} != null && (other.${field.name} == null || !${field.name}!!.contentEquals(other.${field.name}!!))) || ${field.name} == null)) return false") } else { addLine("if ($presenceCheck!${field.name}.contentEquals(other.${field.name})) return false") } From a4fa19cc44b88117b4d9824785c9be6af9828e9b Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:38:06 +0100 Subject: [PATCH 4/8] pb: Fix bytes copy --- .../kotlinx/rpc/protobuf/test/CopyTest.kt | 144 ++++++++++++++++-- .../ModelToProtobufKotlinCommonGenerator.kt | 16 +- 2 files changed, 140 insertions(+), 20 deletions(-) diff --git a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt index 5dc0ecdd1..cd12708fc 100644 --- a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt +++ b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt @@ -5,7 +5,6 @@ package kotlinx.rpc.protobuf.test import invoke -import kotlinx.rpc.protobuf.test.invoke import test.submsg.Other import test.submsg.invoke import kotlin.collections.iterator @@ -16,19 +15,6 @@ import kotlin.test.assertTrue class CopyTest { - @Test - fun `test list copy - should be real copy`() { - val userList = mutableListOf(1,2,3) - val original = Repeated { - listInt32 = userList - } - val copy = original.copy() - userList.add(4) - - assertEquals(listOf(1,2,3,4), original.listInt32) - assertEquals(listOf(1,2,3), copy.listInt32) - } - @Test fun `copy primitives and bytes - equality and independence`() { val bytesSrc = byteArrayOf(1, 2, 3) @@ -70,6 +56,8 @@ class CopyTest { } val cp = orig.copy() + assertEquals(orig, cp) + // Lists are distinct instances assertTrue(orig.listMessage !== cp.listMessage) // Elements are deep-copied @@ -158,4 +146,132 @@ class CopyTest { assertEquals(1, cp2.RequiredPresence) assertEquals(5f, cp2.OptionalPresence) } + + @Test + fun `copy with user-provided mutable map - mutation after copy should not affect copy`() { + val userMap = mutableMapOf("a" to 10L, "b" to 20L) + val original = TestMap { + primitives = userMap + } + + val copy = original.copy() + + // Mutate user's map after copy - should not affect copy + userMap["c"] = 30L + userMap["a"] = 999L + + assertEquals(mapOf("a" to 10L, "b" to 20L, "c" to 30L, "a" to 999L), original.primitives) + assertEquals(mapOf("a" to 10L, "b" to 20L), copy.primitives) + } + + @Test + fun `copy with user-provided bytes - mutation after copy should not affect copy`() { + val userBytes = byteArrayOf(1, 2, 3) + val original = AllPrimitives { + bytes = userBytes + } + val copy = original.copy() + userBytes[0] = 99 + assertEquals(listOf(99, 2, 3), original.bytes?.toList()) + assertEquals(listOf(1, 2, 3), copy.bytes?.toList()) + } + + @Test + fun `copy with nested messages - user mutation after copy should not affect copy`() { + val userMessages = mutableMapOf( + 1 to PresenceCheck { RequiredPresence = 1 }, + 2 to PresenceCheck { RequiredPresence = 2 } + ) + val original = TestMap { + messages = userMessages + } + + val copy = original.copy() + + // Mutate user's map after copy + userMessages[3] = PresenceCheck { RequiredPresence = 3 } + + // Original has all 3, copy should only have original 2 + assertEquals(3, original.messages.size) + assertEquals(2, copy.messages.size) + assertEquals(setOf(1, 2, 3), original.messages.keys) + assertEquals(setOf(1, 2), copy.messages.keys) + } + + @Test + fun `copy with bytes - mutating source array after construction should not affect copy`() { + val bytesSrc = byteArrayOf(1, 2, 3) + val msg = AllPrimitives { + bytes = bytesSrc + } + + val copy = msg.copy() + + // Mutate source array after message creation + bytesSrc[0] = 99 + bytesSrc[1] = 88 + + // Neither original nor copy should be affected + assertEquals(listOf(99, 88, 3), msg.bytes?.toList()) + assertEquals(listOf(1, 2, 3), copy.bytes?.toList()) + } + + @Test + fun `copy with empty collections`() { + val msg = Repeated { + listInt32 = emptyList() + listMessage = emptyList() + } + + val copy = msg.copy() + + assertTrue(copy.listInt32.isEmpty()) + assertTrue(copy.listMessage.isEmpty()) + + // Verify they are distinct instances + assertTrue(msg.listInt32 !== copy.listInt32) + assertTrue(msg.listMessage !== copy.listMessage) + } + + @Test + fun `copy with nested message in list - mutations after copy don't affect copy`() { + val nestedList = mutableListOf( + Repeated.Other { a = 1 }, + Repeated.Other { a = 2 } + ) + val original = Repeated { + listMessage = nestedList + } + + val copy = original.copy() + + // Mutate the user's list after copy + nestedList.add(Repeated.Other { a = 3 }) + + assertEquals(3, original.listMessage.size) + assertEquals(2, copy.listMessage.size) + assertEquals(listOf(1, 2, 3), original.listMessage.map { it.a }) + assertEquals(listOf(1, 2), copy.listMessage.map { it.a }) + } + + @Test + fun `copy lambda modifications don't affect original`() { + val original = AllPrimitives { + int32 = 10 + string = "original" + } + + val modified = original.copy { + int32 = 20 + string = "modified" + } + + // Original should remain unchanged + assertEquals(10, original.int32) + assertEquals("original", original.string) + + // Modified should have new values + assertEquals(20, modified.int32) + assertEquals("modified", modified.string) + } } \ No newline at end of file diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index 7081e4d38..fa6283ba6 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -405,11 +405,11 @@ class ModelToProtobufKotlinCommonGenerator( // if the field has presence, we need to check if it was set in the original object. // if it was set, we copy it to the new object, otherwise we leave it unset. ifBranch(condition = "presenceMask[${field.presenceIdx}]", ifBlock = { - code("copy.${field.name} = ${field.type.copyCall(field.name)}") + code("copy.${field.name} = ${field.type.copyCall(field.name, field.nullable)}") }) } else { // by default, we copy the field value - code("copy.${field.name} = ${field.type.copyCall(field.name)}") + code("copy.${field.name} = ${field.type.copyCall(field.name, field.nullable)}") } } code("copy.apply(body)") @@ -417,12 +417,16 @@ class ModelToProtobufKotlinCommonGenerator( } } - private fun FieldType.copyCall(varName: String): String { + private fun FieldType.copyCall(varName: String, nullable: Boolean): String { return when (this) { + FieldType.IntegralType.BYTES -> { + val optionalPrefix = if (nullable) "?" else "" + "$varName$optionalPrefix.copyOf()" + } is FieldType.IntegralType -> varName is FieldType.Enum -> varName - is FieldType.List -> "$varName.map { ${value.copyCall("it")} }" - is FieldType.Map -> "$varName.mapValues { ${entry.value.copyCall("it.value")} }" + is FieldType.List -> "$varName.map { ${value.copyCall("it", false)} }" + is FieldType.Map -> "$varName.mapValues { ${entry.value.copyCall("it.value", false)} }" is FieldType.Message -> "$varName.copy()" is FieldType.OneOf -> "$varName?.oneOfCopy()" } @@ -456,7 +460,7 @@ class ModelToProtobufKotlinCommonGenerator( // no need to reconstruct a new object, we can just return this code("this") } else { - code("$variantName(${variant.type.copyCall("this.value")})") + code("$variantName(${variant.type.copyCall("this.value", false)})") } } } From 2ff435993990f5ebb16d2b44c944f26c4471ba00 Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:38:23 +0100 Subject: [PATCH 5/8] pb: Update generated default protos --- .../com/google/protobuf/kotlin/Any.kt | 5 + .../com/google/protobuf/kotlin/Api.kt | 15 +++ .../com/google/protobuf/kotlin/Duration.kt | 5 + .../com/google/protobuf/kotlin/Empty.kt | 5 + .../com/google/protobuf/kotlin/FieldMask.kt | 5 + .../google/protobuf/kotlin/SourceContext.kt | 5 + .../com/google/protobuf/kotlin/Struct.kt | 15 +++ .../com/google/protobuf/kotlin/Timestamp.kt | 5 + .../com/google/protobuf/kotlin/Type.kt | 25 ++++ .../com/google/protobuf/kotlin/Wrappers.kt | 45 +++++++ .../protobuf/kotlin/_rpc_internal/Any.kt | 10 +- .../protobuf/kotlin/_rpc_internal/Api.kt | 53 +++++--- .../protobuf/kotlin/_rpc_internal/Duration.kt | 10 +- .../protobuf/kotlin/_rpc_internal/Empty.kt | 6 + .../kotlin/_rpc_internal/FieldMask.kt | 8 +- .../kotlin/_rpc_internal/SourceContext.kt | 8 +- .../protobuf/kotlin/_rpc_internal/Struct.kt | 66 ++++++---- .../kotlin/_rpc_internal/Timestamp.kt | 10 +- .../protobuf/kotlin/_rpc_internal/Type.kt | 121 ++++++++++-------- .../protobuf/kotlin/_rpc_internal/Wrappers.kt | 72 +++++++++-- .../ModelToProtobufKotlinCommonGenerator.kt | 2 - 21 files changed, 385 insertions(+), 111 deletions(-) diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt index 8aed599fa..10f256950 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt @@ -128,5 +128,10 @@ public interface Any { */ public val value: ByteArray + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.AnyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Any + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt index 68ea99595..1c473599d 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt @@ -65,6 +65,11 @@ public interface Api { */ public val syntax: com.google.protobuf.kotlin.Syntax + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.ApiInternal.() -> Unit = {}): com.google.protobuf.kotlin.Api + public companion object } @@ -102,6 +107,11 @@ public interface Method { */ public val syntax: com.google.protobuf.kotlin.Syntax + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.MethodInternal.() -> Unit = {}): com.google.protobuf.kotlin.Method + public companion object } @@ -197,5 +207,10 @@ public interface Mixin { */ public val root: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.MixinInternal.() -> Unit = {}): com.google.protobuf.kotlin.Mixin + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt index b5fd74ea8..1fa3b8b49 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt @@ -81,5 +81,10 @@ public interface Duration { */ public val nanos: Int + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.DurationInternal.() -> Unit = {}): com.google.protobuf.kotlin.Duration + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt index 0ea1dfafa..219e694ba 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt @@ -14,5 +14,10 @@ import kotlinx.rpc.internal.utils.* */ @kotlinx.rpc.grpc.codec.WithCodec(com.google.protobuf.kotlin.EmptyInternal.CODEC::class) public interface Empty { + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Empty + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt index 4b50a3707..8a3a4fea6 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt @@ -211,5 +211,10 @@ public interface FieldMask { */ public val paths: List + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.FieldMaskInternal.() -> Unit = {}): com.google.protobuf.kotlin.FieldMask + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt index 6756c3269..c3f9b54d4 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt @@ -15,5 +15,10 @@ public interface SourceContext { */ public val fileName: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.SourceContextInternal.() -> Unit = {}): com.google.protobuf.kotlin.SourceContext + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt index 5dc863986..375d0dc30 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt @@ -21,6 +21,11 @@ public interface Struct { */ public val fields: Map + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.StructInternal.() -> Unit = {}): com.google.protobuf.kotlin.Struct + public companion object } @@ -39,6 +44,11 @@ public interface Value { */ public val kind: com.google.protobuf.kotlin.Value.Kind? + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Value + /** * The kind of value. */ @@ -101,6 +111,11 @@ public interface ListValue { */ public val values: List + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.ListValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.ListValue + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt index ea8d32b7f..151a73171 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt @@ -110,5 +110,10 @@ public interface Timestamp { */ public val nanos: Int + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.TimestampInternal.() -> Unit = {}): com.google.protobuf.kotlin.Timestamp + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt index 1a2836671..23bc7acfc 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt @@ -37,6 +37,11 @@ public interface Type { */ public val edition: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.TypeInternal.() -> Unit = {}): com.google.protobuf.kotlin.Type + public companion object } @@ -88,6 +93,11 @@ public interface Field { */ public val defaultValue: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.FieldInternal.() -> Unit = {}): com.google.protobuf.kotlin.Field + /** * Basic field types. */ @@ -258,6 +268,11 @@ public interface Enum { */ public val edition: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.EnumInternal.() -> Unit = {}): com.google.protobuf.kotlin.Enum + public companion object } @@ -279,6 +294,11 @@ public interface EnumValue { */ public val options: List + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.EnumValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.EnumValue + public companion object } @@ -303,6 +323,11 @@ public interface Option { */ public val value: com.google.protobuf.kotlin.Any + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.OptionInternal.() -> Unit = {}): com.google.protobuf.kotlin.Option + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt index da349669f..81be10db4 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt @@ -18,6 +18,11 @@ public interface DoubleValue { */ public val value: Double + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.DoubleValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.DoubleValue + public companion object } @@ -36,6 +41,11 @@ public interface FloatValue { */ public val value: Float + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.FloatValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.FloatValue + public companion object } @@ -54,6 +64,11 @@ public interface Int64Value { */ public val value: Long + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.Int64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int64Value + public companion object } @@ -72,6 +87,11 @@ public interface UInt64Value { */ public val value: ULong + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.UInt64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt64Value + public companion object } @@ -90,6 +110,11 @@ public interface Int32Value { */ public val value: Int + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.Int32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int32Value + public companion object } @@ -108,6 +133,11 @@ public interface UInt32Value { */ public val value: UInt + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.UInt32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt32Value + public companion object } @@ -126,6 +156,11 @@ public interface BoolValue { */ public val value: Boolean + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.BoolValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BoolValue + public companion object } @@ -144,6 +179,11 @@ public interface StringValue { */ public val value: String + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.StringValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.StringValue + public companion object } @@ -162,5 +202,10 @@ public interface BytesValue { */ public val value: ByteArray + /** + * Copies the original message, including unknown fields. + */ + public fun copy(body: com.google.protobuf.kotlin.BytesValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BytesValue + public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt index 2b77f2fd1..24bb041bf 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt @@ -46,6 +46,14 @@ public class AnyInternal: com.google.protobuf.kotlin.Any, kotlinx.rpc.protobuf.i } } + public override fun copy(body: AnyInternal.() -> Unit): AnyInternal { + val copy = AnyInternal() + copy.typeUrl = typeUrl + copy.value = value.copyOf() + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Any): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -104,11 +112,9 @@ public fun com.google.protobuf.kotlin.AnyInternal.Companion.decodeWith(msg: com. tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.typeUrl = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.value = decoder.readBytes() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt index be631134b..0f7b25ca0 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt @@ -76,6 +76,22 @@ public class ApiInternal: com.google.protobuf.kotlin.Api, kotlinx.rpc.protobuf.i } } + public override fun copy(body: ApiInternal.() -> Unit): ApiInternal { + val copy = ApiInternal() + copy.name = name + copy.methods = methods.map { it.copy() } + copy.options = options.map { it.copy() } + copy.version = version + if (presenceMask[0]) { + copy.sourceContext = sourceContext.copy() + } + + copy.mixins = mixins.map { it.copy() } + copy.syntax = syntax + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Api): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -165,6 +181,19 @@ public class MethodInternal: com.google.protobuf.kotlin.Method, kotlinx.rpc.prot } } + public override fun copy(body: MethodInternal.() -> Unit): MethodInternal { + val copy = MethodInternal() + copy.name = name + copy.requestTypeUrl = requestTypeUrl + copy.requestStreaming = requestStreaming + copy.responseTypeUrl = responseTypeUrl + copy.responseStreaming = responseStreaming + copy.options = options.map { it.copy() } + copy.syntax = syntax + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Method): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -234,6 +263,14 @@ public class MixinInternal: com.google.protobuf.kotlin.Mixin, kotlinx.rpc.protob } } + public override fun copy(body: MixinInternal.() -> Unit): MixinInternal { + val copy = MixinInternal() + copy.name = name + copy.root = root + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Mixin): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -345,23 +382,19 @@ public fun com.google.protobuf.kotlin.ApiInternal.Companion.decodeWith(msg: com. tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.MethodInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.MethodInternal::decodeWith) (msg.methods as MutableList).add(elem) } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.version = decoder.readString() } - tag.fieldNr == 5 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { if (!msg.presenceMask[0]) { msg.sourceContext = com.google.protobuf.kotlin.SourceContextInternal() @@ -369,17 +402,14 @@ public fun com.google.protobuf.kotlin.ApiInternal.Companion.decodeWith(msg: com. decoder.readMessage(msg.sourceContext.asInternal(), com.google.protobuf.kotlin.SourceContextInternal::decodeWith) } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.MixinInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.MixinInternal::decodeWith) (msg.mixins as MutableList).add(elem) } - tag.fieldNr == 7 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.syntax = com.google.protobuf.kotlin.Syntax.fromNumber(decoder.readEnum()) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -479,33 +509,26 @@ public fun com.google.protobuf.kotlin.MethodInternal.Companion.decodeWith(msg: c tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.requestTypeUrl = decoder.readString() } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.requestStreaming = decoder.readBool() } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.responseTypeUrl = decoder.readString() } - tag.fieldNr == 5 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.responseStreaming = decoder.readBool() } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - tag.fieldNr == 7 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.syntax = com.google.protobuf.kotlin.Syntax.fromNumber(decoder.readEnum()) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -580,11 +603,9 @@ public fun com.google.protobuf.kotlin.MixinInternal.Companion.decodeWith(msg: co tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.root = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt index 4c3a44868..919292332 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt @@ -46,6 +46,14 @@ public class DurationInternal: com.google.protobuf.kotlin.Duration, kotlinx.rpc. } } + public override fun copy(body: DurationInternal.() -> Unit): DurationInternal { + val copy = DurationInternal() + copy.seconds = seconds + copy.nanos = nanos + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Duration): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -104,11 +112,9 @@ public fun com.google.protobuf.kotlin.DurationInternal.Companion.decodeWith(msg: tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.seconds = decoder.readInt64() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.nanos = decoder.readInt32() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt index cbe8ce7d6..51f0aaa81 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt @@ -37,6 +37,12 @@ public class EmptyInternal: com.google.protobuf.kotlin.Empty, kotlinx.rpc.protob } } + public override fun copy(body: EmptyInternal.() -> Unit): EmptyInternal { + val copy = EmptyInternal() + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Empty): kotlinx.rpc.protobuf.input.stream.InputStream { diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt index 0b009c190..3eb7622c2 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt @@ -41,6 +41,13 @@ public class FieldMaskInternal: com.google.protobuf.kotlin.FieldMask, kotlinx.rp } } + public override fun copy(body: FieldMaskInternal.() -> Unit): FieldMaskInternal { + val copy = FieldMaskInternal() + copy.paths = paths.map { it } + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.FieldMask): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -98,7 +105,6 @@ public fun com.google.protobuf.kotlin.FieldMaskInternal.Companion.decodeWith(msg val elem = decoder.readString() (msg.paths as MutableList).add(elem) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt index a321f0e25..8f81cef27 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt @@ -41,6 +41,13 @@ public class SourceContextInternal: com.google.protobuf.kotlin.SourceContext, ko } } + public override fun copy(body: SourceContextInternal.() -> Unit): SourceContextInternal { + val copy = SourceContextInternal() + copy.fileName = fileName + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.SourceContext): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -95,7 +102,6 @@ public fun com.google.protobuf.kotlin.SourceContextInternal.Companion.decodeWith tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.fileName = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt index 41b0c2809..c6309f0e3 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt @@ -41,6 +41,13 @@ public class StructInternal: com.google.protobuf.kotlin.Struct, kotlinx.rpc.prot } } + public override fun copy(body: StructInternal.() -> Unit): StructInternal { + val copy = StructInternal() + copy.fields = fields.mapValues { it.value.copy() } + copy.apply(body) + return copy + } + public class FieldsEntryInternal: kotlinx.rpc.protobuf.internal.InternalMessage(fieldsWithPresence = 1) { private object PresenceIndices { public const val value: Int = 0 @@ -173,6 +180,36 @@ public class ValueInternal: com.google.protobuf.kotlin.Value, kotlinx.rpc.protob } } + public override fun copy(body: ValueInternal.() -> Unit): ValueInternal { + val copy = ValueInternal() + copy.kind = kind?.oneOfCopy() + copy.apply(body) + return copy + } + + public fun com.google.protobuf.kotlin.Value.Kind.oneOfCopy(): com.google.protobuf.kotlin.Value.Kind { + return when (this) { + is com.google.protobuf.kotlin.Value.Kind.NullValue -> { + this + } + is com.google.protobuf.kotlin.Value.Kind.NumberValue -> { + this + } + is com.google.protobuf.kotlin.Value.Kind.StringValue -> { + this + } + is com.google.protobuf.kotlin.Value.Kind.BoolValue -> { + this + } + is com.google.protobuf.kotlin.Value.Kind.StructValue -> { + com.google.protobuf.kotlin.Value.Kind.StructValue(this.value.copy()) + } + is com.google.protobuf.kotlin.Value.Kind.ListValue -> { + com.google.protobuf.kotlin.Value.Kind.ListValue(this.value.copy()) + } + } + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Value): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -237,6 +274,13 @@ public class ListValueInternal: com.google.protobuf.kotlin.ListValue, kotlinx.rp } } + public override fun copy(body: ListValueInternal.() -> Unit): ListValueInternal { + val copy = ListValueInternal() + copy.values = values.map { it.copy() } + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.ListValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -317,7 +361,6 @@ public fun com.google.protobuf.kotlin.StructInternal.Companion.decodeWith(msg: c (msg.fields as MutableMap)[key] = value } } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -358,7 +401,6 @@ public fun com.google.protobuf.kotlin.ValueInternal.checkRequiredFields() { it is com.google.protobuf.kotlin.Value.Kind.StructValue -> { it.value.asInternal().checkRequiredFields() } - it is com.google.protobuf.kotlin.Value.Kind.ListValue -> { it.value.asInternal().checkRequiredFields() } @@ -373,23 +415,18 @@ public fun com.google.protobuf.kotlin.ValueInternal.encodeWith(encoder: kotlinx. is com.google.protobuf.kotlin.Value.Kind.NullValue -> { encoder.writeEnum(fieldNr = 1, value = value.value.number) } - is com.google.protobuf.kotlin.Value.Kind.NumberValue -> { encoder.writeDouble(fieldNr = 2, value = value.value) } - is com.google.protobuf.kotlin.Value.Kind.StringValue -> { encoder.writeString(fieldNr = 3, value = value.value) } - is com.google.protobuf.kotlin.Value.Kind.BoolValue -> { encoder.writeBool(fieldNr = 4, value = value.value) } - is com.google.protobuf.kotlin.Value.Kind.StructValue -> { encoder.writeMessage(fieldNr = 5, value = value.value.asInternal()) { encodeWith(it) } } - is com.google.protobuf.kotlin.Value.Kind.ListValue -> { encoder.writeMessage(fieldNr = 6, value = value.value.asInternal()) { encodeWith(it) } } @@ -405,19 +442,15 @@ public fun com.google.protobuf.kotlin.ValueInternal.Companion.decodeWith(msg: co tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.kind = com.google.protobuf.kotlin.Value.Kind.NullValue(com.google.protobuf.kotlin.NullValue.fromNumber(decoder.readEnum())) } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.FIXED64 -> { msg.kind = com.google.protobuf.kotlin.Value.Kind.NumberValue(decoder.readDouble()) } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.kind = com.google.protobuf.kotlin.Value.Kind.StringValue(decoder.readString()) } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.kind = com.google.protobuf.kotlin.Value.Kind.BoolValue(decoder.readBool()) } - tag.fieldNr == 5 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val field = (msg.kind as? com.google.protobuf.kotlin.Value.Kind.StructValue) ?: com.google.protobuf.kotlin.Value.Kind.StructValue(com.google.protobuf.kotlin.StructInternal()).also { msg.kind = it @@ -425,7 +458,6 @@ public fun com.google.protobuf.kotlin.ValueInternal.Companion.decodeWith(msg: co decoder.readMessage(field.value.asInternal(), com.google.protobuf.kotlin.StructInternal::decodeWith) } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val field = (msg.kind as? com.google.protobuf.kotlin.Value.Kind.ListValue) ?: com.google.protobuf.kotlin.Value.Kind.ListValue(com.google.protobuf.kotlin.ListValueInternal()).also { msg.kind = it @@ -433,7 +465,6 @@ public fun com.google.protobuf.kotlin.ValueInternal.Companion.decodeWith(msg: co decoder.readMessage(field.value.asInternal(), com.google.protobuf.kotlin.ListValueInternal::decodeWith) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -453,23 +484,18 @@ private fun com.google.protobuf.kotlin.ValueInternal.computeSize(): Int { is com.google.protobuf.kotlin.Value.Kind.NullValue -> { __result += (kotlinx.rpc.protobuf.internal.WireSize.tag(1, kotlinx.rpc.protobuf.internal.WireType.VARINT) + kotlinx.rpc.protobuf.internal.WireSize.enum(value.value.number)) } - is com.google.protobuf.kotlin.Value.Kind.NumberValue -> { __result += (kotlinx.rpc.protobuf.internal.WireSize.tag(2, kotlinx.rpc.protobuf.internal.WireType.FIXED64) + kotlinx.rpc.protobuf.internal.WireSize.double(value.value)) } - is com.google.protobuf.kotlin.Value.Kind.StringValue -> { __result += kotlinx.rpc.protobuf.internal.WireSize.string(value.value).let { kotlinx.rpc.protobuf.internal.WireSize.tag(3, kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED) + kotlinx.rpc.protobuf.internal.WireSize.int32(it) + it } } - is com.google.protobuf.kotlin.Value.Kind.BoolValue -> { __result += (kotlinx.rpc.protobuf.internal.WireSize.tag(4, kotlinx.rpc.protobuf.internal.WireType.VARINT) + kotlinx.rpc.protobuf.internal.WireSize.bool(value.value)) } - is com.google.protobuf.kotlin.Value.Kind.StructValue -> { __result += value.value.asInternal()._size.let { kotlinx.rpc.protobuf.internal.WireSize.tag(5, kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED) + kotlinx.rpc.protobuf.internal.WireSize.int32(it) + it } } - is com.google.protobuf.kotlin.Value.Kind.ListValue -> { __result += value.value.asInternal()._size.let { kotlinx.rpc.protobuf.internal.WireSize.tag(6, kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED) + kotlinx.rpc.protobuf.internal.WireSize.int32(it) + it } } @@ -511,7 +537,6 @@ public fun com.google.protobuf.kotlin.ListValueInternal.Companion.decodeWith(msg decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.ValueInternal::decodeWith) (msg.values as MutableList).add(elem) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -565,7 +590,6 @@ public fun com.google.protobuf.kotlin.StructInternal.FieldsEntryInternal.Compani tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.key = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { if (!msg.presenceMask[0]) { msg.value = com.google.protobuf.kotlin.ValueInternal() @@ -573,7 +597,6 @@ public fun com.google.protobuf.kotlin.StructInternal.FieldsEntryInternal.Compani decoder.readMessage(msg.value.asInternal(), com.google.protobuf.kotlin.ValueInternal::decodeWith) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -610,7 +633,6 @@ public fun com.google.protobuf.kotlin.NullValue.Companion.fromNumber(number: Int 0 -> { com.google.protobuf.kotlin.NullValue.NULL_VALUE } - else -> { com.google.protobuf.kotlin.NullValue.UNRECOGNIZED(number) } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt index b54a46c5b..35fbddbd3 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt @@ -46,6 +46,14 @@ public class TimestampInternal: com.google.protobuf.kotlin.Timestamp, kotlinx.rp } } + public override fun copy(body: TimestampInternal.() -> Unit): TimestampInternal { + val copy = TimestampInternal() + copy.seconds = seconds + copy.nanos = nanos + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Timestamp): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -104,11 +112,9 @@ public fun com.google.protobuf.kotlin.TimestampInternal.Companion.decodeWith(msg tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.seconds = decoder.readInt64() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.nanos = decoder.readInt32() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt index acd3f69e6..fe475b6c1 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt @@ -76,6 +76,22 @@ public class TypeInternal: com.google.protobuf.kotlin.Type, kotlinx.rpc.protobuf } } + public override fun copy(body: TypeInternal.() -> Unit): TypeInternal { + val copy = TypeInternal() + copy.name = name + copy.fields = fields.map { it.copy() } + copy.oneofs = oneofs.map { it } + copy.options = options.map { it.copy() } + if (presenceMask[0]) { + copy.sourceContext = sourceContext.copy() + } + + copy.syntax = syntax + copy.edition = edition + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Type): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -177,6 +193,22 @@ public class FieldInternal: com.google.protobuf.kotlin.Field, kotlinx.rpc.protob } } + public override fun copy(body: FieldInternal.() -> Unit): FieldInternal { + val copy = FieldInternal() + copy.kind = kind + copy.cardinality = cardinality + copy.number = number + copy.name = name + copy.typeUrl = typeUrl + copy.oneofIndex = oneofIndex + copy.packed = packed + copy.options = options.map { it.copy() } + copy.jsonName = jsonName + copy.defaultValue = defaultValue + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Field): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -272,6 +304,21 @@ public class EnumInternal: com.google.protobuf.kotlin.Enum, kotlinx.rpc.protobuf } } + public override fun copy(body: EnumInternal.() -> Unit): EnumInternal { + val copy = EnumInternal() + copy.name = name + copy.enumvalue = enumvalue.map { it.copy() } + copy.options = options.map { it.copy() } + if (presenceMask[0]) { + copy.sourceContext = sourceContext.copy() + } + + copy.syntax = syntax + copy.edition = edition + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Enum): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -345,6 +392,15 @@ public class EnumValueInternal: com.google.protobuf.kotlin.EnumValue, kotlinx.rp } } + public override fun copy(body: EnumValueInternal.() -> Unit): EnumValueInternal { + val copy = EnumValueInternal() + copy.name = name + copy.number = number + copy.options = options.map { it.copy() } + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.EnumValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -424,6 +480,17 @@ public class OptionInternal: com.google.protobuf.kotlin.Option, kotlinx.rpc.prot } } + public override fun copy(body: OptionInternal.() -> Unit): OptionInternal { + val copy = OptionInternal() + copy.name = name + if (presenceMask[0]) { + copy.value = value.copy() + } + + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Option): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -543,24 +610,20 @@ public fun com.google.protobuf.kotlin.TypeInternal.Companion.decodeWith(msg: com tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.FieldInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.FieldInternal::decodeWith) (msg.fields as MutableList).add(elem) } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = decoder.readString() (msg.oneofs as MutableList).add(elem) } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - tag.fieldNr == 5 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { if (!msg.presenceMask[0]) { msg.sourceContext = com.google.protobuf.kotlin.SourceContextInternal() @@ -568,15 +631,12 @@ public fun com.google.protobuf.kotlin.TypeInternal.Companion.decodeWith(msg: com decoder.readMessage(msg.sourceContext.asInternal(), com.google.protobuf.kotlin.SourceContextInternal::decodeWith) } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.syntax = com.google.protobuf.kotlin.Syntax.fromNumber(decoder.readEnum()) } - tag.fieldNr == 7 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.edition = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -688,45 +748,35 @@ public fun com.google.protobuf.kotlin.FieldInternal.Companion.decodeWith(msg: co tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.kind = com.google.protobuf.kotlin.Field.Kind.fromNumber(decoder.readEnum()) } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.cardinality = com.google.protobuf.kotlin.Field.Cardinality.fromNumber(decoder.readEnum()) } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.number = decoder.readInt32() } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.typeUrl = decoder.readString() } - tag.fieldNr == 7 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.oneofIndex = decoder.readInt32() } - tag.fieldNr == 8 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.packed = decoder.readBool() } - tag.fieldNr == 9 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - tag.fieldNr == 10 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.jsonName = decoder.readString() } - tag.fieldNr == 11 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.defaultValue = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -844,19 +894,16 @@ public fun com.google.protobuf.kotlin.EnumInternal.Companion.decodeWith(msg: com tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.EnumValueInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.EnumValueInternal::decodeWith) (msg.enumvalue as MutableList).add(elem) } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - tag.fieldNr == 4 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { if (!msg.presenceMask[0]) { msg.sourceContext = com.google.protobuf.kotlin.SourceContextInternal() @@ -864,15 +911,12 @@ public fun com.google.protobuf.kotlin.EnumInternal.Companion.decodeWith(msg: com decoder.readMessage(msg.sourceContext.asInternal(), com.google.protobuf.kotlin.SourceContextInternal::decodeWith) } - tag.fieldNr == 5 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.syntax = com.google.protobuf.kotlin.Syntax.fromNumber(decoder.readEnum()) } - tag.fieldNr == 6 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.edition = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -952,17 +996,14 @@ public fun com.google.protobuf.kotlin.EnumValueInternal.Companion.decodeWith(msg tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.number = decoder.readInt32() } - tag.fieldNr == 3 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { val elem = com.google.protobuf.kotlin.OptionInternal() decoder.readMessage(elem.asInternal(), com.google.protobuf.kotlin.OptionInternal::decodeWith) (msg.options as MutableList).add(elem) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -1024,7 +1065,6 @@ public fun com.google.protobuf.kotlin.OptionInternal.Companion.decodeWith(msg: c tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.name = decoder.readString() } - tag.fieldNr == 2 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { if (!msg.presenceMask[0]) { msg.value = com.google.protobuf.kotlin.AnyInternal() @@ -1032,7 +1072,6 @@ public fun com.google.protobuf.kotlin.OptionInternal.Companion.decodeWith(msg: c decoder.readMessage(msg.value.asInternal(), com.google.protobuf.kotlin.AnyInternal::decodeWith) } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -1069,15 +1108,12 @@ public fun com.google.protobuf.kotlin.Syntax.Companion.fromNumber(number: Int): 0 -> { com.google.protobuf.kotlin.Syntax.SYNTAX_PROTO2 } - 1 -> { com.google.protobuf.kotlin.Syntax.SYNTAX_PROTO3 } - 2 -> { com.google.protobuf.kotlin.Syntax.SYNTAX_EDITIONS } - else -> { com.google.protobuf.kotlin.Syntax.UNRECOGNIZED(number) } @@ -1090,79 +1126,60 @@ public fun com.google.protobuf.kotlin.Field.Kind.Companion.fromNumber(number: In 0 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_UNKNOWN } - 1 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_DOUBLE } - 2 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_FLOAT } - 3 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_INT64 } - 4 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_UINT64 } - 5 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_INT32 } - 6 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_FIXED64 } - 7 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_FIXED32 } - 8 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_BOOL } - 9 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_STRING } - 10 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_GROUP } - 11 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_MESSAGE } - 12 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_BYTES } - 13 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_UINT32 } - 14 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_ENUM } - 15 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_SFIXED32 } - 16 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_SFIXED64 } - 17 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_SINT32 } - 18 -> { com.google.protobuf.kotlin.Field.Kind.TYPE_SINT64 } - else -> { com.google.protobuf.kotlin.Field.Kind.UNRECOGNIZED(number) } @@ -1175,19 +1192,15 @@ public fun com.google.protobuf.kotlin.Field.Cardinality.Companion.fromNumber(num 0 -> { com.google.protobuf.kotlin.Field.Cardinality.CARDINALITY_UNKNOWN } - 1 -> { com.google.protobuf.kotlin.Field.Cardinality.CARDINALITY_OPTIONAL } - 2 -> { com.google.protobuf.kotlin.Field.Cardinality.CARDINALITY_REQUIRED } - 3 -> { com.google.protobuf.kotlin.Field.Cardinality.CARDINALITY_REPEATED } - else -> { com.google.protobuf.kotlin.Field.Cardinality.UNRECOGNIZED(number) } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt index 07435b293..26ea0e668 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt @@ -41,6 +41,13 @@ public class DoubleValueInternal: com.google.protobuf.kotlin.DoubleValue, kotlin } } + public override fun copy(body: DoubleValueInternal.() -> Unit): DoubleValueInternal { + val copy = DoubleValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.DoubleValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -105,6 +112,13 @@ public class FloatValueInternal: com.google.protobuf.kotlin.FloatValue, kotlinx. } } + public override fun copy(body: FloatValueInternal.() -> Unit): FloatValueInternal { + val copy = FloatValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.FloatValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -169,6 +183,13 @@ public class Int64ValueInternal: com.google.protobuf.kotlin.Int64Value, kotlinx. } } + public override fun copy(body: Int64ValueInternal.() -> Unit): Int64ValueInternal { + val copy = Int64ValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Int64Value): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -233,6 +254,13 @@ public class UInt64ValueInternal: com.google.protobuf.kotlin.UInt64Value, kotlin } } + public override fun copy(body: UInt64ValueInternal.() -> Unit): UInt64ValueInternal { + val copy = UInt64ValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.UInt64Value): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -297,6 +325,13 @@ public class Int32ValueInternal: com.google.protobuf.kotlin.Int32Value, kotlinx. } } + public override fun copy(body: Int32ValueInternal.() -> Unit): Int32ValueInternal { + val copy = Int32ValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.Int32Value): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -361,6 +396,13 @@ public class UInt32ValueInternal: com.google.protobuf.kotlin.UInt32Value, kotlin } } + public override fun copy(body: UInt32ValueInternal.() -> Unit): UInt32ValueInternal { + val copy = UInt32ValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.UInt32Value): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -425,6 +467,13 @@ public class BoolValueInternal: com.google.protobuf.kotlin.BoolValue, kotlinx.rp } } + public override fun copy(body: BoolValueInternal.() -> Unit): BoolValueInternal { + val copy = BoolValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.BoolValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -489,6 +538,13 @@ public class StringValueInternal: com.google.protobuf.kotlin.StringValue, kotlin } } + public override fun copy(body: StringValueInternal.() -> Unit): StringValueInternal { + val copy = StringValueInternal() + copy.value = value + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.StringValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -553,6 +609,13 @@ public class BytesValueInternal: com.google.protobuf.kotlin.BytesValue, kotlinx. } } + public override fun copy(body: BytesValueInternal.() -> Unit): BytesValueInternal { + val copy = BytesValueInternal() + copy.value = value.copyOf() + copy.apply(body) + return copy + } + @kotlinx.rpc.internal.utils.InternalRpcApi public object CODEC: kotlinx.rpc.grpc.codec.MessageCodec { public override fun encode(value: com.google.protobuf.kotlin.BytesValue): kotlinx.rpc.protobuf.input.stream.InputStream { @@ -655,7 +718,6 @@ public fun com.google.protobuf.kotlin.DoubleValueInternal.Companion.decodeWith(m tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.FIXED64 -> { msg.value = decoder.readDouble() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -702,7 +764,6 @@ public fun com.google.protobuf.kotlin.FloatValueInternal.Companion.decodeWith(ms tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.FIXED32 -> { msg.value = decoder.readFloat() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -749,7 +810,6 @@ public fun com.google.protobuf.kotlin.Int64ValueInternal.Companion.decodeWith(ms tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.value = decoder.readInt64() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -796,7 +856,6 @@ public fun com.google.protobuf.kotlin.UInt64ValueInternal.Companion.decodeWith(m tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.value = decoder.readUInt64() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -843,7 +902,6 @@ public fun com.google.protobuf.kotlin.Int32ValueInternal.Companion.decodeWith(ms tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.value = decoder.readInt32() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -890,7 +948,6 @@ public fun com.google.protobuf.kotlin.UInt32ValueInternal.Companion.decodeWith(m tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.value = decoder.readUInt32() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -937,7 +994,6 @@ public fun com.google.protobuf.kotlin.BoolValueInternal.Companion.decodeWith(msg tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.VARINT -> { msg.value = decoder.readBool() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -984,7 +1040,6 @@ public fun com.google.protobuf.kotlin.StringValueInternal.Companion.decodeWith(m tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.value = decoder.readString() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") @@ -1031,7 +1086,6 @@ public fun com.google.protobuf.kotlin.BytesValueInternal.Companion.decodeWith(ms tag.fieldNr == 1 && tag.wireType == kotlinx.rpc.protobuf.internal.WireType.LENGTH_DELIMITED -> { msg.value = decoder.readBytes() } - else -> { if (tag.wireType == kotlinx.rpc.protobuf.internal.WireType.END_GROUP) { throw kotlinx.rpc.protobuf.internal.ProtobufDecodingException("Unexpected END_GROUP tag.") diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index fa6283ba6..618223c6d 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -471,8 +471,6 @@ class ModelToProtobufKotlinCommonGenerator( } } - - private fun CodeGenerator.generatePresenceIndicesObject(declaration: MessageDeclaration) { if (declaration.presenceMaskSize == 0) { return From 24c07511eb65da63ad9e440ccbf55da81b4c3be3 Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Thu, 27 Nov 2025 11:56:32 +0100 Subject: [PATCH 6/8] pb: Fix bytes copy in oneOf --- .../kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt | 16 ++++++++++++++++ .../src/commonTest/proto/oneof.proto | 1 + .../gen/ModelToProtobufKotlinCommonGenerator.kt | 4 +++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt index cd12708fc..6879b62f4 100644 --- a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt +++ b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt @@ -4,11 +4,14 @@ package kotlinx.rpc.protobuf.test +import Equals +import OneOfMsg import invoke import test.submsg.Other import test.submsg.invoke import kotlin.collections.iterator import kotlin.test.Test +import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertNull import kotlin.test.assertTrue @@ -216,6 +219,19 @@ class CopyTest { assertEquals(listOf(1, 2, 3), copy.bytes?.toList()) } + @Test + fun `copy with bytes in oneof - mutating must not affect copy`() { + val userBytes = byteArrayOf(1, 2, 3) + val original = OneOfMsg { + field = OneOfMsg.Field.Bytes(userBytes) + } + val copy = original.copy() + userBytes[0] = 99 + + assertContentEquals(byteArrayOf(99, 2, 3), (original.field as OneOfMsg.Field.Bytes).value) + assertContentEquals(byteArrayOf(1, 2, 3), (copy.field as OneOfMsg.Field.Bytes).value) + } + @Test fun `copy with empty collections`() { val msg = Repeated { diff --git a/protobuf/protobuf-core/src/commonTest/proto/oneof.proto b/protobuf/protobuf-core/src/commonTest/proto/oneof.proto index d0fbdc8fd..7c382ae68 100644 --- a/protobuf/protobuf-core/src/commonTest/proto/oneof.proto +++ b/protobuf/protobuf-core/src/commonTest/proto/oneof.proto @@ -8,6 +8,7 @@ message OneOfMsg { fixed64 fixed = 3; test.submsg.Other other = 4; kotlinx.rpc.protobuf.test.MyEnum enum = 5; + bytes bytes = 6; } } diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index 618223c6d..a8ef7836d 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -441,7 +441,9 @@ class ModelToProtobufKotlinCommonGenerator( contextReceiver = oneOfFullName, ) { // check if the type is copy by value (no need for deep copy) - val copyByValue = { type: FieldType -> type is FieldType.IntegralType || type is FieldType.Enum } + val copyByValue = { type: FieldType -> + (type is FieldType.IntegralType && type != FieldType.IntegralType.BYTES) || type is FieldType.Enum + } // if all variants are integral or enum types, we can just return this directly. val fastPath = oneOf.variants.all { copyByValue(it.type) } From e0e11ef493b5c929dda2a850115a5dda87c1b1ee Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Fri, 28 Nov 2025 11:03:17 +0100 Subject: [PATCH 7/8] pb: Move copy method to copy extension function in internal --- .../com/google/protobuf/kotlin/Any.kt | 5 - .../com/google/protobuf/kotlin/Api.kt | 15 -- .../com/google/protobuf/kotlin/Duration.kt | 5 - .../com/google/protobuf/kotlin/Empty.kt | 5 - .../com/google/protobuf/kotlin/FieldMask.kt | 5 - .../google/protobuf/kotlin/SourceContext.kt | 5 - .../com/google/protobuf/kotlin/Struct.kt | 15 -- .../com/google/protobuf/kotlin/Timestamp.kt | 5 - .../com/google/protobuf/kotlin/Type.kt | 25 --- .../com/google/protobuf/kotlin/Wrappers.kt | 45 ---- .../protobuf/kotlin/_rpc_internal/Any.kt | 23 +- .../protobuf/kotlin/_rpc_internal/Api.kt | 69 +++++- .../protobuf/kotlin/_rpc_internal/Duration.kt | 23 +- .../protobuf/kotlin/_rpc_internal/Empty.kt | 23 +- .../kotlin/_rpc_internal/FieldMask.kt | 23 +- .../kotlin/_rpc_internal/SourceContext.kt | 23 +- .../protobuf/kotlin/_rpc_internal/Struct.kt | 70 +++++- .../kotlin/_rpc_internal/Timestamp.kt | 23 +- .../protobuf/kotlin/_rpc_internal/Type.kt | 115 +++++++++- .../protobuf/kotlin/_rpc_internal/Wrappers.kt | 207 +++++++++++++++++- .../kotlinx/rpc/protobuf/test/CopyTest.kt | 1 + .../ModelToProtobufKotlinCommonGenerator.kt | 47 +++- 22 files changed, 612 insertions(+), 165 deletions(-) diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt index 10f256950..8aed599fa 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Any.kt @@ -128,10 +128,5 @@ public interface Any { */ public val value: ByteArray - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.AnyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Any - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt index 1c473599d..68ea99595 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Api.kt @@ -65,11 +65,6 @@ public interface Api { */ public val syntax: com.google.protobuf.kotlin.Syntax - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.ApiInternal.() -> Unit = {}): com.google.protobuf.kotlin.Api - public companion object } @@ -107,11 +102,6 @@ public interface Method { */ public val syntax: com.google.protobuf.kotlin.Syntax - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.MethodInternal.() -> Unit = {}): com.google.protobuf.kotlin.Method - public companion object } @@ -207,10 +197,5 @@ public interface Mixin { */ public val root: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.MixinInternal.() -> Unit = {}): com.google.protobuf.kotlin.Mixin - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt index 1fa3b8b49..b5fd74ea8 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Duration.kt @@ -81,10 +81,5 @@ public interface Duration { */ public val nanos: Int - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.DurationInternal.() -> Unit = {}): com.google.protobuf.kotlin.Duration - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt index 219e694ba..0ea1dfafa 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Empty.kt @@ -14,10 +14,5 @@ import kotlinx.rpc.internal.utils.* */ @kotlinx.rpc.grpc.codec.WithCodec(com.google.protobuf.kotlin.EmptyInternal.CODEC::class) public interface Empty { - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Empty - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt index 8a3a4fea6..4b50a3707 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/FieldMask.kt @@ -211,10 +211,5 @@ public interface FieldMask { */ public val paths: List - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.FieldMaskInternal.() -> Unit = {}): com.google.protobuf.kotlin.FieldMask - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt index c3f9b54d4..6756c3269 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/SourceContext.kt @@ -15,10 +15,5 @@ public interface SourceContext { */ public val fileName: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.SourceContextInternal.() -> Unit = {}): com.google.protobuf.kotlin.SourceContext - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt index 375d0dc30..5dc863986 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Struct.kt @@ -21,11 +21,6 @@ public interface Struct { */ public val fields: Map - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.StructInternal.() -> Unit = {}): com.google.protobuf.kotlin.Struct - public companion object } @@ -44,11 +39,6 @@ public interface Value { */ public val kind: com.google.protobuf.kotlin.Value.Kind? - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Value - /** * The kind of value. */ @@ -111,11 +101,6 @@ public interface ListValue { */ public val values: List - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.ListValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.ListValue - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt index 151a73171..ea8d32b7f 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Timestamp.kt @@ -110,10 +110,5 @@ public interface Timestamp { */ public val nanos: Int - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.TimestampInternal.() -> Unit = {}): com.google.protobuf.kotlin.Timestamp - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt index 23bc7acfc..1a2836671 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Type.kt @@ -37,11 +37,6 @@ public interface Type { */ public val edition: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.TypeInternal.() -> Unit = {}): com.google.protobuf.kotlin.Type - public companion object } @@ -93,11 +88,6 @@ public interface Field { */ public val defaultValue: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.FieldInternal.() -> Unit = {}): com.google.protobuf.kotlin.Field - /** * Basic field types. */ @@ -268,11 +258,6 @@ public interface Enum { */ public val edition: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.EnumInternal.() -> Unit = {}): com.google.protobuf.kotlin.Enum - public companion object } @@ -294,11 +279,6 @@ public interface EnumValue { */ public val options: List - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.EnumValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.EnumValue - public companion object } @@ -323,11 +303,6 @@ public interface Option { */ public val value: com.google.protobuf.kotlin.Any - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.OptionInternal.() -> Unit = {}): com.google.protobuf.kotlin.Option - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt index 81be10db4..da349669f 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/Wrappers.kt @@ -18,11 +18,6 @@ public interface DoubleValue { */ public val value: Double - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.DoubleValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.DoubleValue - public companion object } @@ -41,11 +36,6 @@ public interface FloatValue { */ public val value: Float - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.FloatValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.FloatValue - public companion object } @@ -64,11 +54,6 @@ public interface Int64Value { */ public val value: Long - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.Int64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int64Value - public companion object } @@ -87,11 +72,6 @@ public interface UInt64Value { */ public val value: ULong - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.UInt64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt64Value - public companion object } @@ -110,11 +90,6 @@ public interface Int32Value { */ public val value: Int - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.Int32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int32Value - public companion object } @@ -133,11 +108,6 @@ public interface UInt32Value { */ public val value: UInt - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.UInt32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt32Value - public companion object } @@ -156,11 +126,6 @@ public interface BoolValue { */ public val value: Boolean - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.BoolValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BoolValue - public companion object } @@ -179,11 +144,6 @@ public interface StringValue { */ public val value: String - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.StringValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.StringValue - public companion object } @@ -202,10 +162,5 @@ public interface BytesValue { */ public val value: ByteArray - /** - * Copies the original message, including unknown fields. - */ - public fun copy(body: com.google.protobuf.kotlin.BytesValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BytesValue - public companion object } diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt index 24bb041bf..905b091e1 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Any.kt @@ -46,7 +46,8 @@ public class AnyInternal: com.google.protobuf.kotlin.Any, kotlinx.rpc.protobuf.i } } - public override fun copy(body: AnyInternal.() -> Unit): AnyInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: AnyInternal.() -> Unit): AnyInternal { val copy = AnyInternal() copy.typeUrl = typeUrl copy.value = value.copyOf() @@ -82,12 +83,32 @@ public class AnyInternal: com.google.protobuf.kotlin.Any, kotlinx.rpc.protobuf.i public companion object } +/** +* Constructs a new message. +* ``` +* val message = Any { +* typeUrl = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Any.Companion.invoke(body: com.google.protobuf.kotlin.AnyInternal.() -> Unit): com.google.protobuf.kotlin.Any { val msg = com.google.protobuf.kotlin.AnyInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* typeUrl = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Any.copy(body: com.google.protobuf.kotlin.AnyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Any { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.AnyInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt index 0f7b25ca0..d84838087 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Api.kt @@ -76,7 +76,8 @@ public class ApiInternal: com.google.protobuf.kotlin.Api, kotlinx.rpc.protobuf.i } } - public override fun copy(body: ApiInternal.() -> Unit): ApiInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: ApiInternal.() -> Unit): ApiInternal { val copy = ApiInternal() copy.name = name copy.methods = methods.map { it.copy() } @@ -181,7 +182,8 @@ public class MethodInternal: com.google.protobuf.kotlin.Method, kotlinx.rpc.prot } } - public override fun copy(body: MethodInternal.() -> Unit): MethodInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: MethodInternal.() -> Unit): MethodInternal { val copy = MethodInternal() copy.name = name copy.requestTypeUrl = requestTypeUrl @@ -263,7 +265,8 @@ public class MixinInternal: com.google.protobuf.kotlin.Mixin, kotlinx.rpc.protob } } - public override fun copy(body: MixinInternal.() -> Unit): MixinInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: MixinInternal.() -> Unit): MixinInternal { val copy = MixinInternal() copy.name = name copy.root = root @@ -299,24 +302,84 @@ public class MixinInternal: com.google.protobuf.kotlin.Mixin, kotlinx.rpc.protob public companion object } +/** +* Constructs a new message. +* ``` +* val message = Api { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Api.Companion.invoke(body: com.google.protobuf.kotlin.ApiInternal.() -> Unit): com.google.protobuf.kotlin.Api { val msg = com.google.protobuf.kotlin.ApiInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Api.copy(body: com.google.protobuf.kotlin.ApiInternal.() -> Unit = {}): com.google.protobuf.kotlin.Api { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Method { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Method.Companion.invoke(body: com.google.protobuf.kotlin.MethodInternal.() -> Unit): com.google.protobuf.kotlin.Method { val msg = com.google.protobuf.kotlin.MethodInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Method.copy(body: com.google.protobuf.kotlin.MethodInternal.() -> Unit = {}): com.google.protobuf.kotlin.Method { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Mixin { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Mixin.Companion.invoke(body: com.google.protobuf.kotlin.MixinInternal.() -> Unit): com.google.protobuf.kotlin.Mixin { val msg = com.google.protobuf.kotlin.MixinInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Mixin.copy(body: com.google.protobuf.kotlin.MixinInternal.() -> Unit = {}): com.google.protobuf.kotlin.Mixin { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.ApiInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt index 919292332..a215b78c6 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Duration.kt @@ -46,7 +46,8 @@ public class DurationInternal: com.google.protobuf.kotlin.Duration, kotlinx.rpc. } } - public override fun copy(body: DurationInternal.() -> Unit): DurationInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: DurationInternal.() -> Unit): DurationInternal { val copy = DurationInternal() copy.seconds = seconds copy.nanos = nanos @@ -82,12 +83,32 @@ public class DurationInternal: com.google.protobuf.kotlin.Duration, kotlinx.rpc. public companion object } +/** +* Constructs a new message. +* ``` +* val message = Duration { +* seconds = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Duration.Companion.invoke(body: com.google.protobuf.kotlin.DurationInternal.() -> Unit): com.google.protobuf.kotlin.Duration { val msg = com.google.protobuf.kotlin.DurationInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* seconds = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Duration.copy(body: com.google.protobuf.kotlin.DurationInternal.() -> Unit = {}): com.google.protobuf.kotlin.Duration { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.DurationInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt index 51f0aaa81..5d096803c 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt @@ -37,7 +37,8 @@ public class EmptyInternal: com.google.protobuf.kotlin.Empty, kotlinx.rpc.protob } } - public override fun copy(body: EmptyInternal.() -> Unit): EmptyInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: EmptyInternal.() -> Unit): EmptyInternal { val copy = EmptyInternal() copy.apply(body) return copy @@ -71,12 +72,32 @@ public class EmptyInternal: com.google.protobuf.kotlin.Empty, kotlinx.rpc.protob public companion object } +/** +* Constructs a new message. +* ``` +* val message = Empty { +* someField = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Empty.Companion.invoke(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit): com.google.protobuf.kotlin.Empty { val msg = com.google.protobuf.kotlin.EmptyInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* someField = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Empty.copy(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Empty { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.EmptyInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt index 3eb7622c2..0ef0fc5fe 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/FieldMask.kt @@ -41,7 +41,8 @@ public class FieldMaskInternal: com.google.protobuf.kotlin.FieldMask, kotlinx.rp } } - public override fun copy(body: FieldMaskInternal.() -> Unit): FieldMaskInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: FieldMaskInternal.() -> Unit): FieldMaskInternal { val copy = FieldMaskInternal() copy.paths = paths.map { it } copy.apply(body) @@ -76,12 +77,32 @@ public class FieldMaskInternal: com.google.protobuf.kotlin.FieldMask, kotlinx.rp public companion object } +/** +* Constructs a new message. +* ``` +* val message = FieldMask { +* paths = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.FieldMask.Companion.invoke(body: com.google.protobuf.kotlin.FieldMaskInternal.() -> Unit): com.google.protobuf.kotlin.FieldMask { val msg = com.google.protobuf.kotlin.FieldMaskInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* paths = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.FieldMask.copy(body: com.google.protobuf.kotlin.FieldMaskInternal.() -> Unit = {}): com.google.protobuf.kotlin.FieldMask { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.FieldMaskInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt index 8f81cef27..102c54b71 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/SourceContext.kt @@ -41,7 +41,8 @@ public class SourceContextInternal: com.google.protobuf.kotlin.SourceContext, ko } } - public override fun copy(body: SourceContextInternal.() -> Unit): SourceContextInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: SourceContextInternal.() -> Unit): SourceContextInternal { val copy = SourceContextInternal() copy.fileName = fileName copy.apply(body) @@ -76,12 +77,32 @@ public class SourceContextInternal: com.google.protobuf.kotlin.SourceContext, ko public companion object } +/** +* Constructs a new message. +* ``` +* val message = SourceContext { +* fileName = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.SourceContext.Companion.invoke(body: com.google.protobuf.kotlin.SourceContextInternal.() -> Unit): com.google.protobuf.kotlin.SourceContext { val msg = com.google.protobuf.kotlin.SourceContextInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* fileName = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.SourceContext.copy(body: com.google.protobuf.kotlin.SourceContextInternal.() -> Unit = {}): com.google.protobuf.kotlin.SourceContext { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.SourceContextInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt index c6309f0e3..48c28f5ac 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Struct.kt @@ -41,7 +41,8 @@ public class StructInternal: com.google.protobuf.kotlin.Struct, kotlinx.rpc.prot } } - public override fun copy(body: StructInternal.() -> Unit): StructInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: StructInternal.() -> Unit): StructInternal { val copy = StructInternal() copy.fields = fields.mapValues { it.value.copy() } copy.apply(body) @@ -180,13 +181,15 @@ public class ValueInternal: com.google.protobuf.kotlin.Value, kotlinx.rpc.protob } } - public override fun copy(body: ValueInternal.() -> Unit): ValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: ValueInternal.() -> Unit): ValueInternal { val copy = ValueInternal() copy.kind = kind?.oneOfCopy() copy.apply(body) return copy } + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.Value.Kind.oneOfCopy(): com.google.protobuf.kotlin.Value.Kind { return when (this) { is com.google.protobuf.kotlin.Value.Kind.NullValue -> { @@ -274,7 +277,8 @@ public class ListValueInternal: com.google.protobuf.kotlin.ListValue, kotlinx.rp } } - public override fun copy(body: ListValueInternal.() -> Unit): ListValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: ListValueInternal.() -> Unit): ListValueInternal { val copy = ListValueInternal() copy.values = values.map { it.copy() } copy.apply(body) @@ -309,24 +313,84 @@ public class ListValueInternal: com.google.protobuf.kotlin.ListValue, kotlinx.rp public companion object } +/** +* Constructs a new message. +* ``` +* val message = Struct { +* fields = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Struct.Companion.invoke(body: com.google.protobuf.kotlin.StructInternal.() -> Unit): com.google.protobuf.kotlin.Struct { val msg = com.google.protobuf.kotlin.StructInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* fields = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Struct.copy(body: com.google.protobuf.kotlin.StructInternal.() -> Unit = {}): com.google.protobuf.kotlin.Struct { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Value { +* kind = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Value.Companion.invoke(body: com.google.protobuf.kotlin.ValueInternal.() -> Unit): com.google.protobuf.kotlin.Value { val msg = com.google.protobuf.kotlin.ValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* kind = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Value.copy(body: com.google.protobuf.kotlin.ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Value { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = ListValue { +* values = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.ListValue.Companion.invoke(body: com.google.protobuf.kotlin.ListValueInternal.() -> Unit): com.google.protobuf.kotlin.ListValue { val msg = com.google.protobuf.kotlin.ListValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* values = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.ListValue.copy(body: com.google.protobuf.kotlin.ListValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.ListValue { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.StructInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt index 35fbddbd3..20bc64873 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Timestamp.kt @@ -46,7 +46,8 @@ public class TimestampInternal: com.google.protobuf.kotlin.Timestamp, kotlinx.rp } } - public override fun copy(body: TimestampInternal.() -> Unit): TimestampInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: TimestampInternal.() -> Unit): TimestampInternal { val copy = TimestampInternal() copy.seconds = seconds copy.nanos = nanos @@ -82,12 +83,32 @@ public class TimestampInternal: com.google.protobuf.kotlin.Timestamp, kotlinx.rp public companion object } +/** +* Constructs a new message. +* ``` +* val message = Timestamp { +* seconds = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Timestamp.Companion.invoke(body: com.google.protobuf.kotlin.TimestampInternal.() -> Unit): com.google.protobuf.kotlin.Timestamp { val msg = com.google.protobuf.kotlin.TimestampInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* seconds = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Timestamp.copy(body: com.google.protobuf.kotlin.TimestampInternal.() -> Unit = {}): com.google.protobuf.kotlin.Timestamp { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.TimestampInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt index fe475b6c1..1a41410ee 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Type.kt @@ -76,7 +76,8 @@ public class TypeInternal: com.google.protobuf.kotlin.Type, kotlinx.rpc.protobuf } } - public override fun copy(body: TypeInternal.() -> Unit): TypeInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: TypeInternal.() -> Unit): TypeInternal { val copy = TypeInternal() copy.name = name copy.fields = fields.map { it.copy() } @@ -193,7 +194,8 @@ public class FieldInternal: com.google.protobuf.kotlin.Field, kotlinx.rpc.protob } } - public override fun copy(body: FieldInternal.() -> Unit): FieldInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: FieldInternal.() -> Unit): FieldInternal { val copy = FieldInternal() copy.kind = kind copy.cardinality = cardinality @@ -304,7 +306,8 @@ public class EnumInternal: com.google.protobuf.kotlin.Enum, kotlinx.rpc.protobuf } } - public override fun copy(body: EnumInternal.() -> Unit): EnumInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: EnumInternal.() -> Unit): EnumInternal { val copy = EnumInternal() copy.name = name copy.enumvalue = enumvalue.map { it.copy() } @@ -392,7 +395,8 @@ public class EnumValueInternal: com.google.protobuf.kotlin.EnumValue, kotlinx.rp } } - public override fun copy(body: EnumValueInternal.() -> Unit): EnumValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: EnumValueInternal.() -> Unit): EnumValueInternal { val copy = EnumValueInternal() copy.name = name copy.number = number @@ -480,7 +484,8 @@ public class OptionInternal: com.google.protobuf.kotlin.Option, kotlinx.rpc.prot } } - public override fun copy(body: OptionInternal.() -> Unit): OptionInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: OptionInternal.() -> Unit): OptionInternal { val copy = OptionInternal() copy.name = name if (presenceMask[0]) { @@ -519,36 +524,136 @@ public class OptionInternal: com.google.protobuf.kotlin.Option, kotlinx.rpc.prot public companion object } +/** +* Constructs a new message. +* ``` +* val message = Type { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Type.Companion.invoke(body: com.google.protobuf.kotlin.TypeInternal.() -> Unit): com.google.protobuf.kotlin.Type { val msg = com.google.protobuf.kotlin.TypeInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Type.copy(body: com.google.protobuf.kotlin.TypeInternal.() -> Unit = {}): com.google.protobuf.kotlin.Type { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Field { +* kind = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Field.Companion.invoke(body: com.google.protobuf.kotlin.FieldInternal.() -> Unit): com.google.protobuf.kotlin.Field { val msg = com.google.protobuf.kotlin.FieldInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* kind = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Field.copy(body: com.google.protobuf.kotlin.FieldInternal.() -> Unit = {}): com.google.protobuf.kotlin.Field { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Enum { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Enum.Companion.invoke(body: com.google.protobuf.kotlin.EnumInternal.() -> Unit): com.google.protobuf.kotlin.Enum { val msg = com.google.protobuf.kotlin.EnumInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Enum.copy(body: com.google.protobuf.kotlin.EnumInternal.() -> Unit = {}): com.google.protobuf.kotlin.Enum { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = EnumValue { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.EnumValue.Companion.invoke(body: com.google.protobuf.kotlin.EnumValueInternal.() -> Unit): com.google.protobuf.kotlin.EnumValue { val msg = com.google.protobuf.kotlin.EnumValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.EnumValue.copy(body: com.google.protobuf.kotlin.EnumValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.EnumValue { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Option { +* name = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Option.Companion.invoke(body: com.google.protobuf.kotlin.OptionInternal.() -> Unit): com.google.protobuf.kotlin.Option { val msg = com.google.protobuf.kotlin.OptionInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* name = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Option.copy(body: com.google.protobuf.kotlin.OptionInternal.() -> Unit = {}): com.google.protobuf.kotlin.Option { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.TypeInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt index 26ea0e668..31e6885e3 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Wrappers.kt @@ -41,7 +41,8 @@ public class DoubleValueInternal: com.google.protobuf.kotlin.DoubleValue, kotlin } } - public override fun copy(body: DoubleValueInternal.() -> Unit): DoubleValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: DoubleValueInternal.() -> Unit): DoubleValueInternal { val copy = DoubleValueInternal() copy.value = value copy.apply(body) @@ -112,7 +113,8 @@ public class FloatValueInternal: com.google.protobuf.kotlin.FloatValue, kotlinx. } } - public override fun copy(body: FloatValueInternal.() -> Unit): FloatValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: FloatValueInternal.() -> Unit): FloatValueInternal { val copy = FloatValueInternal() copy.value = value copy.apply(body) @@ -183,7 +185,8 @@ public class Int64ValueInternal: com.google.protobuf.kotlin.Int64Value, kotlinx. } } - public override fun copy(body: Int64ValueInternal.() -> Unit): Int64ValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: Int64ValueInternal.() -> Unit): Int64ValueInternal { val copy = Int64ValueInternal() copy.value = value copy.apply(body) @@ -254,7 +257,8 @@ public class UInt64ValueInternal: com.google.protobuf.kotlin.UInt64Value, kotlin } } - public override fun copy(body: UInt64ValueInternal.() -> Unit): UInt64ValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: UInt64ValueInternal.() -> Unit): UInt64ValueInternal { val copy = UInt64ValueInternal() copy.value = value copy.apply(body) @@ -325,7 +329,8 @@ public class Int32ValueInternal: com.google.protobuf.kotlin.Int32Value, kotlinx. } } - public override fun copy(body: Int32ValueInternal.() -> Unit): Int32ValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: Int32ValueInternal.() -> Unit): Int32ValueInternal { val copy = Int32ValueInternal() copy.value = value copy.apply(body) @@ -396,7 +401,8 @@ public class UInt32ValueInternal: com.google.protobuf.kotlin.UInt32Value, kotlin } } - public override fun copy(body: UInt32ValueInternal.() -> Unit): UInt32ValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: UInt32ValueInternal.() -> Unit): UInt32ValueInternal { val copy = UInt32ValueInternal() copy.value = value copy.apply(body) @@ -467,7 +473,8 @@ public class BoolValueInternal: com.google.protobuf.kotlin.BoolValue, kotlinx.rp } } - public override fun copy(body: BoolValueInternal.() -> Unit): BoolValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: BoolValueInternal.() -> Unit): BoolValueInternal { val copy = BoolValueInternal() copy.value = value copy.apply(body) @@ -538,7 +545,8 @@ public class StringValueInternal: com.google.protobuf.kotlin.StringValue, kotlin } } - public override fun copy(body: StringValueInternal.() -> Unit): StringValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: StringValueInternal.() -> Unit): StringValueInternal { val copy = StringValueInternal() copy.value = value copy.apply(body) @@ -609,7 +617,8 @@ public class BytesValueInternal: com.google.protobuf.kotlin.BytesValue, kotlinx. } } - public override fun copy(body: BytesValueInternal.() -> Unit): BytesValueInternal { + @kotlinx.rpc.internal.utils.InternalRpcApi + public fun copyInternal(body: BytesValueInternal.() -> Unit): BytesValueInternal { val copy = BytesValueInternal() copy.value = value.copyOf() copy.apply(body) @@ -644,60 +653,240 @@ public class BytesValueInternal: com.google.protobuf.kotlin.BytesValue, kotlinx. public companion object } +/** +* Constructs a new message. +* ``` +* val message = DoubleValue { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.DoubleValue.Companion.invoke(body: com.google.protobuf.kotlin.DoubleValueInternal.() -> Unit): com.google.protobuf.kotlin.DoubleValue { val msg = com.google.protobuf.kotlin.DoubleValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.DoubleValue.copy(body: com.google.protobuf.kotlin.DoubleValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.DoubleValue { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = FloatValue { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.FloatValue.Companion.invoke(body: com.google.protobuf.kotlin.FloatValueInternal.() -> Unit): com.google.protobuf.kotlin.FloatValue { val msg = com.google.protobuf.kotlin.FloatValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.FloatValue.copy(body: com.google.protobuf.kotlin.FloatValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.FloatValue { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Int64Value { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Int64Value.Companion.invoke(body: com.google.protobuf.kotlin.Int64ValueInternal.() -> Unit): com.google.protobuf.kotlin.Int64Value { val msg = com.google.protobuf.kotlin.Int64ValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Int64Value.copy(body: com.google.protobuf.kotlin.Int64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int64Value { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = UInt64Value { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.UInt64Value.Companion.invoke(body: com.google.protobuf.kotlin.UInt64ValueInternal.() -> Unit): com.google.protobuf.kotlin.UInt64Value { val msg = com.google.protobuf.kotlin.UInt64ValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.UInt64Value.copy(body: com.google.protobuf.kotlin.UInt64ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt64Value { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = Int32Value { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.Int32Value.Companion.invoke(body: com.google.protobuf.kotlin.Int32ValueInternal.() -> Unit): com.google.protobuf.kotlin.Int32Value { val msg = com.google.protobuf.kotlin.Int32ValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.Int32Value.copy(body: com.google.protobuf.kotlin.Int32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.Int32Value { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = UInt32Value { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.UInt32Value.Companion.invoke(body: com.google.protobuf.kotlin.UInt32ValueInternal.() -> Unit): com.google.protobuf.kotlin.UInt32Value { val msg = com.google.protobuf.kotlin.UInt32ValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.UInt32Value.copy(body: com.google.protobuf.kotlin.UInt32ValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.UInt32Value { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = BoolValue { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.BoolValue.Companion.invoke(body: com.google.protobuf.kotlin.BoolValueInternal.() -> Unit): com.google.protobuf.kotlin.BoolValue { val msg = com.google.protobuf.kotlin.BoolValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.BoolValue.copy(body: com.google.protobuf.kotlin.BoolValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BoolValue { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = StringValue { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.StringValue.Companion.invoke(body: com.google.protobuf.kotlin.StringValueInternal.() -> Unit): com.google.protobuf.kotlin.StringValue { val msg = com.google.protobuf.kotlin.StringValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.StringValue.copy(body: com.google.protobuf.kotlin.StringValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.StringValue { + return this.asInternal().copyInternal(body) +} + +/** +* Constructs a new message. +* ``` +* val message = BytesValue { +* value = ... +* } +* ``` +*/ public operator fun com.google.protobuf.kotlin.BytesValue.Companion.invoke(body: com.google.protobuf.kotlin.BytesValueInternal.() -> Unit): com.google.protobuf.kotlin.BytesValue { val msg = com.google.protobuf.kotlin.BytesValueInternal().apply(body) msg.checkRequiredFields() return msg } +/** +* Copies the original message, including unknown fields. +* ``` +* val copy = original.copy { +* value = ... +* } +* ``` +*/ +public fun com.google.protobuf.kotlin.BytesValue.copy(body: com.google.protobuf.kotlin.BytesValueInternal.() -> Unit = {}): com.google.protobuf.kotlin.BytesValue { + return this.asInternal().copyInternal(body) +} + @kotlinx.rpc.internal.utils.InternalRpcApi public fun com.google.protobuf.kotlin.DoubleValueInternal.checkRequiredFields() { // no required fields to check diff --git a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt index 6879b62f4..1668bd858 100644 --- a/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt +++ b/protobuf/protobuf-core/src/commonTest/kotlin/kotlinx/rpc/protobuf/test/CopyTest.kt @@ -6,6 +6,7 @@ package kotlinx.rpc.protobuf.test import Equals import OneOfMsg +import copy import invoke import test.submsg.Other import test.submsg.invoke diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index a8ef7836d..d2838019e 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -58,6 +58,7 @@ class ModelToProtobufKotlinCommonGenerator( val allMsgs = messages + messages.flatMap(MessageDeclaration::allNestedRecursively) allMsgs.forEach { generateMessageConstructor(it) + generatePublicCopy(it) } allMsgs.forEach { generateRequiredCheck(it) @@ -94,12 +95,6 @@ class ModelToProtobufKotlinCommonGenerator( ) } - function("copy", - args = "body: ${declaration.internalClassFullName()}.() -> Unit = {}", - returnType = declaration.name.safeFullName(), - comment = Comment.leading("Copies the original message, including unknown fields.") - ) - if (declaration.actualFields.isNotEmpty()) { newLine() } @@ -186,7 +181,7 @@ class ModelToProtobufKotlinCommonGenerator( generateOneOfHashCode(declaration) generateEquals(declaration) generateToString(declaration) - generateCopy(declaration) + generateInternalCopy(declaration) generateOneOfCopy(declaration) declaration.nestedDeclarations.forEach { nested -> @@ -387,14 +382,38 @@ class ModelToProtobufKotlinCommonGenerator( } } - private fun CodeGenerator.generateCopy(declaration: MessageDeclaration) { + private fun CodeGenerator.generatePublicCopy(declaration: MessageDeclaration) { if (!declaration.isUserFacing) { // e.g., internal map entries don't need a copy() method return } + val demoField = declaration.actualFields.firstOrNull()?.name ?: "someField" function( name = "copy", - modifiers = "override", + contextReceiver = declaration.name.safeFullName(), + args = "body: ${declaration.internalClassFullName()}.() -> Unit = {}", + returnType = declaration.name.safeFullName(), + comment = Comment.leading(""" + Copies the original message, including unknown fields. + ``` + val copy = original.copy { + $demoField = ... + } + ``` + """.trimIndent()) + ) { + code("return this.asInternal().copyInternal(body)") + } + } + + private fun CodeGenerator.generateInternalCopy(declaration: MessageDeclaration) { + if (!declaration.isUserFacing) { + // e.g., internal map entries don't need a copy() method + return + } + function( + name = "copyInternal", + annotations = listOf("@$INTERNAL_RPC_API_ANNO"), args = "body: ${declaration.internalClassName()}.() -> Unit", returnType = declaration.internalClassName(), ) { @@ -437,6 +456,7 @@ class ModelToProtobufKotlinCommonGenerator( val oneOfFullName = oneOf.name.safeFullName() function( name = "oneOfCopy", + annotations = listOf("@$INTERNAL_RPC_API_ANNO"), returnType = oneOfFullName, contextReceiver = oneOfFullName, ) { @@ -569,12 +589,21 @@ class ModelToProtobufKotlinCommonGenerator( private fun CodeGenerator.generateMessageConstructor(declaration: MessageDeclaration) { if (!declaration.isUserFacing) return + val demoField = declaration.actualFields.firstOrNull()?.name ?: "someField" function( name = "invoke", modifiers = "operator", args = "body: ${declaration.internalClassFullName()}.() -> Unit", contextReceiver = "${declaration.name.safeFullName()}.Companion", returnType = declaration.name.safeFullName(), + comment = Comment.leading(""" + Constructs a new message. + ``` + val message = ${declaration.name.simpleName} { + $demoField = ... + } + ``` + """.trimIndent()) ) { code("val msg = ${declaration.internalClassFullName()}().apply(body)") // check if the user set all required fields From c488e5899b7f9d8cc9273ff858e34fdfd864c807 Mon Sep 17 00:00:00 2001 From: Johannes Zottele Date: Fri, 28 Nov 2025 11:32:38 +0100 Subject: [PATCH 8/8] pb: Construct demo docs conditionally --- .../protobuf/kotlin/_rpc_internal/Empty.kt | 8 +--- .../ModelToProtobufKotlinCommonGenerator.kt | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt index 5d096803c..97b2be560 100644 --- a/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt +++ b/protobuf/protobuf-core/src/commonMain/generated-code/kotlin-multiplatform/com/google/protobuf/kotlin/_rpc_internal/Empty.kt @@ -75,9 +75,7 @@ public class EmptyInternal: com.google.protobuf.kotlin.Empty, kotlinx.rpc.protob /** * Constructs a new message. * ``` -* val message = Empty { -* someField = ... -* } +* val message = Empty { } * ``` */ public operator fun com.google.protobuf.kotlin.Empty.Companion.invoke(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit): com.google.protobuf.kotlin.Empty { @@ -89,9 +87,7 @@ public operator fun com.google.protobuf.kotlin.Empty.Companion.invoke(body: com. /** * Copies the original message, including unknown fields. * ``` -* val copy = original.copy { -* someField = ... -* } +* val copy = original.copy() * ``` */ public fun com.google.protobuf.kotlin.Empty.copy(body: com.google.protobuf.kotlin.EmptyInternal.() -> Unit = {}): com.google.protobuf.kotlin.Empty { diff --git a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt index d2838019e..16f6fa612 100644 --- a/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt +++ b/protoc-gen/protobuf/src/main/kotlin/kotlinx/rpc/protoc/gen/ModelToProtobufKotlinCommonGenerator.kt @@ -387,20 +387,23 @@ class ModelToProtobufKotlinCommonGenerator( // e.g., internal map entries don't need a copy() method return } - val demoField = declaration.actualFields.firstOrNull()?.name ?: "someField" + val demoField = declaration.actualFields.firstOrNull()?.name + val invocation = if (demoField == null) "()" else """ + | { + | $demoField = ... + |} + """.trimMargin() function( name = "copy", contextReceiver = declaration.name.safeFullName(), args = "body: ${declaration.internalClassFullName()}.() -> Unit = {}", returnType = declaration.name.safeFullName(), comment = Comment.leading(""" - Copies the original message, including unknown fields. - ``` - val copy = original.copy { - $demoField = ... - } - ``` - """.trimIndent()) + |Copies the original message, including unknown fields. + |``` + |val copy = original.copy$invocation + |``` + """.trimMargin()) ) { code("return this.asInternal().copyInternal(body)") } @@ -589,7 +592,12 @@ class ModelToProtobufKotlinCommonGenerator( private fun CodeGenerator.generateMessageConstructor(declaration: MessageDeclaration) { if (!declaration.isUserFacing) return - val demoField = declaration.actualFields.firstOrNull()?.name ?: "someField" + val demoField = declaration.actualFields.firstOrNull()?.name + val invocation = if (demoField == null) "{ }" else """ + |{ + | $demoField = ... + |} + """.trimMargin() function( name = "invoke", modifiers = "operator", @@ -597,13 +605,11 @@ class ModelToProtobufKotlinCommonGenerator( contextReceiver = "${declaration.name.safeFullName()}.Companion", returnType = declaration.name.safeFullName(), comment = Comment.leading(""" - Constructs a new message. - ``` - val message = ${declaration.name.simpleName} { - $demoField = ... - } - ``` - """.trimIndent()) + |Constructs a new message. + |``` + |val message = ${declaration.name.simpleName} $invocation + |``` + """.trimMargin()) ) { code("val msg = ${declaration.internalClassFullName()}().apply(body)") // check if the user set all required fields