Skip to content

Commit 220968c

Browse files
committed
Added RpcServiceDescriptor declarations
1 parent 6407b9d commit 220968c

File tree

20 files changed

+224
-350
lines changed

20 files changed

+224
-350
lines changed

core/src/commonMain/kotlin/kotlinx/rpc/awaitFieldInitialization.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
package kotlinx.rpc
66

7+
import kotlinx.rpc.descriptor.serviceDescriptorOf
78
import kotlinx.rpc.internal.RPCDeferredField
8-
import kotlinx.rpc.internal.RPCServiceFieldsProvider
9-
import kotlinx.rpc.internal.findRPCStubProvider
10-
import kotlinx.rpc.internal.utils.safeCast
119
import kotlin.reflect.KClass
1210

1311
/**
@@ -81,8 +79,8 @@ public suspend inline fun <reified T : RemoteService> T.awaitFieldInitialization
8179
* @return specified service, after all of it's field were initialized.
8280
*/
8381
public suspend fun <T : RemoteService> T.awaitFieldInitialization(kClass: KClass<T>): T {
84-
findRPCStubProvider<RPCServiceFieldsProvider<T>>(kClass, RPCServiceFieldsProvider::class.safeCast())
85-
.rpcFields(this)
82+
serviceDescriptorOf(kClass)
83+
.getFields(this)
8684
.forEach { field ->
8785
field.await()
8886
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.rpc.descriptor
6+
7+
import kotlinx.rpc.RPCClient
8+
import kotlinx.rpc.RemoteService
9+
import kotlinx.rpc.internal.*
10+
import kotlinx.rpc.internal.utils.ExperimentalRPCApi
11+
import kotlin.reflect.KClass
12+
import kotlin.reflect.KType
13+
14+
@ExperimentalRPCApi
15+
public inline fun <reified T : RemoteService> serviceDescriptorOf(): RpcServiceDescriptor<T> {
16+
return serviceDescriptorOf(T::class)
17+
}
18+
19+
@ExperimentalRPCApi
20+
public fun <T : RemoteService> serviceDescriptorOf(kType: KType): RpcServiceDescriptor<T> {
21+
return serviceDescriptorOf(kType.kClass())
22+
}
23+
24+
@ExperimentalRPCApi
25+
public fun <T : RemoteService> serviceDescriptorOf(kClass: KClass<T>): RpcServiceDescriptor<T> {
26+
val maybeDescriptor = internalServiceDescriptorOf(kClass)
27+
?: internalError("Unable to find a service descriptor of the $kClass")
28+
29+
if (RpcServiceDescriptor::class.isInstance(maybeDescriptor)) {
30+
@Suppress("UNCHECKED_CAST")
31+
return maybeDescriptor as RpcServiceDescriptor<T>
32+
}
33+
34+
internalError(
35+
"Located descriptor object is not of a desired type ${RpcServiceDescriptor::class}, " +
36+
"instead found $maybeDescriptor of the class " +
37+
(maybeDescriptor::class.qualifiedClassNameOrNull ?: maybeDescriptor::class)
38+
)
39+
}
40+
41+
@ExperimentalRPCApi
42+
public interface RpcServiceDescriptor<T : RemoteService> {
43+
public val fqName: String
44+
45+
public fun getFields(service: T): List<RPCDeferredField<*>>
46+
47+
public fun getCallable(name: String): RpcCallable<T>?
48+
49+
public fun createInstance(serviceId: Long, client: RPCClient): T
50+
}
51+
52+
@ExperimentalRPCApi
53+
public data class RpcCallable<T : RemoteService>(
54+
public val name: String,
55+
public val dataType: KType,
56+
public val returnType: KType,
57+
public val invokator: RpcInvokator<T>,
58+
public val parameters: List<RpcParameter>,
59+
)
60+
61+
@ExperimentalRPCApi
62+
public sealed interface RpcInvokator<T : RemoteService> {
63+
@ExperimentalRPCApi
64+
public interface Method<T : RemoteService> : RpcInvokator<T> {
65+
public suspend fun call(service: T, data: Any?): Any?
66+
}
67+
68+
@ExperimentalRPCApi
69+
public interface Field<T : RemoteService> : RpcInvokator<T> {
70+
public fun call(service: T): Any?
71+
}
72+
}
73+
74+
@ExperimentalRPCApi
75+
public data class RpcParameter(val name: String, val type: KType)

core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCMethodClassArguments.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt

Lines changed: 0 additions & 31 deletions
This file was deleted.

core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt renamed to core/src/commonMain/kotlin/kotlinx/rpc/internal/internalServiceDescriptorOf.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
package kotlinx.rpc.internal
66

7-
import kotlinx.rpc.internal.utils.InternalRPCApi
7+
import kotlinx.rpc.RemoteService
88
import kotlin.reflect.KClass
99

10-
@InternalRPCApi
11-
public expect fun <R : Any> findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass<R>): R
10+
internal expect fun <T : RemoteService> internalServiceDescriptorOf(kClass: KClass<T>): Any?

core/src/commonMain/kotlin/kotlinx/rpc/withService.kt

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

77
import kotlinx.atomicfu.atomic
8-
import kotlinx.rpc.internal.RPCStubServiceProvider
9-
import kotlinx.rpc.internal.findRPCStubProvider
8+
import kotlinx.rpc.descriptor.serviceDescriptorOf
109
import kotlinx.rpc.internal.kClass
11-
import kotlinx.rpc.internal.utils.safeCast
1210
import kotlin.reflect.KClass
1311
import kotlin.reflect.KType
1412

@@ -53,12 +51,9 @@ private val SERVICE_ID = atomic(0L)
5351
* @return instance of the generated service.
5452
*/
5553
public fun <T : RemoteService> RPCClient.withService(serviceKClass: KClass<T>): T {
56-
val provider = findRPCStubProvider<RPCStubServiceProvider<T>>(
57-
kClass = serviceKClass,
58-
resultKClass = RPCStubServiceProvider::class.safeCast(),
59-
)
54+
val descriptor = serviceDescriptorOf(serviceKClass)
6055

6156
val id = SERVICE_ID.incrementAndGet()
6257

63-
return provider.withClient(id, this)
58+
return descriptor.createInstance(id, this)
6459
}

core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt renamed to core/src/jsMain/kotlin/kotlinx/rpc/internal/internalServiceDescriptorOf.js.kt

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
@file:Suppress("detekt.MatchingDeclarationName")
6-
75
package kotlinx.rpc.internal
86

97
import js.objects.Object
108
import kotlinx.rpc.RemoteService
9+
import kotlinx.rpc.descriptor.RpcServiceDescriptor
1110
import kotlinx.rpc.internal.utils.InternalRPCApi
1211
import kotlin.reflect.AssociatedObjectKey
1312
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -18,26 +17,13 @@ import kotlin.reflect.findAssociatedObject
1817
@AssociatedObjectKey
1918
@OptIn(ExperimentalAssociatedObjects::class)
2019
@Target(AnnotationTarget.CLASS)
21-
public annotation class WithRPCStubObject(
20+
public annotation class WithServiceDescriptor(
2221
@Suppress("unused")
23-
val stub: KClass<out RPCStubObject<out RemoteService>>,
22+
val stub: KClass<out RpcServiceDescriptor<out RemoteService>>,
2423
)
2524

26-
@InternalRPCApi
27-
public actual fun <R : Any> findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass<R>): R {
28-
val associatedObject = kClass.findAssociatedObjectImpl(WithRPCStubObject::class, resultKClass)
29-
?: internalError("Unable to find $kClass associated object")
30-
31-
if (resultKClass.isInstance(associatedObject)) {
32-
@Suppress("UNCHECKED_CAST")
33-
return associatedObject as R
34-
}
35-
36-
internalError(
37-
"Located associated object is not of desired type $resultKClass, " +
38-
"instead found $associatedObject of class " +
39-
(associatedObject::class.qualifiedClassNameOrNull ?: associatedObject::class.js.name)
40-
)
25+
internal actual fun <T : RemoteService> internalServiceDescriptorOf(kClass: KClass<T>): Any? {
26+
return kClass.findAssociatedObjectImpl(WithServiceDescriptor::class)
4127
}
4228

4329
/**
@@ -46,22 +32,19 @@ public actual fun <R : Any> findRPCStubProvider(kClass: KClass<*>, resultKClass:
4632
*
4733
* This function uses std-lib's implementation and accounts for the bug in the compiler
4834
*/
49-
internal fun <T : Annotation, R : Any> KClass<*>.findAssociatedObjectImpl(
50-
annotationClass: KClass<T>,
51-
resultKClass: KClass<R>,
52-
): Any? {
35+
internal fun <T : Annotation> KClass<*>.findAssociatedObjectImpl(annotationClass: KClass<T>): Any? {
5336
val key = annotationClass.js.asDynamic().`$metadata$`?.associatedObjectKey?.unsafeCast<Int>() ?: return null
5437
val map = js.asDynamic().`$metadata$`?.associatedObjects ?: return null
55-
val factory = map[key] ?: return fallbackFindAssociatedObjectImpl(map, resultKClass)
38+
val factory = map[key] ?: return fallbackFindAssociatedObjectImpl(map)
5639
return factory()
5740
}
5841

59-
private fun <R : Any> fallbackFindAssociatedObjectImpl(map: dynamic, resultKClass: KClass<R>): R? {
42+
private fun <R : Any> fallbackFindAssociatedObjectImpl(map: dynamic): R? {
6043
return Object.entries(map as Any)
6144
.mapNotNull { (_, factory) ->
6245
val unsafeFactory = factory.asDynamic()
6346
val maybeObject = unsafeFactory()
64-
if (resultKClass.isInstance(maybeObject)) {
47+
if (RpcServiceDescriptor::class.isInstance(maybeObject)) {
6548
maybeObject.unsafeCast<R>()
6649
} else {
6750
null

core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.rpc.internal
6+
7+
import kotlinx.rpc.RemoteService
8+
import kotlin.reflect.KClass
9+
import kotlin.reflect.full.companionObjectInstance
10+
11+
private const val RPC_SERVICE_STUB_SIMPLE_NAME = "\$rpcServiceStub"
12+
13+
internal actual fun <T : RemoteService> internalServiceDescriptorOf(kClass: KClass<T>): Any? {
14+
val className = "${kClass.qualifiedName}\$$RPC_SERVICE_STUB_SIMPLE_NAME"
15+
16+
return kClass.java.classLoader
17+
.loadClass(className)
18+
?.kotlin
19+
?.companionObjectInstance
20+
}

core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)