Skip to content

Commit 49db8e1

Browse files
committed
grpc-native: First message generation
Signed-off-by: Johannes Zottele <[email protected]>
1 parent 75f8b3c commit 49db8e1

File tree

30 files changed

+724
-57
lines changed

30 files changed

+724
-57
lines changed

gradle-plugin/src/main/kotlin/kotlinx/rpc/proto/DefaultProtoSourceSet.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ import kotlinx.rpc.buf.tasks.BufGenerateTask
88
import kotlinx.rpc.util.findOrCreate
99
import kotlinx.rpc.util.withKotlinJvmExtension
1010
import kotlinx.rpc.util.withKotlinKmpExtension
11-
import org.gradle.api.Action
12-
import org.gradle.api.GradleException
13-
import org.gradle.api.NamedDomainObjectFactory
14-
import org.gradle.api.NamedDomainObjectProvider
15-
import org.gradle.api.Project
11+
import org.gradle.api.*
1612
import org.gradle.api.file.SourceDirectorySet
1713
import org.gradle.api.provider.ListProperty
1814
import org.gradle.api.provider.Property
@@ -104,7 +100,7 @@ internal fun Project.createProtoExtensions() {
104100
findOrCreateAndConfigure("jvmTest", null)
105101

106102
sourceSets.configureEach {
107-
if (name == "jvmMain" || name == "jvmTest") {
103+
if (name == "jvmMain" || name == "jvmTest" || name == "nativeTest") {
108104
findOrCreateAndConfigure(name, this)
109105
}
110106
}

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/KTag.kt renamed to grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/KTag.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
package kotlinx.rpc.grpc.internal
5+
package kotlinx.rpc.grpc.pb
66

7-
import kotlinx.rpc.grpc.internal.KTag.Companion.K_TAG_TYPE_BITS
8-
9-
internal enum class WireType {
7+
public enum class WireType {
108
VARINT, // 0
119
FIXED64, // 1
1210
LENGTH_DELIMITED, // 2
@@ -15,13 +13,13 @@ internal enum class WireType {
1513
FIXED32, // 5
1614
}
1715

18-
internal data class KTag(val fieldNr: Int, val wireType: WireType) {
16+
public data class KTag(val fieldNr: Int, val wireType: WireType) {
1917

2018
init {
2119
check(isValidFieldNr(fieldNr)) { "Invalid field number: $fieldNr" }
2220
}
2321

24-
companion object {
22+
internal companion object {
2523
// Number of bits in a tag which identify the wire type.
2624
const val K_TAG_TYPE_BITS: Int = 3;
2725

@@ -31,7 +29,7 @@ internal data class KTag(val fieldNr: Int, val wireType: WireType) {
3129
}
3230

3331
internal fun KTag.toRawKTag(): UInt {
34-
return (fieldNr.toUInt() shl K_TAG_TYPE_BITS) or wireType.ordinal.toUInt()
32+
return (fieldNr.toUInt() shl KTag.Companion.K_TAG_TYPE_BITS) or wireType.ordinal.toUInt()
3533
}
3634

3735
internal fun KTag.Companion.fromOrNull(rawKTag: UInt): KTag? {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.rpc.grpc.pb
6+
7+
import kotlinx.io.Buffer
8+
import kotlinx.rpc.internal.utils.InternalRpcApi
9+
10+
/**
11+
* A platform-specific decoder for wire format data.
12+
*
13+
* This decoder is used by first calling [readTag], than looking up the field based on the field number in the returned,
14+
* tag and then calling the actual `read*()` method to read the value to the corresponding field.
15+
*
16+
* [hadError] indicates an error during decoding. While calling `read*()` is safe, the returned values
17+
* are meaningless if [hadError] returns `true`.
18+
*
19+
* NOTE: If the [hadError] after a call to `read*()` returns `false`, it doesn't mean that the
20+
* value is correctly decoded. E.g., the following test will pass:
21+
* ```kt
22+
* val fieldNr = 1
23+
* val buffer = Buffer()
24+
*
25+
* val encoder = WireEncoder(buffer)
26+
* assertTrue(encoder.writeInt32(fieldNr, 12312))
27+
* encoder.flush()
28+
*
29+
* WireDecoder(buffer).use { decoder ->
30+
* decoder.readTag()
31+
* decoder.readBool()
32+
* assertFalse(decoder.hasError())
33+
* }
34+
* ```
35+
*/
36+
@InternalRpcApi
37+
public interface WireDecoder : AutoCloseable {
38+
public fun hadError(): Boolean
39+
40+
/**
41+
* When the read tag is null, it indicates EOF and the parse may stop at this point.
42+
*/
43+
public fun readTag(): KTag?
44+
public fun readBool(): Boolean
45+
public fun readInt32(): Int
46+
public fun readInt64(): Long
47+
public fun readUInt32(): UInt
48+
public fun readUInt64(): ULong
49+
public fun readSInt32(): Int
50+
public fun readSInt64(): Long
51+
public fun readFixed32(): UInt
52+
public fun readFixed64(): ULong
53+
public fun readSFixed32(): Int
54+
public fun readSFixed64(): Long
55+
public fun readFloat(): Float
56+
public fun readDouble(): Double
57+
58+
public fun readEnum(): Int
59+
public fun readString(): String
60+
public fun readBytes(): ByteArray
61+
public fun readPackedBool(): List<Boolean>
62+
public fun readPackedInt32(): List<Int>
63+
public fun readPackedInt64(): List<Long>
64+
public fun readPackedSInt32(): List<Int>
65+
public fun readPackedSInt64(): List<Long>
66+
public fun readPackedUInt32(): List<UInt>
67+
public fun readPackedUInt64(): List<ULong>
68+
public fun readPackedFixed32(): List<UInt>
69+
public fun readPackedFixed64(): List<ULong>
70+
public fun readPackedSFixed32(): List<Int>
71+
public fun readPackedSFixed64(): List<Long>
72+
public fun readPackedFloat(): List<Float>
73+
public fun readPackedDouble(): List<Double>
74+
public fun readPackedEnum(): List<Int>
75+
}
76+
77+
/**
78+
* Creates a platform-specific [WireDecoder].
79+
*
80+
* This constructor takes a [Buffer] instead of a [kotlinx.io.Source] because
81+
* the native implementation (`WireDecoderNative`) depends on [Buffer]'s internal structure.
82+
*
83+
* NOTE: Do not use the [source] buffer while the [WireDecoder] is still open.
84+
*
85+
* @param source The buffer containing the encoded wire-format data.
86+
*/
87+
internal expect fun WireDecoder(source: Buffer): WireDecoder
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.rpc.grpc.pb
6+
7+
import kotlinx.io.Sink
8+
import kotlinx.rpc.internal.utils.InternalRpcApi
9+
10+
/**
11+
* A platform-specific class that encodes values into protobuf's wire format.
12+
*
13+
* If one `write*()` method returns false, the encoding of the value failed
14+
* and no further encodings can be performed on this [WireEncoder].
15+
*
16+
* [flush] must be called to ensure that all data is written to the [Sink].
17+
*/
18+
@InternalRpcApi
19+
@OptIn(ExperimentalUnsignedTypes::class)
20+
public interface WireEncoder {
21+
public fun flush()
22+
public fun writeBool(field: Int, value: Boolean): Boolean
23+
public fun writeInt32(fieldNr: Int, value: Int): Boolean
24+
public fun writeInt64(fieldNr: Int, value: Long): Boolean
25+
public fun writeUInt32(fieldNr: Int, value: UInt): Boolean
26+
public fun writeUInt64(fieldNr: Int, value: ULong): Boolean
27+
public fun writeSInt32(fieldNr: Int, value: Int): Boolean
28+
public fun writeSInt64(fieldNr: Int, value: Long): Boolean
29+
public fun writeFixed32(fieldNr: Int, value: UInt): Boolean
30+
public fun writeFixed64(fieldNr: Int, value: ULong): Boolean
31+
public fun writeSFixed32(fieldNr: Int, value: Int): Boolean
32+
public fun writeSFixed64(fieldNr: Int, value: Long): Boolean
33+
public fun writeFloat(fieldNr: Int, value: Float): Boolean
34+
public fun writeDouble(fieldNr: Int, value: Double): Boolean
35+
public fun writeEnum(fieldNr: Int, value: Int): Boolean
36+
public fun writeBytes(fieldNr: Int, value: ByteArray): Boolean
37+
public fun writeString(fieldNr: Int, value: String): Boolean
38+
public fun writePackedBool(fieldNr: Int, value: List<Boolean>, fieldSize: Int): Boolean
39+
public fun writePackedInt32(fieldNr: Int, value: List<Int>, fieldSize: Int): Boolean
40+
public fun writePackedInt64(fieldNr: Int, value: List<Long>, fieldSize: Int): Boolean
41+
public fun writePackedUInt32(fieldNr: Int, value: List<UInt>, fieldSize: Int): Boolean
42+
public fun writePackedUInt64(fieldNr: Int, value: List<ULong>, fieldSize: Int): Boolean
43+
public fun writePackedSInt32(fieldNr: Int, value: List<Int>, fieldSize: Int): Boolean
44+
public fun writePackedSInt64(fieldNr: Int, value: List<Long>, fieldSize: Int): Boolean
45+
public fun writePackedFixed32(fieldNr: Int, value: List<UInt>): Boolean
46+
public fun writePackedFixed64(fieldNr: Int, value: List<ULong>): Boolean
47+
public fun writePackedSFixed32(fieldNr: Int, value: List<Int>): Boolean
48+
public fun writePackedSFixed64(fieldNr: Int, value: List<Long>): Boolean
49+
public fun writePackedFloat(fieldNr: Int, value: List<Float>): Boolean
50+
public fun writePackedDouble(fieldNr: Int, value: List<Double>): Boolean
51+
public fun writePackedEnum(fieldNr: Int, value: List<Int>, fieldSize: Int): Boolean =
52+
writePackedInt32(fieldNr, value, fieldSize)
53+
}
54+
55+
56+
internal expect fun WireEncoder(sink: Sink): WireEncoder

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/WireSize.kt renamed to grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/WireSize.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
package kotlinx.rpc.grpc.internal
5+
package kotlinx.rpc.grpc.pb
66

77
internal object WireSize
88

grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/internal/WireCodecTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package kotlinx.rpc.grpc.internal
66

77
import kotlinx.io.Buffer
8+
import kotlinx.rpc.grpc.pb.*
9+
import kotlin.experimental.ExperimentalNativeApi
810
import kotlin.test.*
911

1012
enum class TestPlatform {

grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/internal/WireDecoder.js.kt renamed to grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/pb/WireDecoder.js.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
package kotlinx.rpc.grpc.internal
5+
package kotlinx.rpc.grpc.pb
66

77
import kotlinx.io.Buffer
8-
import kotlinx.io.Source
98

109
internal actual fun WireDecoder(source: Buffer): WireDecoder {
1110
TODO("Not yet implemented")

grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/internal/WireEncoder.js.kt renamed to grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/pb/WireEncoder.js.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
package kotlinx.rpc.grpc.internal
5+
package kotlinx.rpc.grpc.pb
66

77
import kotlinx.io.Sink
88

grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/internal/WireSize.js.kt renamed to grpc/grpc-core/src/jsMain/kotlin/kotlinx/rpc/grpc/pb/WireSize.js.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
package kotlinx.rpc.grpc.internal
5+
package kotlinx.rpc.grpc.pb
66

77
internal actual fun WireSize.int32(value: Int): UInt {
88
TODO("Not yet implemented")

0 commit comments

Comments
 (0)