Skip to content

Commit aab38b9

Browse files
authored
grpc: Support sub-messages (#430)
* grpc-pb: Implement sub messages Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: First successful sub-message test Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Support recursive messages Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Support nested message Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Support repeated messages Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Make generated methods internal Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Support message in oneof Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Add test for enum in oneOf Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Add oneOf message merge test Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Check required fields ins submessages Signed-off-by: Johannes Zottele <[email protected]> * grpc-pb: Address PR comments Signed-off-by: Johannes Zottele <[email protected]> --------- Signed-off-by: Johannes Zottele <[email protected]>
1 parent d9a0cd3 commit aab38b9

File tree

20 files changed

+784
-129
lines changed

20 files changed

+784
-129
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/InternalMessage.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,41 @@ package kotlinx.rpc.grpc.pb
66

77
import kotlinx.rpc.grpc.utils.BitSet
88
import kotlinx.rpc.internal.utils.InternalRpcApi
9+
import kotlin.properties.ReadWriteProperty
10+
import kotlin.reflect.KProperty
911

1012
@InternalRpcApi
1113
public abstract class InternalMessage(fieldsWithPresence: Int) {
1214
public val presenceMask: BitSet = BitSet(fieldsWithPresence)
15+
16+
@Suppress("PropertyName")
17+
public abstract val _size: Int
18+
}
19+
20+
@InternalRpcApi
21+
public class MsgFieldDelegate<T : Any>(
22+
private val presenceIdx: Int? = null,
23+
private val defaultProvider: (() -> T)? = null
24+
) : ReadWriteProperty<InternalMessage, T> {
25+
26+
private var valueSet = false
27+
private var value: T? = null
28+
29+
override operator fun getValue(thisRef: InternalMessage, property: KProperty<*>): T {
30+
if (!valueSet) {
31+
if (defaultProvider != null) {
32+
value = defaultProvider.invoke()
33+
valueSet = true
34+
} else {
35+
error("Property ${property.name} not initialized")
36+
}
37+
}
38+
return value as T
39+
}
40+
41+
override operator fun setValue(thisRef: InternalMessage, property: KProperty<*>, value: T) {
42+
presenceIdx?.let { thisRef.presenceMask[it] = true }
43+
this@MsgFieldDelegate.value = value
44+
valueSet = true
45+
}
1346
}

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/WireDecoder.kt

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

77
import kotlinx.io.Buffer
8+
import kotlinx.rpc.grpc.internal.popLimit
9+
import kotlinx.rpc.grpc.internal.pushLimit
810
import kotlinx.rpc.internal.utils.InternalRpcApi
911

1012
// TODO: Evaluate if this buffer size is suitable for all targets (KRPC-186)
@@ -76,6 +78,16 @@ public interface WireDecoder : AutoCloseable {
7678
public fun readPackedFloat(): List<Float>
7779
public fun readPackedDouble(): List<Double>
7880
public fun readPackedEnum(): List<Int>
81+
82+
// TODO: Throw error instead of just returning
83+
public fun <T : InternalMessage> readMessage(msg: T, decoder: (T, WireDecoder) -> Unit) {
84+
val len = readInt32()
85+
if (hadError()) return
86+
if (len <= 0) return
87+
val limit = pushLimit(len)
88+
decoder(msg, this)
89+
popLimit(limit)
90+
}
7991
}
8092

8193
/**

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/WireEncoder.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ public interface WireEncoder {
5050
public fun writePackedDouble(fieldNr: Int, value: List<Double>): Boolean
5151
public fun writePackedEnum(fieldNr: Int, value: List<Int>, fieldSize: Int): Boolean =
5252
writePackedInt32(fieldNr, value, fieldSize)
53+
54+
public fun <T : InternalMessage> writeMessage(
55+
fieldNr: Int,
56+
value: T,
57+
encode: T.(WireEncoder) -> Unit
58+
)
59+
5360
}
5461

5562

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
package kotlinx.rpc.grpc.pb
66

7+
import kotlinx.io.bytestring.encodeToByteString
78
import kotlinx.rpc.internal.utils.InternalRpcApi
89

910
@InternalRpcApi
1011
public object WireSize
1112

13+
public fun WireSize.tag(fieldNumber: Int, wireType: WireType): Int =
14+
uInt32(KTag(fieldNumber, wireType).toRawKTag())
15+
1216
@InternalRpcApi
1317
public expect fun WireSize.int32(value: Int): Int
1418

@@ -27,12 +31,36 @@ public expect fun WireSize.sInt32(value: Int): Int
2731
@InternalRpcApi
2832
public expect fun WireSize.sInt64(value: Long): Int
2933

34+
@InternalRpcApi
35+
public fun WireSize.float(value: Float): Int = 32
36+
37+
@InternalRpcApi
38+
public fun WireSize.double(value: Double): Int = 64
39+
40+
@InternalRpcApi
41+
public fun WireSize.fixed32(value: UInt): Int = 32
42+
43+
@InternalRpcApi
44+
public fun WireSize.fixed64(value: ULong): Int = 64
45+
46+
@InternalRpcApi
47+
public fun WireSize.sFixed32(value: Int): Int = 32
48+
49+
@InternalRpcApi
50+
public fun WireSize.sFixed64(value: Long): Int = 64
51+
3052
@InternalRpcApi
3153
public fun WireSize.bool(value: Boolean): Int = int32(if (value) 1 else 0)
3254

3355
@InternalRpcApi
3456
public fun WireSize.enum(value: Int): Int = int32(value)
3557

58+
@InternalRpcApi
59+
public fun WireSize.bytes(value: ByteArray): Int = value.size
60+
61+
@InternalRpcApi
62+
public fun WireSize.string(value: String): Int = value.encodeToByteString().size
63+
3664
@InternalRpcApi
3765
public fun WireSize.packedInt32(value: List<Int>): Int = value.sumOf { int32(it) }
3866

@@ -53,3 +81,21 @@ public fun WireSize.packedSInt64(value: List<Long>): Int = value.sumOf { sInt64(
5381

5482
@InternalRpcApi
5583
public fun WireSize.packedEnum(value: List<Int>): Int = value.sumOf { enum(it) }
84+
85+
@InternalRpcApi
86+
public fun WireSize.packedFloat(value: List<Float>): Int = value.size * 32
87+
88+
@InternalRpcApi
89+
public fun WireSize.packedDouble(value: List<Double>): Int = value.size * 64
90+
91+
@InternalRpcApi
92+
public fun WireSize.packedFixed32(value: List<UInt>): Int = value.size * 32
93+
94+
@InternalRpcApi
95+
public fun WireSize.packedFixed64(value: List<ULong>): Int = value.size * 64
96+
97+
@InternalRpcApi
98+
public fun WireSize.packedSFixed32(value: List<Int>): Int = value.size * 32
99+
100+
@InternalRpcApi
101+
public fun WireSize.packedSFixed64(value: List<Long>): Int = value.size * 64

0 commit comments

Comments
 (0)