diff --git a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcDeclarationScanner.kt b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcDeclarationScanner.kt index 6cb5c3af2..80cdf8620 100644 --- a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcDeclarationScanner.kt +++ b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcDeclarationScanner.kt @@ -4,6 +4,7 @@ package kotlinx.rpc.codegen.extension +import kotlinx.rpc.codegen.common.RpcClassId import kotlinx.rpc.codegen.common.RpcNames import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -11,7 +12,11 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.expressions.IrConst +import org.jetbrains.kotlin.ir.expressions.IrConstKind +import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.util.dumpKotlinLike +import org.jetbrains.kotlin.ir.util.getAnnotation import org.jetbrains.kotlin.ir.util.hasDefaultValue /** @@ -25,6 +30,9 @@ internal object RpcDeclarationScanner { fun scanServiceDeclaration(service: IrClass, ctx: RpcIrContext, logger: MessageCollector): ServiceDeclaration { var stubClass: IrClass? = null + val grpcAnnotation = service.getAnnotation(RpcClassId.grpcAnnotation.asSingleFqName()) + val protoPackage = grpcAnnotation?.arguments?.getOrNull(0)?.asConstString() ?: "" + val declarations = service.declarations.memoryOptimizedMap { declaration -> when (declaration) { is IrSimpleFunction -> { @@ -75,6 +83,7 @@ internal object RpcDeclarationScanner { service = service, stubClass = stubClassNotNull, methods = declarations.filterNotNull(), + protoPackage = protoPackage.trim() ) } } @@ -87,3 +96,7 @@ private fun unsupportedDeclaration(service: IrClass, declaration: IrDeclaration, return null } + +fun IrExpression.asConstString(): String = + (this as? IrConst)?.takeIf { it.kind == IrConstKind.String }?.value as? String + ?: error("Expected IrConst of kind String, got ${dumpKotlinLike()}") diff --git a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcStubGenerator.kt b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcStubGenerator.kt index eaa734485..43bdac58a 100644 --- a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcStubGenerator.kt +++ b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcStubGenerator.kt @@ -18,11 +18,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.symbols.IrValueSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name @@ -39,6 +35,8 @@ private object Stub { private object Descriptor { const val CALLABLE_MAP = "callableMap" const val CALLABLES = "callables" + + // the kotlin class name const val FQ_NAME = "fqName" const val SIMPLE_NAME = "simpleName" const val GET_CALLABLE = "getCallable" @@ -915,7 +913,8 @@ internal class RpcStubGenerator( }.apply { overriddenSymbols = listOf(ctx.properties.rpcServiceDescriptorCallables) - val collectionType = ctx.irBuiltIns.collectionClass.typeWith(ctx.rpcCallable.typeWith(declaration.serviceType)) + val collectionType = + ctx.irBuiltIns.collectionClass.typeWith(ctx.rpcCallable.typeWith(declaration.serviceType)) addGetter { returnType = collectionType @@ -1086,7 +1085,7 @@ internal class RpcStubGenerator( * * ```kotlin * serviceDescriptor( - * name = MyService, // simpleName + * name = my.proto.package.MyService, // $declaration.serviceFqName * methods = methodDescriptorMap.values, // Collection> * schemaDescriptor = null, // for now, only null * ) @@ -1105,7 +1104,7 @@ internal class RpcStubGenerator( }.apply { arguments { values { - +stringConst(declaration.simpleName) + +stringConst(declaration.serviceFqName) +irCallProperty( receiver = IrGetValueImpl( @@ -1130,7 +1129,7 @@ internal class RpcStubGenerator( * // In scope: resolver: MessageCodecResolver * * methodDescriptor<, >( - * fullMethodName = "${descriptor.simpleName}/${callable.name}", + * fullMethodName = "${descriptor.serviceFqName}/${callable.name}", * requestCodec = , * responseCodec = , * type = MethodType., @@ -1185,7 +1184,7 @@ internal class RpcStubGenerator( values { // fullMethodName - +stringConst("${declaration.simpleName}/${callable.name}") + +stringConst("${declaration.serviceFqName}/${callable.name}") // requestCodec +irCodec(requestType, resolver) @@ -1245,7 +1244,7 @@ internal class RpcStubGenerator( val protobufMessage = owner.getAnnotation(ctx.withCodecAnnotation.owner.kotlinFqName) return if (protobufMessage != null) { - val classReference = vsApi{ protobufMessage.argumentsVS }.single() as? IrClassReference + val classReference = vsApi { protobufMessage.argumentsVS }.single() as? IrClassReference ?: error("Expected IrClassReference for ${ctx.withCodecAnnotation.owner.kotlinFqName} parameter") val codec = classReference.classType diff --git a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt index cfd93114d..68fc80eba 100644 --- a/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt +++ b/compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt @@ -17,12 +17,15 @@ class ServiceDeclaration( val service: IrClass, val stubClass: IrClass, val methods: List, + val protoPackage: String, ) { // todo change to extension after KRPC-178 val isGrpc = service.hasAnnotation(RpcClassId.grpcAnnotation) val simpleName = service.kotlinFqName.shortName().asString() val fqName = service.kotlinFqName.asString() + // the name of the service based on the proto file (or @Grpc annotation) + val serviceFqName = if (protoPackage.isNotEmpty()) "$protoPackage.$simpleName" else simpleName val serviceType = service.defaultType sealed interface Callable { diff --git a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcStrictModeClassChecker.kt b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcStrictModeClassChecker.kt index a9bb88cad..5ec65d673 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcStrictModeClassChecker.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcStrictModeClassChecker.kt @@ -10,6 +10,7 @@ import kotlinx.rpc.codegen.checkers.util.functionParametersRecursionCheck import kotlinx.rpc.codegen.common.RpcClassId import kotlinx.rpc.codegen.vsApi import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.descriptors.isAnnotationClass import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0 import org.jetbrains.kotlin.diagnostics.reportOn @@ -26,7 +27,10 @@ object FirRpcStrictModeClassChecker { context: CheckerContext, reporter: DiagnosticReporter, ) { - if (!context.session.predicateBasedProvider.matches(FirRpcPredicates.rpc, declaration)) { + if (!context.session.predicateBasedProvider.matches(FirRpcPredicates.rpc, declaration) + // skip checks for annotation classes + || declaration.classKind.isAnnotationClass + ) { return } @@ -37,7 +41,10 @@ object FirRpcStrictModeClassChecker { } is FirNamedFunctionSymbol -> { - fun reportOn(element: KtSourceElement?, checker: FirRpcStrictModeDiagnostics.() -> KtDiagnosticFactory0) { + fun reportOn( + element: KtSourceElement?, + checker: FirRpcStrictModeDiagnostics.() -> KtDiagnosticFactory0, + ) { reporter.reportOn(element, FirRpcStrictModeDiagnostics.checker(), context) } diff --git a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/Status.kt b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/Status.kt index 65cf7a054..66e452cb7 100644 --- a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/Status.kt +++ b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/Status.kt @@ -32,7 +32,7 @@ public expect class Status { public expect fun Status(code: StatusCode, description: String? = null, cause: Throwable? = null): Status -public expect val Status.code: StatusCode +public expect val Status.statusCode: StatusCode public enum class StatusCode(public val value: Int) { OK(0), diff --git a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/annotations/Grpc.kt b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/annotations/Grpc.kt index d3379c9e0..3b4e378ee 100644 --- a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/annotations/Grpc.kt +++ b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/annotations/Grpc.kt @@ -5,11 +5,10 @@ package kotlinx.rpc.grpc.annotations import kotlinx.rpc.annotations.Rpc -import kotlinx.rpc.internal.utils.InternalRpcApi /** * Annotation used for marking gRPC services. */ @Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.TYPE_PARAMETER) @Rpc -public annotation class Grpc +public annotation class Grpc(val protoPackage: String = "") diff --git a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/suspendClientCalls.kt b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/suspendClientCalls.kt index 1578c9277..39635bdc9 100644 --- a/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/suspendClientCalls.kt +++ b/grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/suspendClientCalls.kt @@ -201,7 +201,7 @@ private fun channelResponseListener( }, onClose = { status: Status, trailers: GrpcTrailers -> val cause = when { - status.code == StatusCode.OK -> null + status.statusCode == StatusCode.OK -> null status.getCause() is CancellationException -> status.getCause() else -> StatusException(status, trailers) } diff --git a/grpc/grpc-core/src/nativeTest/kotlin/kotlinx/rpc/grpc/internal/CoreTest.kt b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/CoreClientTest.kt similarity index 56% rename from grpc/grpc-core/src/nativeTest/kotlin/kotlinx/rpc/grpc/internal/CoreTest.kt rename to grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/CoreClientTest.kt index 4db3e63aa..399b9c5ac 100644 --- a/grpc/grpc-core/src/nativeTest/kotlin/kotlinx/rpc/grpc/internal/CoreTest.kt +++ b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/CoreClientTest.kt @@ -1,34 +1,32 @@ /* * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ -@file:OptIn(ExperimentalForeignApi::class, ExperimentalStdlibApi::class, ExperimentalNativeApi::class) - -package kotlinx.rpc.grpc.internal - -import HelloReply -import HelloReplyInternal -import HelloRequest -import HelloRequestInternal -import grpc.examples.echo.EchoRequest -import grpc.examples.echo.EchoRequestInternal -import grpc.examples.echo.EchoResponseInternal -import grpc.examples.echo.invoke -import invoke -import kotlinx.cinterop.ExperimentalForeignApi +package kotlinx.rpc.grpc.test + import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.coroutines.withTimeout import kotlinx.rpc.grpc.* -import kotlin.experimental.ExperimentalNativeApi +import kotlinx.rpc.grpc.internal.* +import kotlinx.rpc.registerService import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFails import kotlin.test.assertFailsWith -import kotlin.test.assertTrue +import kotlin.time.Duration + +private const val PORT = 50051 -class GrpcCoreTest { +/** + * Client tests that use lower level API directly to test that it behaves correctly. + * Before executing the tests run [GreeterServiceImpl.runServer] on JVM. + */ +// TODO: Start external service server automatically (KRPC-208) +class GrpcCoreClientTest { - private fun descriptorFor(fullName: String = "helloworld.Greeter/SayHello"): MethodDescriptor = + private fun descriptorFor(fullName: String = "kotlinx.rpc.grpc.test.GreeterService/SayHello"): MethodDescriptor = methodDescriptor( fullMethodName = fullName, requestCodec = HelloRequestInternal.CODEC, @@ -40,10 +38,10 @@ class GrpcCoreTest { sampledToLocalTracing = true, ) - private fun ManagedChannel.newHelloCall(fullName: String = "helloworld.Greeter/SayHello"): ClientCall = - platformApi.newCall(descriptorFor(fullName), GrpcCallOptions()) + private fun ManagedChannel.newHelloCall(fullName: String = "kotlinx.rpc.grpc.test.GreeterService/SayHello"): ClientCall = + platformApi.newCall(descriptorFor(fullName), GrpcDefaultCallOptions) - private fun createChannel(): ManagedChannel = ManagedChannelBuilder("localhost:50051") + private fun createChannel(): ManagedChannel = ManagedChannelBuilder("localhost:$PORT") .usePlaintext() .buildChannel() @@ -66,15 +64,10 @@ class GrpcCoreTest { val statusDeferred = CompletableDeferred() val replyDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onMessage(message: HelloReply) { - replyDeferred.complete(message) - } - - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onMessage = { replyDeferred.complete(it) }, + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) call.sendMessage(req) @@ -84,41 +77,22 @@ class GrpcCoreTest { runBlocking { withTimeout(10000) { val status = statusDeferred.await() - val reply = replyDeferred.await() assertEquals(StatusCode.OK, status.statusCode) + val reply = replyDeferred.await() assertEquals("Hello world", reply.message) } } shutdownAndWait(channel) } - @Test - fun sendMessage_beforeStart_throws() { - val channel = createChannel() - val call = channel.newHelloCall() - val req = helloReq() - assertFailsWith { call.sendMessage(req) } - shutdownAndWait(channel) - } - - @Test - fun request_beforeStart_throws() { - val channel = createChannel() - val call = channel.newHelloCall() - assertFailsWith { call.request(1) } - shutdownAndWait(channel) - } - @Test fun start_twice_throws() { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) assertFailsWith { call.start(listener, GrpcTrailers()) } // cancel to finish the call quickly @@ -133,11 +107,9 @@ class GrpcCoreTest { val call = channel.newHelloCall() val req = helloReq() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) call.halfClose() assertFailsWith { call.sendMessage(req) } @@ -148,17 +120,15 @@ class GrpcCoreTest { } @Test - fun request_zero_throws() { + fun request_negative_throws() { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) - assertFailsWith { call.request(0) } + assertFails { call.request(-1) } call.cancel("cleanup", null) runBlocking { withTimeout(5000) { statusDeferred.await() } } shutdownAndWait(channel) @@ -169,11 +139,9 @@ class GrpcCoreTest { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) call.cancel("user cancel", null) runBlocking { @@ -188,13 +156,11 @@ class GrpcCoreTest { @Test fun invalid_method_returnsNonOkStatus() { val channel = createChannel() - val call = channel.newHelloCall("/helloworld.Greeter/NoSuchMethod") + val call = channel.newHelloCall("kotlinx.rpc.grpc.test.Greeter/NoSuchMethod") val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) call.sendMessage(helloReq()) @@ -203,7 +169,7 @@ class GrpcCoreTest { runBlocking { withTimeout(10000) { val status = statusDeferred.await() - assertTrue(status.statusCode != StatusCode.OK) + assertEquals(StatusCode.UNIMPLEMENTED, status.statusCode) } } shutdownAndWait(channel) @@ -215,11 +181,9 @@ class GrpcCoreTest { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) assertFailsWith { try { call.start(listener, GrpcTrailers()) @@ -236,13 +200,12 @@ class GrpcCoreTest { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) channel.shutdown() + runBlocking { channel.awaitTermination() } call.start(listener, GrpcTrailers()) call.sendMessage(helloReq()) call.halfClose() @@ -261,11 +224,9 @@ class GrpcCoreTest { val channel = createChannel() val call = channel.newHelloCall() val statusDeferred = CompletableDeferred() - val listener = object : ClientCall.Listener() { - override fun onClose(status: Status, trailers: GrpcTrailers) { - statusDeferred.complete(status) - } - } + val listener = createClientCallListener( + onClose = { status, _ -> statusDeferred.complete(status) } + ) call.start(listener, GrpcTrailers()) // set timeout on the server to 1000 ms, to simulate a long-running call @@ -278,41 +239,53 @@ class GrpcCoreTest { channel.shutdownNow() withTimeout(10000) { val status = statusDeferred.await() - assertEquals(StatusCode.CANCELLED, status.statusCode) + assertEquals(StatusCode.UNAVAILABLE, status.statusCode) } } } +} - @Test - fun unaryCallTest() = runBlocking { - val ch = createChannel() - val desc = descriptorFor() - val req = helloReq() - repeat(1000) { - val res = unaryRpc(ch.platformApi, desc, req) - assertEquals("Hello world", res.message) +class GreeterServiceImpl : GreeterService { + + override suspend fun SayHello(message: HelloRequest): HelloReply { + delay(message.timeout?.toLong() ?: 0) + return HelloReply { + this.message = "Hello ${message.name}" } } - private fun echoDescriptor(methodName: String, type: MethodType) = - methodDescriptor( - fullMethodName = "grpc.examples.echo.Echo/$methodName", - requestCodec = EchoRequestInternal.CODEC, - responseCodec = EchoResponseInternal.CODEC, - type = type, - schemaDescriptor = Unit, - idempotent = true, - safe = true, - sampledToLocalTracing = true, + /** + * Run this on JVM before executing tests. + */ + @Test + fun runServer() = runTest(timeout = Duration.INFINITE) { + val server = GrpcServer( + port = PORT, + builder = { registerService { GreeterServiceImpl() } } ) - @Test - fun unaryEchoTest() = runBlocking { - val ch = createChannel() - val desc = echoDescriptor("UnaryEcho", MethodType.UNARY) - val req = EchoRequest { message = "Echoooo" } - unaryRpc(ch.platformApi, desc, req) - return@runBlocking + try { + server.start() + println("Server started") + server.awaitTermination() + } finally { + server.shutdown() + server.awaitTermination() + } } -} \ No newline at end of file + +} + + +private fun createClientCallListener( + onHeaders: (headers: GrpcTrailers) -> Unit = {}, + onMessage: (message: T) -> Unit = {}, + onClose: (status: Status, trailers: GrpcTrailers) -> Unit = { _, _ -> }, + onReady: () -> Unit = {}, +) = clientCallListener( + onHeaders = onHeaders, + onMessage = onMessage, + onClose = onClose, + onReady = onReady, +) \ No newline at end of file diff --git a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/RawClientTest.kt b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/RawClientTest.kt index 18743bdac..f50105f5a 100644 --- a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/RawClientTest.kt +++ b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/RawClientTest.kt @@ -5,18 +5,27 @@ package kotlinx.rpc.grpc.test import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.toList import kotlinx.coroutines.test.runTest +import kotlinx.rpc.grpc.GrpcServer import kotlinx.rpc.grpc.ManagedChannelBuilder import kotlinx.rpc.grpc.buildChannel import kotlinx.rpc.grpc.internal.* +import kotlinx.rpc.registerService import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration + +private const val PORT = 50051 /** * Tests for JVM and Native clients. + * + * To run the tests you must first start the server with the [EchoServiceImpl.runServer] method on JVM. */ -// TODO: Start echo service server automatically +// TODO: Start external service server automatically (KRPC-208) class RawClientTest { @Test @@ -86,7 +95,7 @@ class RawClientTest { .buildChannel() val methodDescriptor = methodDescriptor( - fullMethodName = "grpc.examples.echo.Echo/$methodName", + fullMethodName = "kotlinx.rpc.grpc.test.EchoService/$methodName", requestCodec = EchoRequestInternal.CODEC, responseCodec = EchoResponseInternal.CODEC, type = type, @@ -103,4 +112,56 @@ class RawClientTest { channel.awaitTermination() } } -} \ No newline at end of file +} + + +class EchoServiceImpl : EchoService { + + override suspend fun UnaryEcho(message: EchoRequest): EchoResponse { + delay(message.timeout.toLong()) + return EchoResponse { this.message = message.message } + } + + override fun ServerStreamingEcho(message: EchoRequest): Flow { + val count = message.serverStreamReps ?: 5u + return flow { + repeat(count.toInt()) { + emit(EchoResponse { this.message = message.message }) + } + } + } + + override suspend fun ClientStreamingEcho(message: Flow): EchoResponse { + val result = message.toList().joinToString(", ") { it.message } + return EchoResponse { this.message = result } + } + + override fun BidirectionalStreamingEcho(message: Flow): Flow { + return flow { + message.collect { + emit(EchoResponse { this.message = it.message }) + } + } + } + + + /** + * Run this on JVM before executing tests. + */ + @Test + fun runServer() = runTest(timeout = Duration.INFINITE) { + val server = GrpcServer( + port = PORT, + builder = { registerService { EchoServiceImpl() } } + ) + + try { + server.start() + println("Server started") + server.awaitTermination() + } finally { + server.shutdown() + server.awaitTermination() + } + } +} diff --git a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/GrpcProtoTest.kt b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/GrpcProtoTest.kt index 88e370dad..735f6f4f7 100644 --- a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/GrpcProtoTest.kt +++ b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/GrpcProtoTest.kt @@ -16,13 +16,13 @@ abstract class GrpcProtoTest { abstract fun RpcServer.registerServices() - protected fun runGrpcTest(test: suspend (GrpcClient) -> Unit, ) = runTest { + protected fun runGrpcTest(test: suspend (GrpcClient) -> Unit) = runTest { serverMutex.withLock { - val grpcClient = GrpcClient("localhost", 8080) { + val grpcClient = GrpcClient("localhost", PORT) { usePlaintext() } - val grpcServer = GrpcServer(8080, builder = { + val grpcServer = GrpcServer(PORT, builder = { registerServices() }) @@ -34,4 +34,8 @@ abstract class GrpcProtoTest { grpcClient.awaitTermination() } } + + companion object { + const val PORT = 8080 + } } diff --git a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/JavaPackageOptionTest.kt b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/JavaPackageOptionTest.kt new file mode 100644 index 000000000..1c7dd3017 --- /dev/null +++ b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/proto/JavaPackageOptionTest.kt @@ -0,0 +1,73 @@ +/* + * 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.grpc.test.proto + +import com.google.protobuf.kotlin.Empty +import com.google.protobuf.kotlin.EmptyInternal +import com.google.protobuf.kotlin.invoke +import kotlinx.rpc.RpcServer +import kotlinx.rpc.grpc.ManagedChannelBuilder +import kotlinx.rpc.grpc.buildChannel +import kotlinx.rpc.grpc.internal.MethodType +import kotlinx.rpc.grpc.internal.methodDescriptor +import kotlinx.rpc.grpc.internal.unaryRpc +import kotlinx.rpc.grpc.test.withJavaPkg.TheService +import kotlinx.rpc.registerService +import kotlinx.rpc.withService +import kotlin.test.Test + +class TheServiceImpl : TheService { + override suspend fun TheMethod(message: Empty): Empty { + return Empty {} + } +} + +/** + * Tests proto service with java_package that differs from the `package` name. + * While the generated Kotlin sources should be generated in the java_package, + * the service name must use the `package` name. + */ +class JavaPackageOptionTest : GrpcProtoTest() { + + /** + * Tests that the generated service descriptor uses the `package` name. + */ + @Test + fun testJavaPackageOptionRaw() = runGrpcTest { _ -> + val channel = ManagedChannelBuilder("localhost", PORT) + .usePlaintext() + .buildChannel() + + val descriptor = methodDescriptor( + fullMethodName = "protopackage.TheService/TheMethod", + requestCodec = EmptyInternal.CODEC, + responseCodec = EmptyInternal.CODEC, + type = MethodType.UNARY, + schemaDescriptor = Unit, + idempotent = true, + safe = true, + sampledToLocalTracing = true, + ) + + unaryRpc(channel.platformApi, descriptor, Empty {}) + + // just reach this without an error + } + + /** + * Tests that the generated client uses the `package` name to call the service. + */ + @Test + fun testJavaPackageOptionStub() = runGrpcTest { client -> + val service = client.withService() + service.TheMethod(Empty {}) + + // just reach this without an error + } + + override fun RpcServer.registerServices() { + registerService { TheServiceImpl() } + } +} \ No newline at end of file diff --git a/grpc/grpc-core/src/commonTest/proto/echo_grpc.proto b/grpc/grpc-core/src/commonTest/proto/echo_grpc.proto index 4c960d90b..6e14c21e4 100644 --- a/grpc/grpc-core/src/commonTest/proto/echo_grpc.proto +++ b/grpc/grpc-core/src/commonTest/proto/echo_grpc.proto @@ -1,10 +1,12 @@ syntax = "proto3"; -package grpc.examples.echo; +package kotlinx.rpc.grpc.test; // EchoRequest is the request for echo. message EchoRequest { string message = 1; + uint32 timeout = 2; + optional uint32 serverStreamReps = 3; } // EchoResponse is the response for echo. @@ -13,7 +15,7 @@ message EchoResponse { } // Echo is the echo service. -service Echo { +service EchoService { // UnaryEcho is unary echo. rpc UnaryEcho(EchoRequest) returns (EchoResponse) {} // ServerStreamingEcho is server side streaming. diff --git a/grpc/grpc-core/src/commonTest/proto/helloworld.proto b/grpc/grpc-core/src/commonTest/proto/helloworld_grpc.proto similarity index 58% rename from grpc/grpc-core/src/commonTest/proto/helloworld.proto rename to grpc/grpc-core/src/commonTest/proto/helloworld_grpc.proto index f3f815255..0a2dc9198 100644 --- a/grpc/grpc-core/src/commonTest/proto/helloworld.proto +++ b/grpc/grpc-core/src/commonTest/proto/helloworld_grpc.proto @@ -1,5 +1,6 @@ syntax = "proto3"; +package kotlinx.rpc.grpc.test; // The request message containing the user's name. message HelloRequest { @@ -12,3 +13,9 @@ message HelloRequest { message HelloReply { string message = 1; } + +// The greeting service definition. +service GreeterService { + // Sends a greeting + rpc SayHello(HelloRequest) returns (HelloReply) {} +} diff --git a/grpc/grpc-core/src/commonTest/proto/with_java_pkg_grpc.proto b/grpc/grpc-core/src/commonTest/proto/with_java_pkg_grpc.proto new file mode 100644 index 000000000..08b99338a --- /dev/null +++ b/grpc/grpc-core/src/commonTest/proto/with_java_pkg_grpc.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "google/protobuf/empty.proto"; + +// the package the service interface should be written to +option java_package = "kotlinx.rpc.grpc.test.withJavaPkg"; + +// the proto package used for the service's full name +package protopackage; + +service TheService { + rpc TheMethod(google.protobuf.Empty) returns (google.protobuf.Empty) {}; +} \ No newline at end of file diff --git a/grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/Status.jvm.kt b/grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/Status.jvm.kt index 888aae224..de395c876 100644 --- a/grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/Status.jvm.kt +++ b/grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/Status.jvm.kt @@ -30,7 +30,7 @@ internal fun StatusCode.toJvm(): io.grpc.Status.Code { public actual typealias Status = io.grpc.Status -public actual val Status.code: StatusCode +public actual val Status.statusCode: StatusCode get() = when (this.code) { io.grpc.Status.Code.OK -> StatusCode.OK io.grpc.Status.Code.CANCELLED -> StatusCode.CANCELLED diff --git a/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/Status.native.kt b/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/Status.native.kt index b097226c7..1f14bb606 100644 --- a/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/Status.native.kt +++ b/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/Status.native.kt @@ -7,14 +7,14 @@ package kotlinx.rpc.grpc public actual class Status internal constructor( private val description: String?, internal val statusCode: StatusCode, - private val cause: Throwable? + private val cause: Throwable?, ) { public actual fun getDescription(): String? = description public actual fun getCause(): Throwable? = cause } -public actual val Status.code: StatusCode +public actual val Status.statusCode: StatusCode get() = this.statusCode public actual fun Status( diff --git a/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/NativeClientCall.kt b/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/NativeClientCall.kt index 0cf37653a..d77bd9fbc 100644 --- a/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/NativeClientCall.kt +++ b/grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/NativeClientCall.kt @@ -38,7 +38,7 @@ internal class NativeClientCall( callJob.invokeOnCompletion { when (it) { is CancellationException -> { - cancelInternal(grpc_status_code.GRPC_STATUS_CANCELLED, "Call got cancelled.") + cancelInternal(grpc_status_code.GRPC_STATUS_UNAVAILABLE, "Channel shutdownNow invoked") } is Throwable -> { diff --git a/protoc-gen/grpc/src/main/kotlin/kotlinx/rpc/protoc/gen/grpc/ModelToGrpcKotlinCommonGenerator.kt b/protoc-gen/grpc/src/main/kotlin/kotlinx/rpc/protoc/gen/grpc/ModelToGrpcKotlinCommonGenerator.kt index d2a62b904..4ee6d63fa 100644 --- a/protoc-gen/grpc/src/main/kotlin/kotlinx/rpc/protoc/gen/grpc/ModelToGrpcKotlinCommonGenerator.kt +++ b/protoc-gen/grpc/src/main/kotlin/kotlinx/rpc/protoc/gen/grpc/ModelToGrpcKotlinCommonGenerator.kt @@ -28,10 +28,13 @@ class ModelToGrpcKotlinCommonGenerator( @Suppress("detekt.LongMethod") private fun CodeGenerator.generatePublicService(service: ServiceDeclaration) { + val pkg = service.dec.file.`package`.orEmpty() + val annotationParams = if (pkg.isNotEmpty()) """(protoPackage = "$pkg")""" else "" + clazz( name = service.name.simpleName, declarationType = CodeGenerator.DeclarationType.Interface, - annotations = listOf("@kotlinx.rpc.grpc.annotations.Grpc") + annotations = listOf("@kotlinx.rpc.grpc.annotations.Grpc$annotationParams") ) { service.methods.forEach { method -> val inputType = method.inputType diff --git a/tests/compiler-plugin-tests/src/main/kotlin/kotlinx/rpc/codegen/test/Grpc.kt b/tests/compiler-plugin-tests/src/main/kotlin/kotlinx/rpc/codegen/test/Grpc.kt index 80f1079b7..40d0a1725 100644 --- a/tests/compiler-plugin-tests/src/main/kotlin/kotlinx/rpc/codegen/test/Grpc.kt +++ b/tests/compiler-plugin-tests/src/main/kotlin/kotlinx/rpc/codegen/test/Grpc.kt @@ -18,6 +18,7 @@ import kotlin.reflect.KType * To check in methods: * ``` * bareMethodName + * fullMethodName * type * serviceName * isSafe @@ -43,6 +44,7 @@ inline fun <@Grpc reified T : Any> grpcDelegate(): GrpcServiceDelegate { fun MethodDescriptor<*, *>.checkMethod( expectedMethodName: String, + expectedFullMethodName: String, expectedMethodType: MethodDescriptor.MethodType, expectedServiceName: String, expectedIsSafe: Boolean = true, @@ -51,6 +53,7 @@ fun MethodDescriptor<*, *>.checkMethod( ): String? { return when { bareMethodName != expectedMethodName -> "wrong bareMethodName: $bareMethodName" + fullMethodName != expectedFullMethodName -> "wrong bareMethodName: $fullMethodName" type != expectedMethodType -> "wrong type: $type" serviceName != expectedServiceName -> "wrong service name: $fullMethodName" isSafe != expectedIsSafe -> "wrong isSafe: $isSafe" diff --git a/tests/compiler-plugin-tests/src/testData/box/grpc.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/grpc.fir.ir.txt index 9c9f8c13e..818636e81 100644 --- a/tests/compiler-plugin-tests/src/testData/box/grpc.fir.ir.txt +++ b/tests/compiler-plugin-tests/src/testData/box/grpc.fir.ir.txt @@ -71,7 +71,7 @@ FILE fqName: fileName:/grpc.kt public open fun toString (): kotlin.String declared in kotlin.Any CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlin.Any] annotations: - Grpc + Grpc(protoPackage = ) thisReceiver: VALUE_PARAMETER INSTANCE_RECEIVER kind:DispatchReceiver name: type:.BoxService CLASS GENERATED[kotlinx.rpc.codegen.RpcGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService] thisReceiver: VALUE_PARAMETER INSTANCE_RECEIVER kind:DispatchReceiver name: type:.BoxService.$rpcServiceStub @@ -748,6 +748,257 @@ FILE fqName: fileName:/grpc.kt VALUE_PARAMETER kind:Regular name:value index:1 type:kotlin.String FUN name:unit visibility:public modality:ABSTRACT returnType:kotlin.Unit [suspend] VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.BoxService + CLASS INTERFACE name:ProtoPkgService modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + annotations: + Grpc(protoPackage = "my.proto.package") + thisReceiver: VALUE_PARAMETER INSTANCE_RECEIVER kind:DispatchReceiver name: type:.ProtoPkgService + CLASS GENERATED[kotlinx.rpc.codegen.RpcGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.ProtoPkgService] + thisReceiver: VALUE_PARAMETER INSTANCE_RECEIVER kind:DispatchReceiver name: type:.ProtoPkgService.$rpcServiceStub + PROPERTY name:__rpc_stub_id visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:__rpc_stub_id type:kotlin.Long visibility:private [final] + EXPRESSION_BODY + GET_VAR '__rpc_stub_id: kotlin.Long declared in .ProtoPkgService.$rpcServiceStub.' type=kotlin.Long origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL returnType:kotlin.Long + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub + correspondingProperty: PROPERTY name:__rpc_stub_id visibility:private modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlin.Long declared in .ProtoPkgService.$rpcServiceStub' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:__rpc_stub_id type:kotlin.Long visibility:private [final]' type=kotlin.Long origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub declared in .ProtoPkgService.$rpcServiceStub.' type=.ProtoPkgService.$rpcServiceStub origin=null + PROPERTY name:__rpc_client visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:__rpc_client type:kotlinx.rpc.RpcClient visibility:private [final] + EXPRESSION_BODY + GET_VAR '__rpc_client: kotlinx.rpc.RpcClient declared in .ProtoPkgService.$rpcServiceStub.' type=kotlinx.rpc.RpcClient origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL returnType:kotlinx.rpc.RpcClient + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub + correspondingProperty: PROPERTY name:__rpc_client visibility:private modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlinx.rpc.RpcClient declared in .ProtoPkgService.$rpcServiceStub' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:__rpc_client type:kotlinx.rpc.RpcClient visibility:private [final]' type=kotlinx.rpc.RpcClient origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub declared in .ProtoPkgService.$rpcServiceStub.' type=.ProtoPkgService.$rpcServiceStub origin=null + CLASS GENERATED[kotlinx.rpc.codegen.FirRpcServiceStubCompanionObject] OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlinx.rpc.descriptor.RpcServiceDescriptor<.ProtoPkgService>; kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor<.ProtoPkgService>] + thisReceiver: VALUE_PARAMETER INSTANCE_RECEIVER kind:DispatchReceiver name: type:.ProtoPkgService.$rpcServiceStub.Companion + PROPERTY name:simpleName visibility:public modality:FINAL [val] + overridden: + public abstract simpleName: kotlin.String declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FIELD PROPERTY_BACKING_FIELD name:simpleName type:kotlin.String visibility:private [final] + EXPRESSION_BODY + CONST String type=kotlin.String value="ProtoPkgService" + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL returnType:kotlin.String + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + correspondingProperty: PROPERTY name:simpleName visibility:public modality:FINAL [val] + overridden: + public abstract fun (): kotlin.String declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .ProtoPkgService.$rpcServiceStub.Companion' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:simpleName type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + PROPERTY name:fqName visibility:public modality:FINAL [val] + overridden: + public abstract fqName: kotlin.String declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FIELD PROPERTY_BACKING_FIELD name:fqName type:kotlin.String visibility:private [final] + EXPRESSION_BODY + CONST String type=kotlin.String value="ProtoPkgService" + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL returnType:kotlin.String + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + correspondingProperty: PROPERTY name:fqName visibility:public modality:FINAL [val] + overridden: + public abstract fun (): kotlin.String declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .ProtoPkgService.$rpcServiceStub.Companion' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:fqName type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + PROPERTY name:unitInvokator visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:unitInvokator type:kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> visibility:private [final] + EXPRESSION_BODY + TYPE_OP type=kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> origin=SAM_CONVERSION typeOperand=kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> + FUN_EXPR type=kotlin.coroutines.SuspendFunction2<.ProtoPkgService, kotlin.Array, kotlin.Any?> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Any? [suspend] + VALUE_PARAMETER kind:Regular name:service index:0 type:.ProtoPkgService + VALUE_PARAMETER kind:Regular name:arguments index:1 type:kotlin.Array + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (service: .ProtoPkgService, arguments: kotlin.Array): kotlin.Any? declared in .ProtoPkgService.$rpcServiceStub.Companion.unitInvokator' + CALL 'public abstract fun unit (): kotlin.Unit declared in .ProtoPkgService' type=kotlin.Unit origin=null + ARG : GET_VAR 'service: .ProtoPkgService declared in .ProtoPkgService.$rpcServiceStub.Companion.unitInvokator.' type=.ProtoPkgService origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL returnType:kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + correspondingProperty: PROPERTY name:unitInvokator visibility:private modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> declared in .ProtoPkgService.$rpcServiceStub.Companion' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:unitInvokator type:kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> visibility:private [final]' type=kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + PROPERTY name:callableMap visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:callableMap type:kotlin.collections.Map.ProtoPkgService>> visibility:private [final] + EXPRESSION_BODY + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections' type=kotlin.collections.Map.ProtoPkgService>> origin=null + TYPE_ARG K: kotlin.String + TYPE_ARG V: kotlinx.rpc.descriptor.RpcCallable<.ProtoPkgService> + ARG pairs: VARARG type=kotlin.Array.ProtoPkgService>>> varargElementType=kotlin.Pair.ProtoPkgService>> + CALL 'public final fun to (: A of kotlin.to, that: B of kotlin.to): kotlin.Pair declared in kotlin' type=kotlin.Pair.ProtoPkgService>> origin=null + TYPE_ARG A: kotlin.String + TYPE_ARG B: kotlinx.rpc.descriptor.RpcCallable<.ProtoPkgService> + ARG : CONST String type=kotlin.String value="unit" + ARG that: CONSTRUCTOR_CALL 'public constructor (name: kotlin.String, returnType: kotlinx.rpc.descriptor.RpcType, invokator: kotlinx.rpc.descriptor.RpcInvokator, parameters: kotlin.Array) declared in kotlinx.rpc.descriptor.RpcCallableDefault' type=kotlinx.rpc.descriptor.RpcCallable<.ProtoPkgService> origin=null + TYPE_ARG Service: .ProtoPkgService + ARG name: CONST String type=kotlin.String value="unit" + ARG returnType: CONSTRUCTOR_CALL 'public constructor (kType: kotlin.reflect.KType, annotations: kotlin.collections.List) declared in kotlinx.rpc.descriptor.RpcTypeDefault' type=kotlinx.rpc.descriptor.RpcType origin=null + ARG kType: CALL 'public final fun typeOf (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null + TYPE_ARG T: kotlin.Unit + ARG annotations: CALL 'public final fun emptyList (): kotlin.collections.List declared in kotlin.collections' type=kotlin.collections.List origin=null + TYPE_ARG T: kotlin.Annotation + ARG invokator: CALL 'private final fun (): kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> declared in .ProtoPkgService.$rpcServiceStub.Companion' type=kotlinx.rpc.descriptor.RpcInvokator.UnaryResponse<.ProtoPkgService> origin=GET_PROPERTY + ARG : GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + ARG parameters: CALL 'public final fun emptyArray (): kotlin.Array declared in kotlin' type=kotlin.Array origin=null + TYPE_ARG T: kotlinx.rpc.descriptor.RpcParameter + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL returnType:kotlin.collections.Map.ProtoPkgService>> + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + correspondingProperty: PROPERTY name:callableMap visibility:private modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlin.collections.Map.ProtoPkgService>> declared in .ProtoPkgService.$rpcServiceStub.Companion' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:callableMap type:kotlin.collections.Map.ProtoPkgService>> visibility:private [final]' type=kotlin.collections.Map.ProtoPkgService>> origin=null + receiver: GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + CONSTRUCTOR visibility:private returnType:.ProtoPkgService.$rpcServiceStub.Companion [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS GENERATED[kotlinx.rpc.codegen.FirRpcServiceStubCompanionObject] OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlinx.rpc.descriptor.RpcServiceDescriptor<.ProtoPkgService>; kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor<.ProtoPkgService>]' type=kotlin.Unit + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN returnType:kotlin.Boolean [fake_override,operator] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + VALUE_PARAMETER kind:Regular name:other index:1 type:kotlin.Any? + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN returnType:kotlin.Int [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN returnType:kotlin.String [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun toString (): kotlin.String declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FUN name:createInstance visibility:public modality:OPEN returnType:.ProtoPkgService + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + VALUE_PARAMETER kind:Regular name:serviceId index:1 type:kotlin.Long + VALUE_PARAMETER kind:Regular name:client index:2 type:kotlinx.rpc.RpcClient + overridden: + public abstract fun createInstance (serviceId: kotlin.Long, client: kotlinx.rpc.RpcClient): Service of kotlinx.rpc.descriptor.RpcServiceDescriptor declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun createInstance (serviceId: kotlin.Long, client: kotlinx.rpc.RpcClient): .ProtoPkgService declared in .ProtoPkgService.$rpcServiceStub.Companion' + CONSTRUCTOR_CALL 'public constructor (__rpc_stub_id: kotlin.Long, __rpc_client: kotlinx.rpc.RpcClient) declared in .ProtoPkgService.$rpcServiceStub' type=.ProtoPkgService.$rpcServiceStub origin=null + ARG __rpc_stub_id: GET_VAR 'serviceId: kotlin.Long declared in .ProtoPkgService.$rpcServiceStub.Companion.createInstance' type=kotlin.Long origin=null + ARG __rpc_client: GET_VAR 'client: kotlinx.rpc.RpcClient declared in .ProtoPkgService.$rpcServiceStub.Companion.createInstance' type=kotlinx.rpc.RpcClient origin=null + FUN name:delegate visibility:public modality:FINAL returnType:kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + VALUE_PARAMETER kind:Regular name:resolver index:1 type:kotlinx.rpc.grpc.codec.MessageCodecResolver + overridden: + public abstract fun delegate (resolver: kotlinx.rpc.grpc.codec.MessageCodecResolver): kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.collections.Map> [val] + CALL 'public final fun mapOf (vararg pairs: kotlin.Pair): kotlin.collections.Map declared in kotlin.collections' type=kotlin.collections.Map> origin=null + TYPE_ARG K: kotlin.String + TYPE_ARG V: io.grpc.MethodDescriptor<*, *> + ARG pairs: VARARG type=kotlin.Array>> varargElementType=kotlin.Pair> + CALL 'public final fun to (: A of kotlin.to, that: B of kotlin.to): kotlin.Pair declared in kotlin' type=kotlin.Pair> origin=null + TYPE_ARG A: kotlin.String + TYPE_ARG B: io.grpc.MethodDescriptor<*, *> + ARG : CONST String type=kotlin.String value="unit" + ARG that: CALL 'public final fun methodDescriptor (fullMethodName: kotlin.String, requestCodec: kotlinx.rpc.grpc.codec.MessageCodec, responseCodec: kotlinx.rpc.grpc.codec.MessageCodec, type: kotlinx.rpc.grpc.internal.MethodType, schemaDescriptor: kotlin.Any?, idempotent: kotlin.Boolean, safe: kotlin.Boolean, sampledToLocalTracing: kotlin.Boolean): io.grpc.MethodDescriptor declared in kotlinx.rpc.grpc.internal' type=io.grpc.MethodDescriptor origin=null + TYPE_ARG Request: kotlin.Unit + TYPE_ARG Response: kotlin.Unit + ARG fullMethodName: CONST String type=kotlin.String value="my.proto.package.ProtoPkgService/unit" + ARG requestCodec: CALL 'public abstract fun resolveOrNull (kType: kotlin.reflect.KType): kotlinx.rpc.grpc.codec.MessageCodec<*>? declared in kotlinx.rpc.grpc.codec.MessageCodecResolver' type=kotlinx.rpc.grpc.codec.MessageCodec origin=null + ARG : GET_VAR 'resolver: kotlinx.rpc.grpc.codec.MessageCodecResolver declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodecResolver origin=null + ARG kType: CALL 'public final fun typeOf (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null + TYPE_ARG T: kotlin.Unit + ARG responseCodec: CALL 'public abstract fun resolveOrNull (kType: kotlin.reflect.KType): kotlinx.rpc.grpc.codec.MessageCodec<*>? declared in kotlinx.rpc.grpc.codec.MessageCodecResolver' type=kotlinx.rpc.grpc.codec.MessageCodec origin=null + ARG : GET_VAR 'resolver: kotlinx.rpc.grpc.codec.MessageCodecResolver declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodecResolver origin=null + ARG kType: CALL 'public final fun typeOf (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null + TYPE_ARG T: kotlin.Unit + ARG type: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:UNARY' type=kotlinx.rpc.grpc.internal.MethodType + ARG schemaDescriptor: CONST Null type=kotlin.Any? value=null + ARG idempotent: CONST Boolean type=kotlin.Boolean value=true + ARG safe: CONST Boolean type=kotlin.Boolean value=true + ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:io.grpc.ServiceDescriptor [val] + CALL 'public final fun serviceDescriptor (name: kotlin.String, methods: kotlin.collections.Collection>, schemaDescriptor: kotlin.Any?): io.grpc.ServiceDescriptor declared in kotlinx.rpc.grpc.internal' type=io.grpc.ServiceDescriptor origin=null + ARG name: CONST String type=kotlin.String value="my.proto.package.ProtoPkgService" + ARG methods: CALL 'public abstract fun (): kotlin.collections.Collection declared in kotlin.collections.Map' type=kotlin.collections.Collection origin=GET_PROPERTY + ARG : GET_VAR 'val tmp_2: kotlin.collections.Map> declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlin.collections.Map> origin=null + ARG schemaDescriptor: CONST Null type=kotlin.Any? value=null + RETURN type=kotlin.Nothing from='public final fun delegate (resolver: kotlinx.rpc.grpc.codec.MessageCodecResolver): kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .ProtoPkgService.$rpcServiceStub.Companion' + CONSTRUCTOR_CALL 'public constructor (methodDescriptorMap: kotlin.collections.Map>, serviceDescriptor: io.grpc.ServiceDescriptor) declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null + ARG methodDescriptorMap: GET_VAR 'val tmp_2: kotlin.collections.Map> declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlin.collections.Map> origin=null + ARG serviceDescriptor: GET_VAR 'val tmp_3: io.grpc.ServiceDescriptor declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=io.grpc.ServiceDescriptor origin=null + FUN name:getCallable visibility:public modality:FINAL returnType:kotlinx.rpc.descriptor.RpcCallable? + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + VALUE_PARAMETER kind:Regular name:name index:1 type:kotlin.String + overridden: + public abstract fun getCallable (name: kotlin.String): kotlinx.rpc.descriptor.RpcCallable? declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun getCallable (name: kotlin.String): kotlinx.rpc.descriptor.RpcCallable? declared in .ProtoPkgService.$rpcServiceStub.Companion' + CALL 'public abstract fun get (key: K of kotlin.collections.Map): V of kotlin.collections.Map? declared in kotlin.collections.Map' type=kotlinx.rpc.descriptor.RpcCallable? origin=GET_ARRAY_ELEMENT + ARG : CALL 'private final fun (): kotlin.collections.Map.ProtoPkgService>> declared in .ProtoPkgService.$rpcServiceStub.Companion' type=kotlin.collections.Map.ProtoPkgService>> origin=GET_PROPERTY + ARG : GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.getCallable' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + ARG key: GET_VAR 'name: kotlin.String declared in .ProtoPkgService.$rpcServiceStub.Companion.getCallable' type=kotlin.String origin=null + PROPERTY name:callables visibility:public modality:FINAL [val] + overridden: + public abstract callables: kotlin.collections.Collection> declared in kotlinx.rpc.descriptor.RpcServiceDescriptor + FUN name: visibility:public modality:FINAL returnType:kotlin.collections.Collection.ProtoPkgService>> + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub.Companion + correspondingProperty: PROPERTY name:callables visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Collection.ProtoPkgService>> declared in .ProtoPkgService.$rpcServiceStub.Companion' + CALL 'public abstract fun (): kotlin.collections.Collection declared in kotlin.collections.Map' type=kotlin.collections.Collection origin=GET_PROPERTY + ARG : CALL 'private final fun (): kotlin.collections.Map.ProtoPkgService>> declared in .ProtoPkgService.$rpcServiceStub.Companion' type=kotlin.collections.Map.ProtoPkgService>> origin=GET_PROPERTY + ARG : GET_VAR ': .ProtoPkgService.$rpcServiceStub.Companion declared in .ProtoPkgService.$rpcServiceStub.Companion.' type=.ProtoPkgService.$rpcServiceStub.Companion origin=null + CONSTRUCTOR visibility:public returnType:.ProtoPkgService.$rpcServiceStub [primary] + VALUE_PARAMETER kind:Regular name:__rpc_stub_id index:0 type:kotlin.Long + VALUE_PARAMETER kind:Regular name:__rpc_client index:1 type:kotlinx.rpc.RpcClient + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS GENERATED[kotlinx.rpc.codegen.RpcGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.ProtoPkgService]' type=kotlin.Unit + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN returnType:kotlin.Boolean [fake_override,operator] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + VALUE_PARAMETER kind:Regular name:other index:1 type:kotlin.Any? + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .ProtoPkgService + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN returnType:kotlin.Int [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun hashCode (): kotlin.Int declared in .ProtoPkgService + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN returnType:kotlin.String [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun toString (): kotlin.String declared in .ProtoPkgService + FUN name:unit visibility:public modality:OPEN returnType:kotlin.Unit [suspend] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService.$rpcServiceStub + overridden: + public abstract fun unit (): kotlin.Unit declared in .ProtoPkgService + BLOCK_BODY + CALL 'public abstract fun call (call: kotlinx.rpc.RpcCall): T of kotlinx.rpc.RpcClient.call declared in kotlinx.rpc.RpcClient' type=kotlin.Unit origin=null + TYPE_ARG T: kotlin.Unit + ARG : CALL 'private final fun (): kotlinx.rpc.RpcClient declared in .ProtoPkgService.$rpcServiceStub' type=kotlinx.rpc.RpcClient origin=GET_PROPERTY + ARG : GET_VAR ': .ProtoPkgService.$rpcServiceStub declared in .ProtoPkgService.$rpcServiceStub.unit' type=.ProtoPkgService.$rpcServiceStub origin=null + ARG call: CONSTRUCTOR_CALL 'public constructor (descriptor: kotlinx.rpc.descriptor.RpcServiceDescriptor<*>, callableName: kotlin.String, arguments: kotlin.Array, serviceId: kotlin.Long) declared in kotlinx.rpc.RpcCall' type=kotlinx.rpc.RpcCall origin=null + ARG descriptor: GET_OBJECT 'CLASS GENERATED[kotlinx.rpc.codegen.FirRpcServiceStubCompanionObject] OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlinx.rpc.descriptor.RpcServiceDescriptor<.ProtoPkgService>; kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor<.ProtoPkgService>]' type=.ProtoPkgService.$rpcServiceStub.Companion + ARG callableName: CONST String type=kotlin.String value="unit" + ARG arguments: CALL 'public final fun emptyArray (): kotlin.Array declared in kotlin' type=kotlin.Array origin=null + TYPE_ARG T: kotlin.Any? + ARG serviceId: CALL 'private final fun (): kotlin.Long declared in .ProtoPkgService.$rpcServiceStub' type=kotlin.Long origin=GET_PROPERTY + ARG : GET_VAR ': .ProtoPkgService.$rpcServiceStub declared in .ProtoPkgService.$rpcServiceStub.unit' type=.ProtoPkgService.$rpcServiceStub origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN returnType:kotlin.Boolean [fake_override,operator] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + VALUE_PARAMETER kind:Regular name:other index:1 type:kotlin.Any? + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN returnType:kotlin.Int [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN returnType:kotlin.String [fake_override] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:kotlin.Any + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + FUN name:unit visibility:public modality:ABSTRACT returnType:kotlin.Unit [suspend] + VALUE_PARAMETER kind:DispatchReceiver name: index:0 type:.ProtoPkgService FUN name:box visibility:public modality:FINAL returnType:kotlin.String BLOCK_BODY VAR name:delegate type:kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate [val] @@ -770,20 +1021,21 @@ FILE fqName: fileName:/grpc.kt ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="simple" ARG expectedMethodName: CONST String type=kotlin.String value="simple" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/simple" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:UNARY' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_2: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_4: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -791,7 +1043,7 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_2: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_4: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String @@ -802,20 +1054,21 @@ FILE fqName: fileName:/grpc.kt GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="unit" ARG expectedMethodName: CONST String type=kotlin.String value="unit" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/unit" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:UNARY' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_3: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_5: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -823,7 +1076,7 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_3: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_5: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String @@ -834,20 +1087,21 @@ FILE fqName: fileName:/grpc.kt GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="custom" ARG expectedMethodName: CONST String type=kotlin.String value="custom" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/custom" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:UNARY' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_4: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_6: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -855,7 +1109,7 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_4: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_6: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String @@ -866,20 +1120,21 @@ FILE fqName: fileName:/grpc.kt GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="clientStream" ARG expectedMethodName: CONST String type=kotlin.String value="clientStream" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/clientStream" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:CLIENT_STREAMING' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_5: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_7: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -887,7 +1142,7 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_5: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_7: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String @@ -898,20 +1153,21 @@ FILE fqName: fileName:/grpc.kt GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="serverStream" ARG expectedMethodName: CONST String type=kotlin.String value="serverStream" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/serverStream" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:SERVER_STREAMING' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_6: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_8: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -919,7 +1175,7 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_6: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_8: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String @@ -930,20 +1186,21 @@ FILE fqName: fileName:/grpc.kt GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Nothing? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.String? [val] - CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null ARG : GET_VAR 'val delegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null ARG methodName: CONST String type=kotlin.String value="bidiStream" ARG expectedMethodName: CONST String type=kotlin.String value="bidiStream" + ARG expectedFullMethodName: CONST String type=kotlin.String value="BoxService/bidiStream" ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:BIDI_STREAMING' type=io.grpc.MethodDescriptor.MethodType ARG expectedServiceName: CONST String type=kotlin.String value="BoxService" WHEN type=kotlin.Nothing? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - ARG arg0: GET_VAR 'val tmp_7: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_9: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH @@ -951,7 +1208,58 @@ FILE fqName: fileName:/grpc.kt then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null TYPE_ARG T: kotlin.String TYPE_ARG R: kotlin.Nothing - ARG : GET_VAR 'val tmp_7: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_9: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing + VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + STRING_CONCATENATION type=kotlin.String + CONST String type=kotlin.String value="Fail: " + GET_VAR 'it: kotlin.String declared in .box.' type=kotlin.String origin=null + VAR name:protoPkgDelegate type:kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate [val] + CALL 'public final fun grpcDelegate (): kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in kotlinx.rpc.codegen.test' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null + TYPE_ARG T: .ProtoPkgService + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + ARG : CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + ARG arg0: CALL 'public open fun getName (): @[FlexibleNullability] kotlin.String? declared in io.grpc.ServiceDescriptor' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY + ARG : CALL 'public final fun (): io.grpc.ServiceDescriptor declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.ServiceDescriptor origin=GET_PROPERTY + ARG : GET_VAR 'val protoPkgDelegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null + ARG arg1: CONST String type=kotlin.String value="my.proto.package.ProtoPkgService" + then: BLOCK type=kotlin.Unit origin=null + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + STRING_CONCATENATION type=kotlin.String + CONST String type=kotlin.String value="Fail: Wrong service name: " + CALL 'public open fun getName (): @[FlexibleNullability] kotlin.String? declared in io.grpc.ServiceDescriptor' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY + ARG : CALL 'public final fun (): io.grpc.ServiceDescriptor declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.ServiceDescriptor origin=GET_PROPERTY + ARG : GET_VAR 'val protoPkgDelegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.String? [val] + CALL 'public final fun checkMethod (: io.grpc.MethodDescriptor<*, *>, expectedMethodName: kotlin.String, expectedFullMethodName: kotlin.String, expectedMethodType: io.grpc.MethodDescriptor.MethodType, expectedServiceName: kotlin.String, expectedIsSafe: kotlin.Boolean, expectedIsIdempotent: kotlin.Boolean, expectedIsSampledToLocalTracing: kotlin.Boolean): kotlin.String? declared in kotlinx.rpc.codegen.test' type=kotlin.String? origin=null + ARG : CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): {T0 of kotlin.internal.ir.CHECK_NOT_NULL & Any} declared in kotlin.internal.ir' type=io.grpc.MethodDescriptor<*, *> origin=EXCLEXCL + TYPE_ARG T0: io.grpc.MethodDescriptor<*, *> + ARG arg0: CALL 'public final fun getMethodDescriptor (methodName: kotlin.String): io.grpc.MethodDescriptor<*, *>? declared in kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate' type=io.grpc.MethodDescriptor<*, *>? origin=null + ARG : GET_VAR 'val protoPkgDelegate: kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .box' type=kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate origin=null + ARG methodName: CONST String type=kotlin.String value="unit" + ARG expectedMethodName: CONST String type=kotlin.String value="unit" + ARG expectedFullMethodName: CONST String type=kotlin.String value="my.proto.package.ProtoPkgService/unit" + ARG expectedMethodType: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_JAVA_DECLARATION_STUB name:UNARY' type=io.grpc.MethodDescriptor.MethodType + ARG expectedServiceName: CONST String type=kotlin.String value="my.proto.package.ProtoPkgService" + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + ARG arg0: GET_VAR 'val tmp_10: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (: T of kotlin.let, block: kotlin.Function1): R of kotlin.let declared in kotlin' type=kotlin.Nothing origin=null + TYPE_ARG T: kotlin.String + TYPE_ARG R: kotlin.Nothing + ARG : GET_VAR 'val tmp_10: kotlin.String? declared in .box' type=kotlin.String? origin=null ARG block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL returnType:kotlin.Nothing VALUE_PARAMETER kind:Regular name:it index:0 type:kotlin.String diff --git a/tests/compiler-plugin-tests/src/testData/box/grpc.fir.txt b/tests/compiler-plugin-tests/src/testData/box/grpc.fir.txt index e60f78ea9..58b908d92 100644 --- a/tests/compiler-plugin-tests/src/testData/box/grpc.fir.txt +++ b/tests/compiler-plugin-tests/src/testData/box/grpc.fir.txt @@ -43,6 +43,16 @@ FILE: grpc.kt } + } + @R|kotlinx/rpc/grpc/annotations/Grpc|(protoPackage = (String(my.proto.), String(package))) public abstract interface ProtoPkgService : R|kotlin/Any| { + public abstract suspend fun unit(): R|kotlin/Unit| + + public final class $rpcServiceStub : R|kotlin/Any| { + public final companion object Companion : R|kotlin/Any| { + } + + } + } public final fun box(): R|kotlin/String| { lval delegate: R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate| = R|kotlinx/rpc/codegen/test/grpcDelegate|() @@ -52,27 +62,38 @@ FILE: grpc.kt } } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(simple))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(simple), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(simple))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(simple), String(BoxService/simple), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + ^box (String(Fail: ), R|/it|) + } + ) } + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(unit))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(unit), String(BoxService/unit), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(unit))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(unit), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(custom))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(custom), String(BoxService/custom), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(custom))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(custom), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(clientStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(clientStream), String(BoxService/clientStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.CLIENT_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(clientStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(clientStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.CLIENT_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(serverStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(serverStream), String(BoxService/serverStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.SERVER_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(serverStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(serverStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.SERVER_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(bidiStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(bidiStream), String(BoxService/bidiStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.BIDI_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } - R|/delegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(bidiStream))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(bidiStream), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.BIDI_STREAMING|, String(BoxService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { + lval protoPkgDelegate: R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate| = R|kotlinx/rpc/codegen/test/grpcDelegate|() + when () { + !=(R|/protoPkgDelegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.serviceDescriptor|.R|io/grpc/ServiceDescriptor.name|, String(my.proto.package.ProtoPkgService)) -> { + ^box (String(Fail: Wrong service name: ), R|/protoPkgDelegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.serviceDescriptor|.R|io/grpc/ServiceDescriptor.name|) + } + } + + R|/protoPkgDelegate|.R|kotlinx/rpc/grpc/descriptor/GrpcServiceDelegate.getMethodDescriptor|(String(unit))!!.R|kotlinx/rpc/codegen/test/checkMethod|(String(unit), String(my.proto.package.ProtoPkgService/unit), Q|io/grpc/MethodDescriptor.MethodType|.R|io/grpc/MethodDescriptor.MethodType.UNARY|, String(my.proto.package.ProtoPkgService))?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing| { ^box (String(Fail: ), R|/it|) } ) } diff --git a/tests/compiler-plugin-tests/src/testData/box/grpc.kt b/tests/compiler-plugin-tests/src/testData/box/grpc.kt index 605ec7de2..c6b0fce99 100644 --- a/tests/compiler-plugin-tests/src/testData/box/grpc.kt +++ b/tests/compiler-plugin-tests/src/testData/box/grpc.kt @@ -44,6 +44,13 @@ interface BoxService { suspend fun custom(): Custom } + +@Grpc(protoPackage = "my.proto." + "package") +interface ProtoPkgService { + suspend fun unit() +} + + fun box(): String { val delegate = grpcDelegate() @@ -53,39 +60,60 @@ fun box(): String { delegate.getMethodDescriptor("simple")!!.checkMethod( expectedMethodName = "simple", + expectedFullMethodName = "BoxService/simple", expectedMethodType = MethodDescriptor.MethodType.UNARY, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } delegate.getMethodDescriptor("unit")!!.checkMethod( expectedMethodName = "unit", + expectedFullMethodName = "BoxService/unit", expectedMethodType = MethodDescriptor.MethodType.UNARY, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } delegate.getMethodDescriptor("custom")!!.checkMethod( expectedMethodName = "custom", + expectedFullMethodName = "BoxService/custom", expectedMethodType = MethodDescriptor.MethodType.UNARY, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } delegate.getMethodDescriptor("clientStream")!!.checkMethod( expectedMethodName = "clientStream", + expectedFullMethodName = "BoxService/clientStream", expectedMethodType = MethodDescriptor.MethodType.CLIENT_STREAMING, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } delegate.getMethodDescriptor("serverStream")!!.checkMethod( expectedMethodName = "serverStream", + expectedFullMethodName = "BoxService/serverStream", expectedMethodType = MethodDescriptor.MethodType.SERVER_STREAMING, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } delegate.getMethodDescriptor("bidiStream")!!.checkMethod( expectedMethodName = "bidiStream", + expectedFullMethodName = "BoxService/bidiStream", expectedMethodType = MethodDescriptor.MethodType.BIDI_STREAMING, expectedServiceName = "BoxService", - )?.let { return "Fail: $it"} + )?.let { return "Fail: $it" } + + + // test ProtoPkgService + val protoPkgDelegate = grpcDelegate() + + if (protoPkgDelegate.serviceDescriptor.name != "my.proto.package.ProtoPkgService") { + return "Fail: Wrong service name: ${protoPkgDelegate.serviceDescriptor.name}" + } + + protoPkgDelegate.getMethodDescriptor("unit")!!.checkMethod( + expectedMethodName = "unit", + expectedFullMethodName = "my.proto.package.ProtoPkgService/unit", + expectedMethodType = MethodDescriptor.MethodType.UNARY, + expectedServiceName = "my.proto.package.ProtoPkgService", + )?.let { return "Fail: $it" } return "OK" }