Skip to content

Commit aa3921e

Browse files
committed
Some impls
1 parent 12bb242 commit aa3921e

File tree

14 files changed

+301
-66
lines changed

14 files changed

+301
-66
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/GrpcClient.kt

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,35 @@
44

55
package kotlinx.rpc.grpc
66

7-
import io.grpc.stub.AbstractStub
87
import kotlinx.coroutines.CoroutineScope
98
import kotlinx.coroutines.Deferred
109
import kotlinx.coroutines.SupervisorJob
1110
import kotlinx.coroutines.job
1211
import kotlinx.rpc.RpcCall
1312
import kotlinx.rpc.RpcClient
14-
import kotlinx.rpc.descriptor.RpcServiceDescriptor
13+
import kotlinx.rpc.grpc.descriptor.GrpcClientDelegate
14+
import kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor
15+
import kotlinx.rpc.internal.utils.map.ConcurrentHashMap
1516
import kotlin.coroutines.CoroutineContext
1617

1718
public class GrpcClient(private val channel: ManagedChannel) : RpcClient {
1819
override val coroutineContext: CoroutineContext = SupervisorJob()
1920

21+
private val stubs = ConcurrentHashMap<Long, GrpcClientDelegate>()
22+
2023
override suspend fun <T> call(call: RpcCall): T {
21-
val stub = grpcStubByServiceDescriptor(call.descriptor)
22-
return invokeRpcMethodOnGrpcStub(stub, call)
24+
return call.delegate().call(call)
2325
}
2426

25-
private fun grpcStubByServiceDescriptor(descriptor: RpcServiceDescriptor<*>): AbstractStub<*> {
26-
error("Not yet implemented")
27+
override fun <T> callAsync(serviceScope: CoroutineScope, call: RpcCall): Deferred<T> {
28+
return call.delegate().callAsync(call)
2729
}
2830

29-
private suspend fun <T> invokeRpcMethodOnGrpcStub(stub: AbstractStub<*>, call: RpcCall): T {
30-
error("Not yet implemented")
31-
}
31+
private fun RpcCall.delegate(): GrpcClientDelegate {
32+
val grpc = (descriptor as? GrpcServiceDescriptor<*>)
33+
?: error("Service ${descriptor.fqName} is not a gRPC service")
3234

33-
override fun <T> callAsync(
34-
serviceScope: CoroutineScope,
35-
call: RpcCall,
36-
): Deferred<T> {
37-
TODO("Not yet implemented")
35+
return stubs.computeIfAbsent(serviceId) { grpc.delegate.clientProvider(channel) }
3836
}
3937

4038
override fun provideStubContext(serviceId: Long): CoroutineContext {

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/GrpcServer.kt

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

77
import kotlinx.coroutines.SupervisorJob
88
import kotlinx.coroutines.job
9-
import kotlinx.rpc.RemoteService
109
import kotlinx.rpc.RpcServer
10+
import kotlinx.rpc.descriptor.serviceDescriptorOf
11+
import kotlinx.rpc.grpc.annotations.Grpc
12+
import kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor
1113
import kotlinx.rpc.grpc.internal.MutableHandlerRegistry
1214
import kotlinx.rpc.grpc.internal.ServerServiceDefinition
1315
import kotlin.coroutines.CoroutineContext
@@ -29,7 +31,7 @@ public class GrpcServer internal constructor(
2931
override val coroutineContext: CoroutineContext
3032
get() = error("coroutineContext is not available for gRPC server builder")
3133

32-
override fun <Service : RemoteService> registerService(
34+
override fun <@Grpc Service : Any> registerService(
3335
serviceKClass: KClass<Service>,
3436
serviceFactory: (CoroutineContext) -> Service,
3537
) {
@@ -45,12 +47,15 @@ public class GrpcServer internal constructor(
4547
}
4648
}
4749

48-
private fun <Service : RemoteService> getDefinition(
50+
private fun <@Grpc Service : Any> getDefinition(
4951
service: Service,
5052
serviceKClass: KClass<Service>,
5153
): ServerServiceDefinition {
52-
// generated locator
53-
TODO("Not yet implemented")
54+
val descriptor = serviceDescriptorOf<Service>(serviceKClass)
55+
val grpc = (descriptor as? GrpcServiceDescriptor<Service>)
56+
?: error("Service ${descriptor.fqName} is not a gRPC service")
57+
58+
return grpc.delegate.definitionFor(service)
5459
}
5560

5661
internal fun build() {

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/ManagedChannel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ package kotlinx.rpc.grpc
88

99
import kotlin.time.Duration
1010

11+
public expect abstract class ManagedChannelPlatform
12+
1113
public interface ManagedChannel {
1214
public val isShutdown: Boolean
1315
public val isTerminated: Boolean
@@ -16,6 +18,8 @@ public interface ManagedChannel {
1618

1719
public fun shutdown(): ManagedChannel
1820
public fun shutdownNow(): ManagedChannel
21+
22+
public val platformApi: ManagedChannelPlatform
1923
}
2024

2125
public expect abstract class ManagedChannelBuilder<T : ManagedChannelBuilder<T>>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright 2023-2024 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.annotations
6+
7+
import kotlinx.rpc.annotations.Rpc
8+
9+
@Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.TYPE_PARAMETER)
10+
@Rpc
11+
public annotation class Grpc
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2023-2024 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.descriptor
6+
7+
import kotlinx.coroutines.Deferred
8+
import kotlinx.rpc.RpcCall
9+
import kotlinx.rpc.descriptor.RpcServiceDescriptor
10+
import kotlinx.rpc.grpc.ManagedChannel
11+
import kotlinx.rpc.grpc.annotations.Grpc
12+
import kotlinx.rpc.grpc.internal.ServerServiceDefinition
13+
import kotlinx.rpc.internal.utils.ExperimentalRpcApi
14+
15+
@ExperimentalRpcApi
16+
public interface GrpcServiceDescriptor<@Grpc T : Any> : RpcServiceDescriptor<T> {
17+
public val delegate: GrpcDelegate<T>
18+
}
19+
20+
@ExperimentalRpcApi
21+
public interface GrpcDelegate<@Grpc T : Any> {
22+
public fun clientProvider(channel: ManagedChannel): GrpcClientDelegate
23+
24+
public fun definitionFor(impl: T): ServerServiceDefinition
25+
}
26+
27+
@ExperimentalRpcApi
28+
public interface GrpcClientDelegate {
29+
public suspend fun <R> call(rpcCall: RpcCall): R
30+
31+
public fun <R> callAsync(rpcCall: RpcCall): Deferred<R>
32+
}

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/ManagedChannel.jvm.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import kotlinx.coroutines.Dispatchers
1010
import kotlinx.coroutines.withContext
1111
import kotlin.time.Duration
1212

13+
public actual typealias ManagedChannelPlatform = io.grpc.ManagedChannel
14+
1315
public actual typealias ManagedChannelBuilder<T> = io.grpc.ManagedChannelBuilder<T>
1416

1517
public actual fun ManagedChannelBuilder<*>.buildChannel(): ManagedChannel {
@@ -50,4 +52,7 @@ private class JvmManagedChannel(private val channel: io.grpc.ManagedChannel) : M
5052
channel.shutdownNow()
5153
return this
5254
}
55+
56+
override val platformApi: ManagedChannelPlatform
57+
get() = channel
5358
}

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/internal/ServerServiceDefinition.jvm.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@
66

77
package kotlinx.rpc.grpc.internal
88

9-
internal actual typealias ServerServiceDefinition = io.grpc.ServerServiceDefinition
9+
import kotlinx.rpc.internal.utils.InternalRpcApi
10+
11+
@InternalRpcApi
12+
public actual typealias ServerServiceDefinition = io.grpc.ServerServiceDefinition

protobuf-plugin/build.gradle.kts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ tasks.jar {
6161
)
6262
}
6363

64-
val buildDir: String = project.layout.buildDirectory.get().asFile.absolutePath
64+
val buildDirPath: String = project.layout.buildDirectory.get().asFile.absolutePath
6565

6666
protobuf {
6767
protoc {
@@ -70,7 +70,7 @@ protobuf {
7070

7171
plugins {
7272
create("kotlinx-rpc") {
73-
path = "$buildDir/libs/protobuf-plugin-$version.jar"
73+
path = "$buildDirPath/libs/protobuf-plugin-$version.jar"
7474
}
7575

7676
create("grpc") {
@@ -80,27 +80,20 @@ protobuf {
8080
create("grpckt") {
8181
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.3.1:jdk8@jar"
8282
}
83-
84-
create("javalite") {
85-
artifact = "com.google.protobuf:protoc:3.24.1"
86-
}
8783
}
8884

8985
generateProtoTasks {
9086
all().matching { it.isTest }.all {
9187
plugins {
9288
create("kotlinx-rpc") {
93-
option("debugOutput=$buildDir/protobuf-plugin.log")
89+
option("debugOutput=$buildDirPath/protobuf-plugin.log")
9490
option("messageMode=interface")
9591
}
9692
create("grpc")
9793
create("grpckt")
9894
}
9995

10096
builtins {
101-
named("java") {
102-
option("lite")
103-
}
10497
id("kotlin")
10598
}
10699

protobuf-plugin/src/main/kotlin/kotlinx/rpc/protobuf/CodeGenerator.kt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import org.slf4j.Logger
88
import org.slf4j.helpers.NOPLogger
99

1010
data class CodeGenerationParameters(
11-
val messageMode: RPCProtobufPlugin.MessageMode,
11+
val messageMode: RpcProtobufPlugin.MessageMode,
1212
)
1313

1414
open class CodeGenerator(
@@ -71,12 +71,12 @@ open class CodeGenerator(
7171
CodeGenerator(parameters, "$indent$ONE_INDENT", builder, logger).block()
7272
}
7373

74-
private fun scope(prefix: String, block: (CodeGenerator.() -> Unit)? = null) {
74+
internal fun scope(prefix: String, suffix: String = "", block: (CodeGenerator.() -> Unit)? = null) {
7575
addLine(prefix)
76-
scope(block)
76+
scopeWithSuffix(suffix, block)
7777
}
7878

79-
private fun scope(block: (CodeGenerator.() -> Unit)? = null) {
79+
private fun scopeWithSuffix(suffix: String = "", block: (CodeGenerator.() -> Unit)? = null) {
8080
if (block == null) {
8181
newLine()
8282
lastIsDeclaration = true
@@ -94,7 +94,7 @@ open class CodeGenerator(
9494
append(" {")
9595
newLine()
9696
append(nested.build().trimEnd())
97-
addLine("}")
97+
addLine("}$suffix")
9898
newLine()
9999
lastIsDeclaration = true
100100
}
@@ -103,9 +103,26 @@ open class CodeGenerator(
103103
code.lines().forEach { addLine(it) }
104104
}
105105

106+
fun property(
107+
name: String,
108+
modifiers: String = "",
109+
contextReceiver: String = "",
110+
type: String = "",
111+
delegate: Boolean = false,
112+
value: String = "",
113+
block: (CodeGenerator.() -> Unit)? = null,
114+
) {
115+
val modifiersString = if (modifiers.isEmpty()) "" else "$modifiers "
116+
val contextString = if (contextReceiver.isEmpty()) "" else "$contextReceiver."
117+
val typeString = if (type.isEmpty()) "" else ": $type"
118+
val delegateString = if (delegate) " by " else " = "
119+
scope("${modifiersString}val $contextString$name$typeString$delegateString$value", block = block)
120+
}
121+
106122
fun function(
107123
name: String,
108124
modifiers: String = "",
125+
typeParameters: String = "",
109126
args: String = "",
110127
contextReceiver: String = "",
111128
returnType: String = "",
@@ -114,7 +131,8 @@ open class CodeGenerator(
114131
val modifiersString = if (modifiers.isEmpty()) "" else "$modifiers "
115132
val contextString = if (contextReceiver.isEmpty()) "" else "$contextReceiver."
116133
val returnTypeString = if (returnType.isEmpty()) "" else ": $returnType"
117-
scope("${modifiersString}fun $contextString$name($args)$returnTypeString", block)
134+
val typeParametersString = if (typeParameters.isEmpty()) "" else " <$typeParameters>"
135+
scope("${modifiersString}fun$typeParametersString $contextString$name($args)$returnTypeString", block = block)
118136
}
119137

120138
enum class DeclarationType(val strValue: String) {
@@ -217,7 +235,7 @@ open class CodeGenerator(
217235

218236
append(superString)
219237

220-
scope(block)
238+
scopeWithSuffix(block = block)
221239
}
222240

223241
open fun build(): String {

protobuf-plugin/src/main/kotlin/kotlinx/rpc/protobuf/Main.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import com.google.protobuf.compiler.PluginProtos
2626
fun main() {
2727
val inputBytes = System.`in`.readBytes()
2828
val request = PluginProtos.CodeGeneratorRequest.parseFrom(inputBytes)
29-
val plugin = RPCProtobufPlugin()
29+
val plugin = RpcProtobufPlugin()
3030
val output: PluginProtos.CodeGeneratorResponse = plugin.run(request)
3131
output.writeTo(System.out)
3232
}

0 commit comments

Comments
 (0)