diff --git a/cinterop-c/build_target.sh b/cinterop-c/build_target.sh index 787fbcb86..227f3debc 100755 --- a/cinterop-c/build_target.sh +++ b/cinterop-c/build_target.sh @@ -26,11 +26,11 @@ CONFIG=release mkdir -p "$(dirname "$DST")" echo "==> Building $LABEL to $DST" >&2 -KONAN_DEP="--define=KONAN_DEPS=/Users/johannes.zottele/.konan//dependencies" -bazel build "$LABEL" --config="$KONAN_TARGET" --config="$CONFIG" $KONAN_DEP "--define=KONAN_HOME=$KONAN_HOME" >/dev/null +KONAN_DEP="--define=KONAN_DEPS=$HOME/.konan/dependencies" +bazel build "$LABEL" --config="$KONAN_TARGET" --config="$CONFIG" "$KONAN_DEP" "--define=KONAN_HOME=$KONAN_HOME" # Ask Bazel what file(s) this target produced under this platform -out="$(bazel cquery "$LABEL" --config="$KONAN_TARGET" --config="$CONFIG" $KONAN_DEP "--define=KONAN_HOME=$KONAN_HOME" --output=files | head -n1)" +out="$(bazel cquery "$LABEL" --config="$KONAN_TARGET" --config="$CONFIG" "$KONAN_DEP" "--define=KONAN_HOME=$KONAN_HOME" --output=files | head -n1)" [[ -n "$out" ]] || { echo "No output for $LABEL ($SHORT)"; exit 1; } cp -f "$out" "$DST" 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 43bdac58a..4ae15ced1 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 @@ -1070,12 +1070,12 @@ internal class RpcStubGenerator( * Where: * - `` - the name of the k-th callable in the service */ - private fun irMethodDescriptorMap(resolver: IrValueParameter): IrCallImpl { + private fun IrBlockBodyBuilder.irMethodDescriptorMap(resolver: IrValueParameter): IrCallImpl { return irMapOf( keyType = ctx.irBuiltIns.stringType, valueType = ctx.grpcPlatformMethodDescriptor.starProjectedType, declaration.methods.memoryOptimizedMap { callable -> - stringConst(callable.name) to irMethodDescriptor(callable, resolver) + stringConst(callable.grpcName) to irMethodDescriptor(callable, resolver) }, ) } @@ -1129,15 +1129,14 @@ internal class RpcStubGenerator( * // In scope: resolver: MessageCodecResolver * * methodDescriptor<, >( - * fullMethodName = "${descriptor.serviceFqName}/${callable.name}", + * fullMethodName = "${descriptor.serviceFqName}/${ ?: callable.name}", * requestCodec = , * responseCodec = , * type = MethodType., * schemaDescriptor = null, // null for now - * // todo understand these values - * idempotent = true, - * safe = true, - * sampledToLocalTracing = true, + * idempotent = , + * safe = , + * sampledToLocalTracing = , * ) * ``` * @@ -1149,7 +1148,10 @@ internal class RpcStubGenerator( * MethodType.CLIENT_STREAMING, MethodType.BIDI_STREAMING * - / - a MessageCodec getter, see [irCodec] */ - private fun irMethodDescriptor(callable: ServiceDeclaration.Callable, resolver: IrValueParameter): IrCall { + private fun IrBlockBodyBuilder.irMethodDescriptor( + callable: ServiceDeclaration.Callable, + resolver: IrValueParameter, + ): IrCall { check(callable is ServiceDeclaration.Method) { "Only methods are allowed here" } @@ -1167,13 +1169,10 @@ internal class RpcStubGenerator( val methodDescriptorType = ctx.grpcPlatformMethodDescriptor.typeWith(requestType, responseType) return vsApi { - IrCallImplVS( - startOffset = UNDEFINED_OFFSET, - endOffset = UNDEFINED_OFFSET, + irCall( type = methodDescriptorType, - symbol = ctx.functions.methodDescriptor, + callee = ctx.functions.methodDescriptor, typeArgumentsCount = 2, - valueArgumentsCount = 8, ) }.apply { arguments { @@ -1182,9 +1181,12 @@ internal class RpcStubGenerator( +responseType } + val grpcMethodAnnotation = callable.function + .getAnnotation(RpcClassId.grpcMethodAnnotation.asSingleFqName()) + values { // fullMethodName - +stringConst("${declaration.serviceFqName}/${callable.name}") + +stringConst("${declaration.serviceFqName}/${callable.grpcName}") // requestCodec +irCodec(requestType, resolver) @@ -1219,28 +1221,39 @@ internal class RpcStubGenerator( // schemaDescriptor +nullConst(ctx.anyNullable) - // todo figure out these + val idempotentArgument = grpcMethodAnnotation + ?.getValueArgument(Name.identifier("idempotent")) + val idempotent = (idempotentArgument as? IrConst)?.value as? Boolean ?: false + // idempotent - +booleanConst(true) + +booleanConst(idempotent) + + val safeArgument = grpcMethodAnnotation + ?.getValueArgument(Name.identifier("safe")) + val safe = (safeArgument as? IrConst)?.value as? Boolean ?: false // safe - +booleanConst(true) + +booleanConst(safe) + + val sampledToLocalTracingArgument = grpcMethodAnnotation + ?.getValueArgument(Name.identifier("sampledToLocalTracing")) + val sampledToLocalTracing = (sampledToLocalTracingArgument as? IrConst)?.value as? Boolean ?: true // sampledToLocalTracing - +booleanConst(true) + +booleanConst(sampledToLocalTracing) } } } } /** - * If [type] is annotated with [RpcIrContext.withCodecAnnotation], + * If [messageType] is annotated with [RpcIrContext.withCodecAnnotation], * we use its codec object * - * If not, use [resolver].resolve() + * If not, use [resolver].resolveOrNull() */ - private fun irCodec(type: IrType, resolver: IrValueParameter): IrExpression { - val owner = type.classOrFail.owner + private fun IrBlockBodyBuilder.irCodec(messageType: IrType, resolver: IrValueParameter): IrExpression { + val owner = messageType.classOrFail.owner val protobufMessage = owner.getAnnotation(ctx.withCodecAnnotation.owner.kotlinFqName) return if (protobufMessage != null) { @@ -1256,14 +1269,12 @@ internal class RpcStubGenerator( symbol = codec.classOrFail, ) } else { - vsApi { - IrCallImplVS( - startOffset = UNDEFINED_OFFSET, - endOffset = UNDEFINED_OFFSET, - type = ctx.grpcMessageCodec.typeWith(type), - symbol = ctx.functions.grpcMessageCodecResolverResolveOrNull.symbol, + val codecType = ctx.grpcMessageCodec.typeWith(messageType) + val codecCall = vsApi { + irCall( + type = codecType.makeNullable(), + callee = ctx.functions.grpcMessageCodecResolverResolveOrNull.symbol, typeArgumentsCount = 0, - valueArgumentsCount = 1, ) }.apply { arguments { @@ -1275,10 +1286,21 @@ internal class RpcStubGenerator( ) values { - +irTypeOfCall(type) + +irTypeOfCall(messageType) } } } + + irElvis( + expression = codecCall, + ifNull = irCall(ctx.irBuiltIns.illegalArgumentExceptionSymbol).apply { + arguments { + values { + +stringConst("No codec found for ${messageType.classFqName}") + } + } + }, + ) } } @@ -1795,4 +1817,31 @@ internal class RpcStubGenerator( fun IrBuilderWithScope.irSafeAs(argument: IrExpression, type: IrType) = IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.SAFE_CAST, type, argument) + + fun IrBlockBodyBuilder.irElvis(expression: IrExpression, ifNull: IrExpression): IrExpression { + check(expression.type == ifNull.type || ifNull.type == ctx.irBuiltIns.nothingType) { + "Type mismatch: ${expression.type.dumpKotlinLike()} != ${ifNull.type.dumpKotlinLike()}" + } + + return irBlock(origin = IrStatementOrigin.ELVIS, resultType = expression.type.makeNotNull()) { + val temp = irTemporary( + value = expression, + nameHint = "elvis_left_hand_side", + isMutable = false, + ) + +irWhen( + type = expression.type, + branches = listOf( + irBranch( + condition = irEqualsNull(irGet(temp)), + result = ifNull, + ), + irBranch( + condition = irTrue(), + result = irGet(temp), + ), + ), + ) + } + } } 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 68fc80eba..585152536 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 @@ -8,12 +8,16 @@ import kotlinx.rpc.codegen.common.RpcClassId import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.getAnnotation +import org.jetbrains.kotlin.ir.util.getValueArgument import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.kotlinFqName +import org.jetbrains.kotlin.name.Name -class ServiceDeclaration( +internal class ServiceDeclaration( val service: IrClass, val stubClass: IrClass, val methods: List, @@ -37,6 +41,17 @@ class ServiceDeclaration( val arguments: List, ) : Callable { override val name: String = function.name.asString() + val grpcName by lazy { + val grpcMethodAnnotation = function.getAnnotation( + RpcClassId.grpcMethodAnnotation.asSingleFqName(), + ) + + val nameArgument = grpcMethodAnnotation?.getValueArgument(Name.identifier("name")) + + ((nameArgument as? IrConst)?.value as? String) + ?.takeIf { it.isNotBlank() } + ?: name + } class Argument( val value: IrValueParameter, diff --git a/compiler-plugin/compiler-plugin-common/src/main/kotlin/kotlinx/rpc/codegen/common/Names.kt b/compiler-plugin/compiler-plugin-common/src/main/kotlin/kotlinx/rpc/codegen/common/Names.kt index a5c0d97c8..06eebd7ee 100644 --- a/compiler-plugin/compiler-plugin-common/src/main/kotlin/kotlinx/rpc/codegen/common/Names.kt +++ b/compiler-plugin/compiler-plugin-common/src/main/kotlin/kotlinx/rpc/codegen/common/Names.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.name.Name object RpcClassId { val rpcAnnotation = ClassId(FqName("kotlinx.rpc.annotations"), Name.identifier("Rpc")) val grpcAnnotation = ClassId(FqName("kotlinx.rpc.grpc.annotations"), Name.identifier("Grpc")) + val grpcMethodAnnotation = ClassId(FqName("kotlinx.rpc.grpc.annotations"), Name.identifier("Grpc.Method")) val withCodecAnnotation = ClassId(FqName("kotlinx.rpc.grpc.codec"), Name.identifier("WithCodec")) val checkedTypeAnnotation = ClassId(FqName("kotlinx.rpc.annotations"), Name.identifier("CheckedTypeAnnotation")) diff --git a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirGrpcServiceDeclarationChecker.kt b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirGrpcServiceDeclarationChecker.kt index 675837715..f8d84d6a7 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirGrpcServiceDeclarationChecker.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirGrpcServiceDeclarationChecker.kt @@ -5,17 +5,25 @@ package kotlinx.rpc.codegen.checkers import kotlinx.rpc.codegen.FirRpcPredicates +import kotlinx.rpc.codegen.checkers.IdentifierRegexes.identifierRegex +import kotlinx.rpc.codegen.checkers.IdentifierRegexes.packageIdentifierRegex import kotlinx.rpc.codegen.checkers.diagnostics.FirGrpcDiagnostics import kotlinx.rpc.codegen.checkers.util.functionParametersRecursionCheck import kotlinx.rpc.codegen.common.RpcClassId import kotlinx.rpc.codegen.vsApi +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId +import org.jetbrains.kotlin.fir.declarations.getBooleanArgument +import org.jetbrains.kotlin.fir.declarations.getStringArgument import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.types.isMarkedNullable +import org.jetbrains.kotlin.name.Name object FirGrpcServiceDeclarationChecker { fun check( @@ -27,6 +35,26 @@ object FirGrpcServiceDeclarationChecker { return } + val isMetaAnnotated = declaration.classKind == ClassKind.ANNOTATION_CLASS + if (isMetaAnnotated) { + return + } + + val annotation = declaration.getAnnotationByClassId(RpcClassId.grpcAnnotation, context.session) + ?: error("Unexpected unresolved @Grpc annotation type for declaration: ${declaration.symbol.classId.asSingleFqName()}") + + val protoPackage = annotation.getStringArgument(protoPackageName, context.session).orEmpty() + + if (protoPackage.isNotEmpty()) { + if (!protoPackage.matches(packageIdentifierRegex)) { + reporter.reportOn( + source = annotation.argumentMapping.mapping[protoPackageName]!!.source, + factory = FirGrpcDiagnostics.WRONG_PROTO_PACKAGE_VALUE, + context = context, + ) + } + } + vsApi { declaration .declarationsVS(context.session) @@ -71,6 +99,48 @@ object FirGrpcServiceDeclarationChecker { context = context, ) } + + val grpcMethodAnnotation = function.getAnnotationByClassId(RpcClassId.grpcMethodAnnotation, context.session) + + if (grpcMethodAnnotation != null) { + val grpcMethodName = grpcMethodAnnotation.getStringArgument(grpcMethodNameName, context.session).orEmpty() + + if (grpcMethodName.isNotEmpty()) { + if (!grpcMethodName.matches(identifierRegex)) { + reporter.reportOn( + source = grpcMethodAnnotation.argumentMapping.mapping[grpcMethodNameName]!!.source, + factory = FirGrpcDiagnostics.WRONG_PROTO_METHOD_NAME_VALUE, + context = context, + ) + } + } + + val safe = grpcMethodAnnotation.getBooleanArgument(grpcMethodSafeName, context.session) ?: false + val idempotent = grpcMethodAnnotation.getBooleanArgument(grpcMethodIdempotentName, context.session) ?: false + + // safe = true, idempotent = true is allowed + // safe = false, idempotent = false is allowed + // safe = false, idempotent = true is allowed + // safe = true, idempotent = false is not allowed + if (safe && !idempotent) { + reporter.reportOn( + source = grpcMethodAnnotation.source, + factory = FirGrpcDiagnostics.WRONG_SAFE_IDEMPOTENT_COMBINATION, + context = context, + positioningStrategy = SourceElementPositioningStrategies.VALUE_ARGUMENTS_LIST, + ) + } + } } } + + private val protoPackageName = Name.identifier("protoPackage") + private val grpcMethodNameName = Name.identifier("name") + private val grpcMethodSafeName = Name.identifier("safe") + private val grpcMethodIdempotentName = Name.identifier("idempotent") +} + +object IdentifierRegexes { + val identifierRegex = Regex("[a-zA-Z_][a-zA-Z0-9_]*") + val packageIdentifierRegex = Regex("[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*") } diff --git a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcServiceDeclarationChecker.kt b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcServiceDeclarationChecker.kt index 156dea13a..f1561864a 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcServiceDeclarationChecker.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/FirRpcServiceDeclarationChecker.kt @@ -62,7 +62,7 @@ object FirRpcServiceDeclarationChecker { } .groupBy { it.name } .filter { (_, list) -> list.size > 1 } - .forEach { name, functions -> + .forEach { (name, functions) -> functions.forEach { function -> reporter.reportOn( source = function.source, diff --git a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt index 948a35f3d..0cbba7472 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt @@ -51,6 +51,9 @@ object FirRpcStrictModeDiagnostics : RpcKtDiagnosticsContainer() { } object FirGrpcDiagnostics : RpcKtDiagnosticsContainer() { + val WRONG_PROTO_PACKAGE_VALUE by error0() + val WRONG_PROTO_METHOD_NAME_VALUE by error0() + val WRONG_SAFE_IDEMPOTENT_COMBINATION by error0() val NULLABLE_PARAMETER_IN_GRPC_SERVICE by error0() val NULLABLE_RETURN_TYPE_IN_GRPC_SERVICE by error0() val NON_TOP_LEVEL_CLIENT_STREAMING_IN_RPC_SERVICE by error0() diff --git a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt index 6bc4487be..1fce9cdfb 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt @@ -4,6 +4,7 @@ package kotlinx.rpc.codegen.checkers.diagnostics +import kotlinx.rpc.codegen.checkers.IdentifierRegexes import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory import org.jetbrains.kotlin.diagnostics.rendering.Renderer import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers @@ -102,6 +103,22 @@ object RpcStrictModeDiagnosticRendererFactory : BaseDiagnosticRendererFactory() object GrpcDiagnosticRendererFactory : BaseDiagnosticRendererFactory() { override val MAP by RpcKtDiagnosticFactoryToRendererMap("Grpc") { map -> + map.put( + factory = FirGrpcDiagnostics.WRONG_PROTO_PACKAGE_VALUE, + message = "'protoPackage' parameter value must be a valid package name (${IdentifierRegexes.packageIdentifierRegex.pattern}) or empty", + ) + + map.put( + factory = FirGrpcDiagnostics.WRONG_PROTO_METHOD_NAME_VALUE, + message = "'name' parameter value must be a valid identifier (${IdentifierRegexes.identifierRegex.pattern}) or empty", + ) + + map.put( + factory = FirGrpcDiagnostics.WRONG_SAFE_IDEMPOTENT_COMBINATION, + message = "'safe = true' and 'idempotent = false' are mutually exclusive. " + + "If the method is safe, write explicitly 'idempotent = true'.", + ) + map.put( factory = FirGrpcDiagnostics.NULLABLE_PARAMETER_IN_GRPC_SERVICE, message = "Nullable type is not allowed in @Grpc service function parameters.", 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 3b4e378ee..5686fea17 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 @@ -11,4 +11,12 @@ import kotlinx.rpc.annotations.Rpc */ @Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.TYPE_PARAMETER) @Rpc -public annotation class Grpc(val protoPackage: String = "") +public annotation class Grpc(val protoPackage: String = "") { + @Target(AnnotationTarget.FUNCTION) + public annotation class Method( + val name: String = "", + val safe: Boolean = false, + val idempotent: Boolean = false, + val sampledToLocalTracing: Boolean = true, + ) +} diff --git a/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/GrpcAnnotationsTest.kt b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/GrpcAnnotationsTest.kt new file mode 100644 index 000000000..99074e1f6 --- /dev/null +++ b/grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/test/GrpcAnnotationsTest.kt @@ -0,0 +1,67 @@ +/* + * 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 + +import kotlinx.rpc.descriptor.serviceDescriptorOf +import kotlinx.rpc.grpc.annotations.Grpc +import kotlinx.rpc.grpc.codec.EmptyMessageCodecResolver +import kotlinx.rpc.grpc.codec.MessageCodec +import kotlinx.rpc.grpc.codec.MessageCodecResolver +import kotlinx.rpc.grpc.descriptor.GrpcServiceDescriptor +import kotlinx.rpc.protobuf.input.stream.InputStream +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +@Grpc("grpc.test") +interface GrpcAnnotationsService { + @Suppress("unused") + @Grpc.Method(name = "Empty", safe = true, idempotent = true, sampledToLocalTracing = false) + suspend fun empty() +} + +class GrpcAnnotationsTest { + @Test + fun nullCodec() { + assertFailsWith { + val descriptor = serviceDescriptorOf() + as GrpcServiceDescriptor + + descriptor.delegate(EmptyMessageCodecResolver) + } + } + + @Test + fun methodAnnotations() { + val descriptor = serviceDescriptorOf() + as GrpcServiceDescriptor + val methodDescriptor = descriptor + .delegate(unitCodec) + .getMethodDescriptor("Empty") + + assertNotNull(methodDescriptor) + + assertEquals("grpc.test.GrpcAnnotationsService/Empty", methodDescriptor.getFullMethodName()) + assertTrue(methodDescriptor.isSafe()) + assertTrue(methodDescriptor.isIdempotent()) + assertFalse(methodDescriptor.isSampledToLocalTracing()) + } +} + +private val unitCodec = MessageCodecResolver { + object : MessageCodec { + override fun encode(value: Unit): InputStream { + TODO("Not yet implemented") + } + + override fun decode(stream: InputStream) { + TODO("Not yet implemented") + } + } +} + diff --git a/grpc/grpc-core/src/commonTest/proto/idempotency.proto b/grpc/grpc-core/src/commonTest/proto/idempotency.proto new file mode 100644 index 000000000..9ec6b02f2 --- /dev/null +++ b/grpc/grpc-core/src/commonTest/proto/idempotency.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package kotlinx.rpc.grpc.test; + +message Message { + string message = 1; +} + +service Idempotency { + rpc Idempotent(Message) returns (Message) { + option idempotency_level = IDEMPOTENT; + } + rpc Safe(Message) returns (Message) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} 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 4ee6d63fa..dfb2f5c00 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 @@ -4,9 +4,11 @@ package kotlinx.rpc.protoc.gen.grpc +import com.google.protobuf.DescriptorProtos import kotlinx.rpc.protoc.gen.core.AModelToKotlinCommonGenerator import kotlinx.rpc.protoc.gen.core.CodeGenerator import kotlinx.rpc.protoc.gen.core.model.FileDeclaration +import kotlinx.rpc.protoc.gen.core.model.FqName import kotlinx.rpc.protoc.gen.core.model.Model import kotlinx.rpc.protoc.gen.core.model.ServiceDeclaration import org.slf4j.Logger @@ -21,15 +23,15 @@ class ModelToGrpcKotlinCommonGenerator( override fun CodeGenerator.generatePublicDeclaredEntities(fileDeclaration: FileDeclaration) { additionalPublicImports.add("kotlinx.coroutines.flow.Flow") - fileDeclaration.serviceDeclarations.forEach { generatePublicService(it) } + fileDeclaration.serviceDeclarations.forEach { generatePublicService(it, fileDeclaration.packageName) } } override fun CodeGenerator.generateInternalDeclaredEntities(fileDeclaration: FileDeclaration) {} @Suppress("detekt.LongMethod") - private fun CodeGenerator.generatePublicService(service: ServiceDeclaration) { + private fun CodeGenerator.generatePublicService(service: ServiceDeclaration, packageName: FqName.Package) { val pkg = service.dec.file.`package`.orEmpty() - val annotationParams = if (pkg.isNotEmpty()) """(protoPackage = "$pkg")""" else "" + val annotationParams = if (pkg.isNotEmpty() && pkg != packageName.safeFullName()) """(protoPackage = "$pkg")""" else "" clazz( name = service.name.simpleName, @@ -39,10 +41,17 @@ class ModelToGrpcKotlinCommonGenerator( service.methods.forEach { method -> val inputType = method.inputType val outputType = method.outputType + val annotations = when (method.dec.options.idempotencyLevel) { + null, DescriptorProtos.MethodOptions.IdempotencyLevel.IDEMPOTENCY_UNKNOWN -> emptyList() + DescriptorProtos.MethodOptions.IdempotencyLevel.IDEMPOTENT -> listOf("@kotlinx.rpc.grpc.annotations.Grpc.Method(idempotent = true)") + DescriptorProtos.MethodOptions.IdempotencyLevel.NO_SIDE_EFFECTS -> listOf("@kotlinx.rpc.grpc.annotations.Grpc.Method(idempotent = true, safe = true)") + } + function( name = method.name, modifiers = if (method.dec.isServerStreaming) "" else "suspend", args = "message: ${inputType.name.safeFullName().wrapInFlowIf(method.dec.isClientStreaming)}", + annotations = annotations, returnType = outputType.name.safeFullName().wrapInFlowIf(method.dec.isServerStreaming), ) } 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 40d0a1725..48bc16501 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 @@ -47,8 +47,8 @@ fun MethodDescriptor<*, *>.checkMethod( expectedFullMethodName: String, expectedMethodType: MethodDescriptor.MethodType, expectedServiceName: String, - expectedIsSafe: Boolean = true, - expectedIsIdempotent: Boolean = true, + expectedIsSafe: Boolean = false, + expectedIsIdempotent: Boolean = false, expectedIsSampledToLocalTracing: Boolean = true, ): String? { return when { diff --git a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java index e29c721ec..3cc329ec6 100644 --- a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java +++ b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java @@ -1,9 +1,5 @@ -/* - * 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.codegen.test.runners; import com.intellij.testFramework.TestDataPath; diff --git a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java index 3bc448f56..067f7f551 100644 --- a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java +++ b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java @@ -1,9 +1,5 @@ -/* - * 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.codegen.test.runners; import com.intellij.testFramework.TestDataPath; 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 818636e81..adefc5939 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 @@ -445,18 +445,42 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlin.String TYPE_ARG Response: kotlin.String ARG fullMethodName: CONST String type=kotlin.String value="BoxService/simple" - 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 .BoxService.$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.String - 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 .BoxService.$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.String + ARG requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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.String + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_1: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.String" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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.String + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.String" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_2: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true 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 @@ -466,18 +490,42 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlin.Unit TYPE_ARG Response: kotlin.Unit ARG fullMethodName: CONST String type=kotlin.String value="BoxService/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 .BoxService.$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 .BoxService.$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 requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_3: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_4: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true 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 @@ -487,18 +535,42 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlin.String TYPE_ARG Response: kotlin.Unit ARG fullMethodName: CONST String type=kotlin.String value="BoxService/clientStream" - 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 .BoxService.$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.String - 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 .BoxService.$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 requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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.String + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.String" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_5: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_6: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null ARG type: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:CLIENT_STREAMING' 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true 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 @@ -508,18 +580,42 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlin.Unit TYPE_ARG Response: kotlin.Unit ARG fullMethodName: CONST String type=kotlin.String value="BoxService/serverStream" - 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 .BoxService.$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 .BoxService.$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 requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_7: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_8: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_8: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null ARG type: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:SERVER_STREAMING' 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true 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 @@ -529,18 +625,42 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlinx.rpc.codegen.test.Message TYPE_ARG Response: kotlinx.rpc.codegen.test.Message ARG fullMethodName: CONST String type=kotlin.String value="BoxService/bidiStream" - 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 .BoxService.$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: kotlinx.rpc.codegen.test.Message - 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 .BoxService.$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: kotlinx.rpc.codegen.test.Message + ARG requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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: kotlinx.rpc.codegen.test.Message + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_9: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlinx.rpc.codegen.test.Message" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_9: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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: kotlinx.rpc.codegen.test.Message + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlinx.rpc.codegen.test.Message" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_10: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null ARG type: GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:BIDI_STREAMING' 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true 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 @@ -550,17 +670,29 @@ FILE fqName: fileName:/grpc.kt TYPE_ARG Request: kotlin.Unit TYPE_ARG Response: .Custom ARG fullMethodName: CONST String type=kotlin.String value="BoxService/custom" - 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 .BoxService.$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 requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 .BoxService.$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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_11: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_11: kotlinx.rpc.grpc.codec.MessageCodec? declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null ARG responseCodec: GET_OBJECT 'CLASS OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[kotlinx.rpc.grpc.codec.MessageCodec<.Custom>]' type=.Custom.Companion 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:io.grpc.ServiceDescriptor [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_12 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="BoxService" ARG methods: CALL 'public abstract fun (): kotlin.collections.Collection declared in kotlin.collections.Map' type=kotlin.collections.Collection origin=GET_PROPERTY @@ -569,7 +701,7 @@ FILE fqName: fileName:/grpc.kt RETURN type=kotlin.Nothing from='public final fun delegate (resolver: kotlinx.rpc.grpc.codec.MessageCodecResolver): kotlinx.rpc.grpc.descriptor.GrpcServiceDelegate declared in .BoxService.$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_0: kotlin.collections.Map> declared in .BoxService.$rpcServiceStub.Companion.delegate' type=kotlin.collections.Map> origin=null - ARG serviceDescriptor: GET_VAR 'val tmp_1: io.grpc.ServiceDescriptor declared in .BoxService.$rpcServiceStub.Companion.delegate' type=io.grpc.ServiceDescriptor origin=null + ARG serviceDescriptor: GET_VAR 'val tmp_12: io.grpc.ServiceDescriptor declared in .BoxService.$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:.BoxService.$rpcServiceStub.Companion VALUE_PARAMETER kind:Regular name:name index:1 type:kotlin.String @@ -891,7 +1023,7 @@ FILE fqName: fileName:/grpc.kt 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] + VAR IR_TEMPORARY_VARIABLE name:tmp_13 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<*, *> @@ -904,29 +1036,53 @@ FILE fqName: fileName:/grpc.kt 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 requestCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_14 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_14: kotlinx.rpc.grpc.codec.MessageCodec? declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_14: kotlinx.rpc.grpc.codec.MessageCodec? declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG responseCodec: BLOCK type=kotlinx.rpc.grpc.codec.MessageCodec origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_15 type:kotlinx.rpc.grpc.codec.MessageCodec? [val] + 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 + WHEN type=kotlinx.rpc.grpc.codec.MessageCodec? 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_15: kotlinx.rpc.grpc.codec.MessageCodec? declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null + ARG arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun illegalArgumentException (arg0: kotlin.String): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + ARG arg0: CONST String type=kotlin.String value="No codec found for kotlin.Unit" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_15: kotlinx.rpc.grpc.codec.MessageCodec? declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlinx.rpc.grpc.codec.MessageCodec? origin=null 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 idempotent: CONST Boolean type=kotlin.Boolean value=false + ARG safe: CONST Boolean type=kotlin.Boolean value=false ARG sampledToLocalTracing: CONST Boolean type=kotlin.Boolean value=true - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:io.grpc.ServiceDescriptor [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_16 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 : GET_VAR 'val tmp_13: 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 + ARG methodDescriptorMap: GET_VAR 'val tmp_13: kotlin.collections.Map> declared in .ProtoPkgService.$rpcServiceStub.Companion.delegate' type=kotlin.collections.Map> origin=null + ARG serviceDescriptor: GET_VAR 'val tmp_16: 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 @@ -1021,7 +1177,7 @@ 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_4 type:kotlin.String? [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_17 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<*, *> @@ -1035,7 +1191,7 @@ FILE fqName: fileName:/grpc.kt 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_17: 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 @@ -1043,7 +1199,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_17: 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 @@ -1054,7 +1210,7 @@ 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] + VAR IR_TEMPORARY_VARIABLE name:tmp_18 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<*, *> @@ -1068,7 +1224,7 @@ FILE fqName: fileName:/grpc.kt 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_18: 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 @@ -1076,7 +1232,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_18: 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 @@ -1087,7 +1243,7 @@ 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] + VAR IR_TEMPORARY_VARIABLE name:tmp_19 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<*, *> @@ -1101,7 +1257,7 @@ FILE fqName: fileName:/grpc.kt 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_19: 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 @@ -1109,7 +1265,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_19: 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 @@ -1120,7 +1276,7 @@ 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] + VAR IR_TEMPORARY_VARIABLE name:tmp_20 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<*, *> @@ -1134,7 +1290,7 @@ FILE fqName: fileName:/grpc.kt 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_20: 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 @@ -1142,7 +1298,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_7: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_20: 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 @@ -1153,7 +1309,7 @@ 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_8 type:kotlin.String? [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_21 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<*, *> @@ -1167,7 +1323,7 @@ FILE fqName: fileName:/grpc.kt 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_8: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_21: 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 @@ -1175,7 +1331,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_8: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_21: 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 @@ -1186,7 +1342,7 @@ 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_9 type:kotlin.String? [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_22 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<*, *> @@ -1200,7 +1356,7 @@ FILE fqName: fileName:/grpc.kt 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_9: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG arg0: GET_VAR 'val tmp_22: 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 @@ -1208,7 +1364,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_9: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_22: 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 @@ -1237,7 +1393,7 @@ FILE fqName: fileName:/grpc.kt 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] + VAR IR_TEMPORARY_VARIABLE name:tmp_23 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<*, *> @@ -1251,7 +1407,7 @@ FILE fqName: fileName:/grpc.kt 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 arg0: GET_VAR 'val tmp_23: 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 @@ -1259,7 +1415,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_10: kotlin.String? declared in .box' type=kotlin.String? origin=null + ARG : GET_VAR 'val tmp_23: 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/diagnostics/grpc.fir.txt b/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.fir.txt index ed5d4d888..812f81f58 100644 --- a/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.fir.txt +++ b/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.fir.txt @@ -34,3 +34,45 @@ FILE: module_main_grpc.kt public get(): R|kotlinx/coroutines/flow/Flow| } + @R|kotlinx/rpc/grpc/annotations/Grpc|(protoPackage = String(-invalid name)) public abstract interface WrongAnnotations1 : R|kotlin/Any| { + public final class $rpcServiceStub : R|kotlin/Any| { + public final companion object Companion : R|kotlin/Any| { + } + + } + + } + @R|kotlinx/rpc/grpc/annotations/Grpc|(protoPackage = String(-invalid name)) public abstract interface WrongAnnotations2 : R|kotlin/Any| { + public final class $rpcServiceStub : R|kotlin/Any| { + public final companion object Companion : R|kotlin/Any| { + } + + } + + } + @R|kotlinx/rpc/grpc/annotations/Grpc|(protoPackage = (String(invalid.name), String( ))) public abstract interface WrongAnnotations3 : R|kotlin/Any| { + public final class $rpcServiceStub : R|kotlin/Any| { + public final companion object Companion : R|kotlin/Any| { + } + + } + + } + @R|kotlinx/rpc/grpc/annotations/Grpc|() public abstract interface WrongAnnotations4 : R|kotlin/Any| { + @R|kotlinx/rpc/grpc/annotations/Grpc.Method|(name = String(wrongName+1)) public abstract suspend fun wrongName1(): R|kotlin/Unit| + + @R|kotlinx/rpc/grpc/annotations/Grpc.Method|(name = String(wrongName+2)) public abstract suspend fun wrongName2(): R|kotlin/Unit| + + @R|kotlinx/rpc/grpc/annotations/Grpc.Method|(name = (String(wrongName), String(+3))) public abstract suspend fun wrongName3(): R|kotlin/Unit| + + @R|kotlinx/rpc/grpc/annotations/Grpc.Method|(safe = Boolean(true), idempotent = Boolean(false)) public abstract suspend fun wrongSafeIdempotent1(): R|kotlin/Unit| + + @R|kotlinx/rpc/grpc/annotations/Grpc.Method|(safe = Boolean(true)) public abstract suspend fun wrongSafeIdempotent2(): R|kotlin/Unit| + + public final class $rpcServiceStub : R|kotlin/Any| { + public final companion object Companion : R|kotlin/Any| { + } + + } + + } diff --git a/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.kt b/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.kt index d3870af4d..da6e0a9a1 100644 --- a/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.kt +++ b/tests/compiler-plugin-tests/src/testData/diagnostics/grpc.kt @@ -31,3 +31,30 @@ interface MyService { } class WithFlow(val flow: Flow) + +@Grpc("-invalid name") +interface WrongAnnotations1 + +@Grpc(protoPackage = "-invalid name") +interface WrongAnnotations2 + +@Grpc(protoPackage = "invalid.name" + " ") +interface WrongAnnotations3 + +@Grpc +interface WrongAnnotations4 { + @Grpc.Method("wrongName+1") + suspend fun wrongName1() + + @Grpc.Method(name = "wrongName+2") + suspend fun wrongName2() + + @Grpc.Method(name = "wrongName" + "+3") + suspend fun wrongName3() + + @Grpc.Method(safe = true, idempotent = false) + suspend fun wrongSafeIdempotent1() + + @Grpc.Method(safe = true) + suspend fun wrongSafeIdempotent2() +}