Skip to content

Commit b0a02d4

Browse files
committed
gRPC Initial Implementation (#262)
1 parent 7dad191 commit b0a02d4

File tree

78 files changed

+2977
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2977
-7
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ plugins {
88
alias(libs.plugins.serialization) apply false
99
alias(libs.plugins.kotlinx.rpc) apply false
1010
alias(libs.plugins.atomicfu) apply false
11+
alias(libs.plugins.protobuf) apply false
1112
alias(libs.plugins.conventions.root)
1213
}
1314

compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcIrContext.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ internal class RpcIrContext(
7373
getRpcIrClassSymbol("RpcServiceDescriptor", "descriptor")
7474
}
7575

76+
val grpcServiceDescriptor by lazy {
77+
getIrClassSymbol("kotlinx.rpc.grpc.descriptor", "GrpcServiceDescriptor")
78+
}
79+
80+
val grpcDelegate by lazy {
81+
getIrClassSymbol("kotlinx.rpc.grpc.descriptor", "GrpcDelegate")
82+
}
83+
7684
val rpcType by lazy {
7785
getRpcIrClassSymbol("RpcType", "descriptor")
7886
}
@@ -210,6 +218,10 @@ internal class RpcIrContext(
210218
rpcServiceDescriptor.namedProperty("fqName")
211219
}
212220

221+
val grpcServiceDescriptorDelegate by lazy {
222+
grpcServiceDescriptor.namedProperty("delegate")
223+
}
224+
213225
private fun IrClassSymbol.namedProperty(name: String): IrPropertySymbol {
214226
return owner.properties.single { it.name.asString() == name }.symbol
215227
}
@@ -224,7 +236,7 @@ internal class RpcIrContext(
224236
return getIrClassSymbol("kotlinx.rpc$suffix", name)
225237
}
226238

227-
private fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
239+
fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
228240
return versionSpecificApi.referenceClass(pluginContext, packageName, name)
229241
?: error("Unable to find symbol. Package: $packageName, name: $name")
230242
}

compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcIrServiceProcessor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ internal class RpcIrServiceProcessor(
1515
private val logger: MessageCollector,
1616
) {
1717
fun visitClass(declaration: IrClass, data: RpcIrContext) {
18-
if (declaration.hasAnnotation(RpcClassId.rpcAnnotation) && declaration.isInterface) {
18+
if ((declaration.hasAnnotation(RpcClassId.rpcAnnotation)
19+
|| declaration.hasAnnotation(RpcClassId.grpcAnnotation)) && declaration.isInterface
20+
) {
1921
processService(declaration, data)
2022
}
2123
}

compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/RpcStubGenerator.kt

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ private object Descriptor {
8989
const val CREATE_INSTANCE = "createInstance"
9090
}
9191

92+
private object GrpcDescriptor {
93+
const val DELEGATE = "delegate"
94+
}
95+
9296
@Suppress("detekt.LargeClass", "detekt.TooManyFunctions")
9397
internal class RpcStubGenerator(
9498
private val declaration: ServiceDeclaration,
@@ -498,7 +502,10 @@ internal class RpcStubGenerator(
498502
stubCompanionObjectThisReceiver = thisReceiver
499503
?: error("Stub companion object expected to have thisReceiver: ${name.asString()}")
500504

501-
superTypes = listOf(ctx.rpcServiceDescriptor.typeWith(declaration.serviceType))
505+
superTypes = listOfNotNull(
506+
ctx.rpcServiceDescriptor.typeWith(declaration.serviceType),
507+
if (declaration.isGrpc) ctx.grpcServiceDescriptor.typeWith(declaration.serviceType) else null,
508+
)
502509

503510
generateCompanionObjectConstructor()
504511

@@ -529,6 +536,10 @@ internal class RpcStubGenerator(
529536
generateGetCallableFunction()
530537

531538
generateCreateInstanceFunction()
539+
540+
if (declaration.isGrpc) {
541+
generateGrpcDelegateProperty()
542+
}
532543
}
533544

534545
/**
@@ -1046,6 +1057,42 @@ internal class RpcStubGenerator(
10461057
}
10471058
}
10481059

1060+
/**
1061+
* override val delegate: GrpcDelegate = MyServiceDelegate
1062+
*/
1063+
private fun IrClass.generateGrpcDelegateProperty() {
1064+
addProperty {
1065+
name = Name.identifier(GrpcDescriptor.DELEGATE)
1066+
visibility = DescriptorVisibilities.PUBLIC
1067+
}.apply {
1068+
overriddenSymbols = listOf(ctx.properties.grpcServiceDescriptorDelegate)
1069+
1070+
addBackingFieldUtil {
1071+
visibility = DescriptorVisibilities.PRIVATE
1072+
type = ctx.grpcDelegate.defaultType
1073+
vsApi { isFinalVS = true }
1074+
}.apply {
1075+
initializer = factory.createExpressionBody(
1076+
IrGetObjectValueImpl(
1077+
startOffset = UNDEFINED_OFFSET,
1078+
endOffset = UNDEFINED_OFFSET,
1079+
type = ctx.grpcDelegate.defaultType,
1080+
symbol = ctx.getIrClassSymbol(
1081+
declaration.service.packageFqName?.asString()
1082+
?: error("Expected package name fro service ${declaration.service.name}"),
1083+
"${declaration.service.name.asString()}Delegate",
1084+
),
1085+
)
1086+
)
1087+
}
1088+
1089+
addDefaultGetter(this@generateGrpcDelegateProperty, ctx.irBuiltIns) {
1090+
visibility = DescriptorVisibilities.PUBLIC
1091+
overriddenSymbols = listOf(ctx.properties.grpcServiceDescriptorDelegate.owner.getterOrFail.symbol)
1092+
}
1093+
}
1094+
}
1095+
10491096
// Associated object annotation works on JS, WASM, and Native platforms.
10501097
// See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/find-associated-object.html
10511098
private fun addAssociatedObjectAnnotationIfPossible() {

compiler-plugin/compiler-plugin-backend/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44

55
package kotlinx.rpc.codegen.extension
66

7+
import kotlinx.rpc.codegen.common.RpcClassId
78
import org.jetbrains.kotlin.ir.declarations.IrClass
89
import org.jetbrains.kotlin.ir.declarations.IrProperty
910
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
1011
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
1112
import org.jetbrains.kotlin.ir.types.IrType
1213
import org.jetbrains.kotlin.ir.util.defaultType
14+
import org.jetbrains.kotlin.ir.util.hasAnnotation
1315
import org.jetbrains.kotlin.ir.util.kotlinFqName
1416

1517
class ServiceDeclaration(
1618
val service: IrClass,
1719
val stubClass: IrClass,
1820
val methods: List<Method>,
1921
) {
22+
val isGrpc = service.hasAnnotation(RpcClassId.grpcAnnotation)
2023
val fqName = service.kotlinFqName.asString()
2124

2225
val serviceType = service.defaultType

compiler-plugin/compiler-plugin-common/src/main/kotlin/kotlinx/rpc/codegen/common/Names.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.name.Name
1010

1111
object RpcClassId {
1212
val rpcAnnotation = ClassId(FqName("kotlinx.rpc.annotations"), Name.identifier("Rpc"))
13+
val grpcAnnotation = ClassId(FqName("kotlinx.rpc.grpc.annotations"), Name.identifier("Grpc"))
1314
val checkedTypeAnnotation = ClassId(FqName("kotlinx.rpc.annotations"), Name.identifier("CheckedTypeAnnotation"))
1415

1516
val serializableAnnotation = ClassId(FqName("kotlinx.serialization"), Name.identifier("Serializable"))

compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/FirGenerationKeys.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
1010
import org.jetbrains.kotlin.name.Name
1111

1212
internal class RpcGeneratedStubKey(
13+
val isGrpc: Boolean,
1314
private val serviceName: Name,
1415
) : GeneratedDeclarationKey() {
1516
override fun toString(): String {

compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/FirRpcAdditionalCheckers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class FirRpcAdditionalCheckers(
2323
) : FirAdditionalCheckersExtension(session) {
2424
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
2525
register(FirRpcPredicates.rpc)
26+
register(FirRpcPredicates.grpc)
2627
register(FirRpcPredicates.checkedAnnotationMeta)
2728
}
2829

compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/FirRpcPredicates.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ object FirRpcPredicates {
1616
metaAnnotated(RpcClassId.rpcAnnotation.asSingleFqName(), includeItself = true)
1717
}
1818

19+
internal val grpc = DeclarationPredicate.create {
20+
annotated(RpcClassId.grpcAnnotation.asSingleFqName()) // @Grpc
21+
}
22+
1923
internal val checkedAnnotationMeta = DeclarationPredicate.create {
2024
metaAnnotated(RpcClassId.checkedTypeAnnotation.asSingleFqName(), includeItself = false)
2125
}

compiler-plugin/compiler-plugin-k2/src/main/kotlin/kotlinx/rpc/codegen/FirRpcServiceGenerator.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class FirRpcServiceGenerator(
2323
) : FirDeclarationGenerationExtension(session) {
2424
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
2525
register(FirRpcPredicates.rpc)
26+
register(FirRpcPredicates.grpc)
2627
}
2728

2829
/**
@@ -51,7 +52,10 @@ class FirRpcServiceGenerator(
5152
setOf(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT)
5253
}
5354

54-
classSymbol.isInterface && session.predicateBasedProvider.matches(FirRpcPredicates.rpc, classSymbol) -> {
55+
classSymbol.isInterface && (
56+
session.predicateBasedProvider.matches(FirRpcPredicates.rpc, classSymbol) ||
57+
session.predicateBasedProvider.matches(FirRpcPredicates.grpc, classSymbol)
58+
) -> {
5559
setOf(RpcNames.SERVICE_STUB_NAME)
5660
}
5761

0 commit comments

Comments
 (0)