Skip to content

Commit 0c1dd6a

Browse files
authored
Add integration tests for gRPC + Protoc generated files (#444)
1 parent 43f48b4 commit 0c1dd6a

File tree

76 files changed

+1066
-684
lines changed

Some content is hidden

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

76 files changed

+1066
-684
lines changed

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

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package kotlinx.rpc.codegen.checkers
66

77
import kotlinx.rpc.codegen.FirRpcPredicates
8-
import kotlinx.rpc.codegen.FirVersionSpecificApiImpl.toClassSymbolVS
98
import kotlinx.rpc.codegen.checkers.diagnostics.FirGrpcDiagnostics
109
import kotlinx.rpc.codegen.common.RpcClassId
1110
import kotlinx.rpc.codegen.vsApi
@@ -20,7 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
2019
import org.jetbrains.kotlin.fir.declarations.getKClassArgument
2120
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
2221
import org.jetbrains.kotlin.fir.resolve.defaultType
23-
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
22+
import org.jetbrains.kotlin.fir.resolve.getSuperTypes
2423
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
2524
import org.jetbrains.kotlin.fir.types.ConeKotlinType
2625
import org.jetbrains.kotlin.fir.types.classId
@@ -55,9 +54,7 @@ object FirWithCodecDeclarationChecker {
5554
"for declaration: ${declaration.symbol.classId.asSingleFqName()}"
5655
)
5756

58-
val codecTargetClass = codecClassSymbol.findMessageCodecSuperType(context.session)
59-
.typeArguments.first().type
60-
?: error("Unexpected unresolved type argument for @WithCodec annotation")
57+
val codecTargetClass = codecClassSymbol.resolveMessageCodecTypeArgument(context.session)
6158

6259
if (codecTargetClass.classId != declaration.symbol.classId) {
6360
reporter.reportOn(
@@ -78,12 +75,13 @@ object FirWithCodecDeclarationChecker {
7875
}
7976
}
8077

81-
private fun FirClassSymbol<*>.findMessageCodecSuperType(session: FirSession): ConeKotlinType = vsApi {
82-
return resolvedSuperTypes.find {
83-
it.classId == RpcClassId.messageCodec
84-
} ?: resolvedSuperTypes.firstNotNullOf {
85-
it.toClassSymbolVS(session)?.findMessageCodecSuperType(session)
86-
}
78+
private fun FirClassSymbol<*>.resolveMessageCodecTypeArgument(session: FirSession): ConeKotlinType = vsApi {
79+
val superTypes = getSuperTypes(session, recursive = true, lookupInterfaces = true, substituteSuperTypes = true)
80+
81+
return superTypes
82+
.find { it.classId == RpcClassId.messageCodec }
83+
?.typeArguments?.single()?.type
84+
?: error("'MessageCodec' supertype not found for $classId")
8785
}
8886

8987
private val CODEC_ARGUMENT_NAME = Name.identifier("codec")

core/api/core.api

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ public abstract interface class kotlinx/rpc/descriptor/RpcInvokator$FlowResponse
4444
public abstract fun call (Ljava/lang/Object;[Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
4545
}
4646

47-
public abstract interface class kotlinx/rpc/descriptor/RpcInvokator$Method : kotlinx/rpc/descriptor/RpcInvokator {
48-
public abstract fun call (Ljava/lang/Object;[Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
49-
}
50-
5147
public abstract interface class kotlinx/rpc/descriptor/RpcInvokator$UnaryResponse : kotlinx/rpc/descriptor/RpcInvokator {
5248
public abstract fun call (Ljava/lang/Object;[Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
5349
}

grpc/grpc-codec-kotlinx-serialization/api/grpc-codec-kotlinx-serialization.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public final class kotlinx/rpc/grpc/codec/kotlinx/serialization/KotlinxSerializationCodecResolver : kotlinx/rpc/grpc/codec/MessageCodecResolver {
22
public fun <init> (Lkotlinx/serialization/SerialFormat;)V
3-
public fun resolve (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
3+
public fun resolveOrNull (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
44
}
55

66
public final class kotlinx/rpc/grpc/codec/kotlinx/serialization/KotlinxSerializationCodecResolverKt {

grpc/grpc-codec-kotlinx-serialization/api/grpc-codec-kotlinx-serialization.klib.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
final class kotlinx.rpc.grpc.codec.kotlinx.serialization/KotlinxSerializationCodecResolver : kotlinx.rpc.grpc.codec/MessageCodecResolver { // kotlinx.rpc.grpc.codec.kotlinx.serialization/KotlinxSerializationCodecResolver|null[0]
1010
constructor <init>(kotlinx.serialization/SerialFormat) // kotlinx.rpc.grpc.codec.kotlinx.serialization/KotlinxSerializationCodecResolver.<init>|<init>(kotlinx.serialization.SerialFormat){}[0]
1111

12-
final fun resolve(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*> // kotlinx.rpc.grpc.codec.kotlinx.serialization/KotlinxSerializationCodecResolver.resolve|resolve(kotlin.reflect.KType){}[0]
12+
final fun resolveOrNull(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*>? // kotlinx.rpc.grpc.codec.kotlinx.serialization/KotlinxSerializationCodecResolver.resolveOrNull|resolveOrNull(kotlin.reflect.KType){}[0]
1313
}
1414

1515
final fun (kotlinx.serialization/SerialFormat).kotlinx.rpc.grpc.codec.kotlinx.serialization/asCodecResolver(): kotlinx.rpc.grpc.codec/MessageCodecResolver // kotlinx.rpc.grpc.codec.kotlinx.serialization/asCodecResolver|[email protected](){}[0]

grpc/grpc-codec-kotlinx-serialization/src/commonMain/kotlin/kotlinx/rpc/grpc/codec/kotlinx/serialization/KotlinxSerializationCodecResolver.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import kotlinx.io.readString
1111
import kotlinx.io.writeString
1212
import kotlinx.rpc.grpc.codec.MessageCodec
1313
import kotlinx.rpc.grpc.codec.MessageCodecResolver
14+
import kotlinx.rpc.grpc.codec.SourcedMessageCodec
1415
import kotlinx.rpc.internal.utils.ExperimentalRpcApi
1516
import kotlinx.serialization.BinaryFormat
1617
import kotlinx.serialization.KSerializer
1718
import kotlinx.serialization.SerialFormat
1819
import kotlinx.serialization.StringFormat
19-
import kotlinx.serialization.serializer
2020
import kotlinx.serialization.serializerOrNull
2121
import kotlin.reflect.KType
2222

@@ -36,8 +36,8 @@ public fun SerialFormat.asCodecResolver(): MessageCodecResolver =
3636
private class KotlinxSerializationCodec<T>(
3737
private val serializer: KSerializer<T>,
3838
private val serialFormat: SerialFormat,
39-
) : MessageCodec<T> {
40-
override fun encode(value: T): Source {
39+
) : SourcedMessageCodec<T> {
40+
override fun encodeToSource(value: T): Source {
4141
return when (serialFormat) {
4242
is StringFormat -> {
4343
val stringValue = serialFormat.encodeToString(serializer, value)
@@ -59,7 +59,7 @@ private class KotlinxSerializationCodec<T>(
5959
}
6060
}
6161

62-
override fun decode(stream: Source): T {
62+
override fun decodeFromSource(stream: Source): T {
6363
return when (serialFormat) {
6464
is StringFormat -> {
6565
serialFormat.decodeFromString(serializer, stream.readString())

grpc/grpc-codec/api/grpc-codec.api

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
public final class kotlinx/rpc/grpc/codec/EmptyMessageCodecResolver : kotlinx/rpc/grpc/codec/MessageCodecResolver {
22
public static final field INSTANCE Lkotlinx/rpc/grpc/codec/EmptyMessageCodecResolver;
3-
public fun resolve (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
3+
public fun resolveOrNull (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
44
}
55

66
public abstract interface class kotlinx/rpc/grpc/codec/MessageCodec {
7-
public abstract fun decode (Lkotlinx/io/Source;)Ljava/lang/Object;
8-
public abstract fun encode (Ljava/lang/Object;)Lkotlinx/io/Source;
7+
public abstract fun decode (Ljava/io/InputStream;)Ljava/lang/Object;
8+
public abstract fun encode (Ljava/lang/Object;)Ljava/io/InputStream;
9+
}
10+
11+
public final class kotlinx/rpc/grpc/codec/MessageCodecKt {
12+
public static final fun plus (Lkotlinx/rpc/grpc/codec/MessageCodecResolver;Lkotlinx/rpc/grpc/codec/MessageCodecResolver;)Lkotlinx/rpc/grpc/codec/MessageCodecResolver;
913
}
1014

1115
public abstract interface class kotlinx/rpc/grpc/codec/MessageCodecResolver {
12-
public abstract fun resolve (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
16+
public abstract fun resolveOrNull (Lkotlin/reflect/KType;)Lkotlinx/rpc/grpc/codec/MessageCodec;
17+
}
18+
19+
public abstract interface class kotlinx/rpc/grpc/codec/SourcedMessageCodec : kotlinx/rpc/grpc/codec/MessageCodec {
20+
public abstract fun decode (Ljava/io/InputStream;)Ljava/lang/Object;
21+
public abstract fun decodeFromSource (Lkotlinx/io/Source;)Ljava/lang/Object;
22+
public abstract fun encode (Ljava/lang/Object;)Ljava/io/InputStream;
23+
public abstract fun encodeToSource (Ljava/lang/Object;)Lkotlinx/io/Source;
24+
}
25+
26+
public final class kotlinx/rpc/grpc/codec/SourcedMessageCodec$DefaultImpls {
27+
public static fun decode (Lkotlinx/rpc/grpc/codec/SourcedMessageCodec;Ljava/io/InputStream;)Ljava/lang/Object;
28+
public static fun encode (Lkotlinx/rpc/grpc/codec/SourcedMessageCodec;Ljava/lang/Object;)Ljava/io/InputStream;
1329
}
1430

1531
public abstract interface annotation class kotlinx/rpc/grpc/codec/WithCodec : java/lang/annotation/Annotation {

grpc/grpc-codec/api/grpc-codec.klib.api

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Klib ABI Dump
22
// Targets: [iosArm64, iosSimulatorArm64, iosX64, js, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, wasmJs, wasmWasi, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64]
3+
// Alias: native => [iosArm64, iosSimulatorArm64, iosX64, linuxArm64, linuxX64, macosArm64, macosX64, mingwX64, tvosArm64, tvosSimulatorArm64, tvosX64, watchosArm32, watchosArm64, watchosDeviceArm64, watchosSimulatorArm64, watchosX64]
34
// Rendering settings:
45
// - Signature version: 2
56
// - Show manifest properties: true
@@ -14,14 +15,42 @@ open annotation class kotlinx.rpc.grpc.codec/WithCodec : kotlin/Annotation { //
1415
}
1516

1617
abstract fun interface kotlinx.rpc.grpc.codec/MessageCodecResolver { // kotlinx.rpc.grpc.codec/MessageCodecResolver|null[0]
17-
abstract fun resolve(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*> // kotlinx.rpc.grpc.codec/MessageCodecResolver.resolve|resolve(kotlin.reflect.KType){}[0]
18+
abstract fun resolveOrNull(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*>? // kotlinx.rpc.grpc.codec/MessageCodecResolver.resolveOrNull|resolveOrNull(kotlin.reflect.KType){}[0]
1819
}
1920

2021
abstract interface <#A: kotlin/Any?> kotlinx.rpc.grpc.codec/MessageCodec { // kotlinx.rpc.grpc.codec/MessageCodec|null[0]
21-
abstract fun decode(kotlinx.io/Source): #A // kotlinx.rpc.grpc.codec/MessageCodec.decode|decode(kotlinx.io.Source){}[0]
22-
abstract fun encode(#A): kotlinx.io/Source // kotlinx.rpc.grpc.codec/MessageCodec.encode|encode(1:0){}[0]
22+
// Targets: [native]
23+
abstract fun decode(kotlinx.rpc.protobuf.input.stream/BufferInputStream): #A // kotlinx.rpc.grpc.codec/MessageCodec.decode|decode(kotlinx.rpc.protobuf.input.stream.BufferInputStream){}[0]
24+
25+
// Targets: [native]
26+
abstract fun encode(#A): kotlinx.rpc.protobuf.input.stream/BufferInputStream // kotlinx.rpc.grpc.codec/MessageCodec.encode|encode(1:0){}[0]
27+
28+
// Targets: [js, wasmJs, wasmWasi]
29+
abstract fun decode(kotlinx.rpc.protobuf.input.stream/InputStream): #A // kotlinx.rpc.grpc.codec/MessageCodec.decode|decode(kotlinx.rpc.protobuf.input.stream.InputStream){}[0]
30+
31+
// Targets: [js, wasmJs, wasmWasi]
32+
abstract fun encode(#A): kotlinx.rpc.protobuf.input.stream/InputStream // kotlinx.rpc.grpc.codec/MessageCodec.encode|encode(1:0){}[0]
33+
}
34+
35+
abstract interface <#A: kotlin/Any?> kotlinx.rpc.grpc.codec/SourcedMessageCodec : kotlinx.rpc.grpc.codec/MessageCodec<#A> { // kotlinx.rpc.grpc.codec/SourcedMessageCodec|null[0]
36+
abstract fun decodeFromSource(kotlinx.io/Source): #A // kotlinx.rpc.grpc.codec/SourcedMessageCodec.decodeFromSource|decodeFromSource(kotlinx.io.Source){}[0]
37+
abstract fun encodeToSource(#A): kotlinx.io/Source // kotlinx.rpc.grpc.codec/SourcedMessageCodec.encodeToSource|encodeToSource(1:0){}[0]
38+
39+
// Targets: [native]
40+
open fun decode(kotlinx.rpc.protobuf.input.stream/BufferInputStream): #A // kotlinx.rpc.grpc.codec/SourcedMessageCodec.decode|decode(kotlinx.rpc.protobuf.input.stream.BufferInputStream){}[0]
41+
42+
// Targets: [native]
43+
open fun encode(#A): kotlinx.rpc.protobuf.input.stream/BufferInputStream // kotlinx.rpc.grpc.codec/SourcedMessageCodec.encode|encode(1:0){}[0]
44+
45+
// Targets: [js, wasmJs, wasmWasi]
46+
open fun decode(kotlinx.rpc.protobuf.input.stream/InputStream): #A // kotlinx.rpc.grpc.codec/SourcedMessageCodec.decode|decode(kotlinx.rpc.protobuf.input.stream.InputStream){}[0]
47+
48+
// Targets: [js, wasmJs, wasmWasi]
49+
open fun encode(#A): kotlinx.rpc.protobuf.input.stream/InputStream // kotlinx.rpc.grpc.codec/SourcedMessageCodec.encode|encode(1:0){}[0]
2350
}
2451

2552
final object kotlinx.rpc.grpc.codec/EmptyMessageCodecResolver : kotlinx.rpc.grpc.codec/MessageCodecResolver { // kotlinx.rpc.grpc.codec/EmptyMessageCodecResolver|null[0]
26-
final fun resolve(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*> // kotlinx.rpc.grpc.codec/EmptyMessageCodecResolver.resolve|resolve(kotlin.reflect.KType){}[0]
53+
final fun resolveOrNull(kotlin.reflect/KType): kotlinx.rpc.grpc.codec/MessageCodec<*>? // kotlinx.rpc.grpc.codec/EmptyMessageCodecResolver.resolveOrNull|resolveOrNull(kotlin.reflect.KType){}[0]
2754
}
55+
56+
final fun (kotlinx.rpc.grpc.codec/MessageCodecResolver).kotlinx.rpc.grpc.codec/plus(kotlinx.rpc.grpc.codec/MessageCodecResolver): kotlinx.rpc.grpc.codec/MessageCodecResolver // kotlinx.rpc.grpc.codec/plus|[email protected](kotlinx.rpc.grpc.codec.MessageCodecResolver){}[0]

grpc/grpc-codec/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ plugins {
77
}
88

99
kotlin {
10+
compilerOptions {
11+
freeCompilerArgs.add("-Xexpect-actual-classes")
12+
}
13+
1014
sourceSets {
1115
commonMain {
1216
dependencies {
1317
api(projects.utils)
18+
api(projects.protobuf.protobufInputStream)
1419
api(libs.kotlinx.io.core)
1520
}
1621
}

grpc/grpc-codec/src/commonMain/kotlin/kotlinx/rpc/grpc/codec/MessageCodec.kt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ package kotlinx.rpc.grpc.codec
77
import kotlinx.io.Source
88
import kotlinx.rpc.internal.utils.ExperimentalRpcApi
99
import kotlinx.rpc.internal.utils.InternalRpcApi
10+
import kotlinx.rpc.protobuf.input.stream.InputStream
11+
import kotlinx.rpc.protobuf.input.stream.asInputStream
12+
import kotlinx.rpc.protobuf.input.stream.asSource
1013
import kotlin.reflect.KType
1114

1215
@ExperimentalRpcApi
@@ -30,8 +33,22 @@ public operator fun MessageCodecResolver.plus(other: MessageCodecResolver): Mess
3033

3134
@ExperimentalRpcApi
3235
public interface MessageCodec<T> {
33-
public fun encode(value: T): Source
34-
public fun decode(stream: Source): T
36+
public fun encode(value: T): InputStream
37+
public fun decode(stream: InputStream): T
38+
}
39+
40+
@ExperimentalRpcApi
41+
public interface SourcedMessageCodec<T> : MessageCodec<T> {
42+
public fun encodeToSource(value: T): Source
43+
public fun decodeFromSource(stream: Source): T
44+
45+
override fun encode(value: T): InputStream {
46+
return encodeToSource(value).asInputStream()
47+
}
48+
49+
override fun decode(stream: InputStream): T {
50+
return decodeFromSource(stream.asSource())
51+
}
3552
}
3653

3754
@InternalRpcApi

grpc/grpc-core/api/grpc-core.api

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,3 @@ public final class kotlinx/rpc/grpc/Status_jvmKt {
9999
public abstract interface annotation class kotlinx/rpc/grpc/annotations/Grpc : java/lang/annotation/Annotation {
100100
}
101101

102-
public abstract interface class kotlinx/rpc/grpc/descriptor/GrpcClientDelegate {
103-
public abstract fun call (Lkotlinx/rpc/RpcCall;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
104-
public abstract fun callServerStreaming (Lkotlinx/rpc/RpcCall;)Lkotlinx/coroutines/flow/Flow;
105-
}
106-
107-
public abstract interface class kotlinx/rpc/grpc/descriptor/GrpcDelegate {
108-
public abstract fun clientProvider (Lkotlinx/rpc/grpc/ManagedChannel;)Lkotlinx/rpc/grpc/descriptor/GrpcClientDelegate;
109-
public abstract fun definitionFor (Ljava/lang/Object;)Lio/grpc/ServerServiceDefinition;
110-
}
111-

0 commit comments

Comments
 (0)