Skip to content

Commit 755a8c7

Browse files
committed
gRPC Reference Types (#291)
1 parent cfa5734 commit 755a8c7

15 files changed

+964
-115
lines changed

protobuf-plugin/src/main/kotlin/kotlinx/rpc/protobuf/ModelToKotlinGenerator.kt

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class ModelToKotlinGenerator(
2020
}
2121

2222
private fun FileDeclaration.generateKotlinFiles(): List<FileGenerator> {
23+
additionalPublicImports.clear()
24+
additionalInternalImports.clear()
25+
2326
return listOf(
2427
generatePublicKotlinFile(),
2528
generateInternalKotlinFile(),
@@ -28,12 +31,12 @@ class ModelToKotlinGenerator(
2831

2932
private fun FileDeclaration.generatePublicKotlinFile(): FileGenerator {
3033
return file(codeGenerationParameters, logger = logger) {
31-
filename = name.simpleName
32-
packageName = name.packageName
33-
packagePath = name.packageName
34+
filename = this@generatePublicKotlinFile.name
35+
packageName = this@generatePublicKotlinFile.packageName.fullName()
36+
packagePath = this@generatePublicKotlinFile.packageName.fullName()
3437

3538
dependencies.forEach { dependency ->
36-
importPackage(dependency.name.packageName)
39+
importPackage(dependency.packageName.fullName())
3740
}
3841

3942
generatePublicDeclaredEntities(this@generatePublicKotlinFile)
@@ -46,23 +49,28 @@ class ModelToKotlinGenerator(
4649

4750
private fun FileDeclaration.generateInternalKotlinFile(): FileGenerator {
4851
return file(codeGenerationParameters, logger = logger) {
49-
filename = name.simpleName
50-
packageName = name.packageName
51-
packagePath = name.packageName.packageNameSuffixed(RPC_INTERNAL_PACKAGE_SUFFIX)
52+
filename = this@generateInternalKotlinFile.name
53+
packageName = this@generateInternalKotlinFile.packageName.fullName()
54+
packagePath = this@generateInternalKotlinFile.packageName.fullName().packageNameSuffixed(RPC_INTERNAL_PACKAGE_SUFFIX)
5255

5356
fileOptIns = listOf("ExperimentalRpcApi::class", "InternalRpcApi::class")
5457

5558
dependencies.forEach { dependency ->
56-
importPackage(dependency.name.packageName)
59+
importPackage(dependency.packageName.fullName())
5760
}
5861

5962
generateInternalDeclaredEntities(this@generateInternalKotlinFile)
6063

6164
import("kotlinx.rpc.internal.utils.*")
65+
66+
additionalInternalImports.forEach {
67+
import(it)
68+
}
6269
}
6370
}
6471

6572
private val additionalPublicImports = mutableSetOf<String>()
73+
private val additionalInternalImports = mutableSetOf<String>()
6674

6775
private fun CodeGenerator.generatePublicDeclaredEntities(fileDeclaration: FileDeclaration) {
6876
fileDeclaration.messageDeclarations.forEach { generatePublicMessage(it) }
@@ -79,7 +87,7 @@ class ModelToKotlinGenerator(
7987
}
8088

8189
private fun MessageDeclaration.fields() = actualFields.map {
82-
it.transformToFieldDeclaration() to it.type.defaultValue
90+
it.transformToFieldDeclaration() to it.type
8391
}
8492

8593
@Suppress("detekt.CyclomaticComplexMethod")
@@ -88,8 +96,8 @@ class ModelToKotlinGenerator(
8896
name = declaration.name.simpleName,
8997
declarationType = DeclarationType.Interface,
9098
) {
91-
declaration.fields().forEach {
92-
code("val ${it.first}")
99+
declaration.fields().forEach { (fieldDeclaration, _) ->
100+
code("val $fieldDeclaration")
93101
newLine()
94102
}
95103

@@ -119,8 +127,15 @@ class ModelToKotlinGenerator(
119127
declarationType = DeclarationType.Class,
120128
superTypes = listOf(declaration.name.simpleName),
121129
) {
122-
declaration.fields().forEach {
123-
code("override var ${it.first} = ${it.second}")
130+
declaration.fields().forEach { (fieldDeclaration, type) ->
131+
val value = if (type is FieldType.Reference) {
132+
additionalInternalImports.add("kotlin.properties.Delegates")
133+
"by Delegates.notNull()"
134+
} else {
135+
"= ${type.defaultValue}"
136+
}
137+
138+
code("override var $fieldDeclaration $value")
124139
newLine()
125140
}
126141
}
@@ -135,7 +150,7 @@ class ModelToKotlinGenerator(
135150
code("return ${declaration.name.simpleName}Builder().apply(body)")
136151
}
137152

138-
val platformType = "${declaration.outerClassName.simpleName}.${declaration.name.simpleName}"
153+
val platformType = "${declaration.outerClassName.fullName()}.${declaration.name.simpleName}"
139154

140155
function(
141156
name = "toPlatform",
@@ -164,27 +179,25 @@ class ModelToKotlinGenerator(
164179
}
165180

166181
private fun FieldDeclaration.toPlatformCast(): String {
167-
val type = type as? FieldType.IntegralType ?: return ""
168-
169182
return when (type) {
170183
FieldType.IntegralType.FIXED32 -> ".toInt()"
171184
FieldType.IntegralType.FIXED64 -> ".toLong()"
172185
FieldType.IntegralType.UINT32 -> ".toInt()"
173186
FieldType.IntegralType.UINT64 -> ".toLong()"
174187
FieldType.IntegralType.BYTES -> ".let { bytes -> com.google.protobuf.ByteString.copyFrom(bytes) }"
188+
is FieldType.Reference -> ".toPlatform()"
175189
else -> ""
176190
}
177191
}
178192

179193
private fun FieldDeclaration.toKotlinCast(): String {
180-
val type = type as? FieldType.IntegralType ?: return ""
181-
182194
return when (type) {
183195
FieldType.IntegralType.FIXED32 -> ".toUInt()"
184196
FieldType.IntegralType.FIXED64 -> ".toULong()"
185197
FieldType.IntegralType.UINT32 -> ".toUInt()"
186198
FieldType.IntegralType.UINT64 -> ".toULong()"
187199
FieldType.IntegralType.BYTES -> ".toByteArray()"
200+
is FieldType.Reference -> ".toKotlin()"
188201
else -> ""
189202
}
190203
}
@@ -196,9 +209,10 @@ class ModelToKotlinGenerator(
196209
private fun FieldDeclaration.typeFqName(): String {
197210
return when (type) {
198211
// KRPC-156 Reference Types
199-
// is FieldType.Reference -> {
200-
// type.value.simpleName
201-
// }
212+
is FieldType.Reference -> {
213+
val value by type.value
214+
value.fullName()
215+
}
202216

203217
is FieldType.IntegralType -> {
204218
type.fqName.simpleName
@@ -269,10 +283,10 @@ class ModelToKotlinGenerator(
269283
val inputType by method.inputType
270284
val outputType by method.outputType
271285
function(
272-
name = method.name.simpleName,
286+
name = method.name,
273287
modifiers = "suspend",
274-
args = "message: ${inputType.name.simpleName}",
275-
returnType = outputType.name.simpleName,
288+
args = "message: ${inputType.name.fullName()}",
289+
returnType = outputType.name.fullName(),
276290
)
277291
}
278292
}
@@ -284,7 +298,7 @@ class ModelToKotlinGenerator(
284298
modifiers = "private",
285299
name = "${service.name.simpleName}Delegate",
286300
declarationType = DeclarationType.Object,
287-
superTypes = listOf("kotlinx.rpc.grpc.descriptor.GrpcDelegate<${service.name.simpleName}>"),
301+
superTypes = listOf("kotlinx.rpc.grpc.descriptor.GrpcDelegate<${service.name.fullName()}>"),
288302
) {
289303
function(
290304
name = "clientProvider",
@@ -298,7 +312,7 @@ class ModelToKotlinGenerator(
298312
function(
299313
name = "definitionFor",
300314
modifiers = "override",
301-
args = "impl: ${service.name.simpleName}",
315+
args = "impl: ${service.name.fullName()}",
302316
returnType = "kotlinx.rpc.grpc.ServerServiceDefinition",
303317
) {
304318
scope("return ${service.name.simpleName}ServerDelegate(impl).bindService()")
@@ -311,10 +325,10 @@ class ModelToKotlinGenerator(
311325
name = "${service.name.simpleName}ServerDelegate",
312326
declarationType = DeclarationType.Class,
313327
superTypes = listOf("${service.name.simpleName}GrpcKt.${service.name.simpleName}CoroutineImplBase()"),
314-
constructorArgs = listOf("private val impl: ${service.name.simpleName}"),
328+
constructorArgs = listOf("private val impl: ${service.name.fullName()}"),
315329
) {
316330
service.methods.forEach { method ->
317-
val grpcName = method.name.simpleName.replaceFirstChar { it.lowercase() }
331+
val grpcName = method.name.replaceFirstChar { it.lowercase() }
318332

319333
val inputType by method.inputType
320334
val outputType by method.outputType
@@ -325,7 +339,7 @@ class ModelToKotlinGenerator(
325339
args = "request: ${inputType.toPlatformMessageType()}",
326340
returnType = outputType.toPlatformMessageType(),
327341
) {
328-
code("return impl.${method.name.simpleName}(request.toKotlin()).toPlatform()")
342+
code("return impl.${method.name}(request.toKotlin()).toPlatform()")
329343
}
330344
}
331345
}
@@ -362,9 +376,9 @@ class ModelToKotlinGenerator(
362376
scope("return when (call.callableName)") {
363377
service.methods.forEach { method ->
364378
val inputType by method.inputType
365-
val grpcName = method.name.simpleName.replaceFirstChar { it.lowercase() }
366-
val result = "stub.$grpcName((message as ${inputType.name.simpleName}).toPlatform())"
367-
code("\"${method.name.simpleName}\" -> $result.toKotlin() as R")
379+
val grpcName = method.name.replaceFirstChar { it.lowercase() }
380+
val result = "stub.$grpcName((message as ${inputType.name.fullName()}).toPlatform())"
381+
code("\"${method.name}\" -> $result.toKotlin() as R")
368382
}
369383

370384
code("else -> error(\"Illegal call: \${call.callableName}\")")
@@ -384,7 +398,7 @@ class ModelToKotlinGenerator(
384398
}
385399

386400
private fun MessageDeclaration.toPlatformMessageType(): String {
387-
return "${outerClassName.simpleName}.${name.simpleName.removePrefix(name.parentNameAsPrefix)}"
401+
return "${outerClassName.fullName()}.${name.simpleName}"
388402
}
389403
}
390404

0 commit comments

Comments
 (0)