@@ -8,74 +8,89 @@ import kotlinx.rpc.protobuf.CodeGenerator.DeclarationType
88import kotlinx.rpc.protobuf.model.*
99import org.slf4j.Logger
1010
11+ private const val RPC_INTERNAL_PACKAGE_SUFFIX = " _rpc_internal"
12+
1113class ModelToKotlinGenerator (
1214 private val model : Model ,
1315 private val logger : Logger ,
1416 private val codeGenerationParameters : CodeGenerationParameters ,
1517) {
1618 fun generateKotlinFiles (): List <FileGenerator > {
17- return model.files.map { it.generateKotlinFile() }
19+ return model.files.flatMap { it.generateKotlinFiles() }
20+ }
21+
22+ private fun FileDeclaration.generateKotlinFiles (): List <FileGenerator > {
23+ return listOf (
24+ generatePublicKotlinFile(),
25+ generateInternalKotlinFile(),
26+ )
1827 }
1928
20- private fun FileDeclaration.generateKotlinFile (): FileGenerator {
29+ private fun FileDeclaration.generatePublicKotlinFile (): FileGenerator {
2130 return file(codeGenerationParameters, logger = logger) {
2231 filename = name.simpleName
2332 packageName = name.packageName
24- fileOptIns = listOf ( " ExperimentalRpcApi::class " , " InternalRpcApi::class " )
33+ packagePath = name.packageName
2534
2635 dependencies.forEach { dependency ->
2736 importPackage(dependency.name.packageName)
2837 }
2938
30- generateDeclaredEntities (this @generateKotlinFile )
39+ generatePublicDeclaredEntities (this @generatePublicKotlinFile )
3140
32- additionalImports .forEach {
41+ additionalPublicImports .forEach {
3342 import(it)
3443 }
44+ }
45+ }
46+
47+ private fun FileDeclaration.generateInternalKotlinFile (): FileGenerator {
48+ return file(codeGenerationParameters, logger = logger) {
49+ filename = name.simpleName
50+ packageName = name.packageName
51+ packagePath = name.packageName.packageNameSuffixed(RPC_INTERNAL_PACKAGE_SUFFIX )
52+
53+ fileOptIns = listOf (" ExperimentalRpcApi::class" , " InternalRpcApi::class" )
54+
55+ dependencies.forEach { dependency ->
56+ importPackage(dependency.name.packageName)
57+ }
58+
59+ generateInternalDeclaredEntities(this @generateInternalKotlinFile)
60+
3561 import(" kotlinx.rpc.internal.utils.*" )
3662 }
3763 }
3864
39- private val additionalImports = mutableSetOf<String >()
65+ private val additionalPublicImports = mutableSetOf<String >()
4066
41- private fun CodeGenerator.generateDeclaredEntities (fileDeclaration : FileDeclaration ) {
42- fileDeclaration.messageDeclarations.forEach { generateMessage (it) }
67+ private fun CodeGenerator.generatePublicDeclaredEntities (fileDeclaration : FileDeclaration ) {
68+ fileDeclaration.messageDeclarations.forEach { generatePublicMessage (it) }
4369 // KRPC-141 Enum Types
4470// fileDeclaration.enumDeclarations.forEach { generateEnum(it) }
45- fileDeclaration.serviceDeclarations.forEach { generateService (it) }
71+ fileDeclaration.serviceDeclarations.forEach { generatePublicService (it) }
4672 }
4773
48- @Suppress(" detekt.CyclomaticComplexMethod" )
49- private fun CodeGenerator.generateMessage (declaration : MessageDeclaration ) {
50- val fields = declaration.actualFields.map { it.generateFieldDeclaration() to it.type.defaultValue }
51-
52- val isInterfaceMode = parameters.messageMode == RpcProtobufPlugin .MessageMode .Interface
53-
54- val (declarationType, modifiers) = when {
55- isInterfaceMode -> {
56- DeclarationType .Interface to " "
57- }
58-
59- fields.isEmpty() -> {
60- DeclarationType .Object to " "
61- }
74+ private fun CodeGenerator.generateInternalDeclaredEntities (fileDeclaration : FileDeclaration ) {
75+ fileDeclaration.messageDeclarations.forEach { generateInternalMessage(it) }
76+ // KRPC-141 Enum Types
77+ // fileDeclaration.enumDeclarations.forEach { generateEnum(it) }
78+ fileDeclaration.serviceDeclarations.forEach { generateInternalService(it) }
79+ }
6280
63- else -> {
64- DeclarationType .Class to " data"
65- }
66- }
81+ private fun MessageDeclaration.fields () = actualFields.map {
82+ it.transformToFieldDeclaration() to it.type.defaultValue
83+ }
6784
85+ @Suppress(" detekt.CyclomaticComplexMethod" )
86+ private fun CodeGenerator.generatePublicMessage (declaration : MessageDeclaration ) {
6887 clazz(
6988 name = declaration.name.simpleName,
70- modifiers = modifiers,
71- constructorArgs = if (isInterfaceMode) emptyList() else fields.map { " val ${it.first} " to it.second },
72- declarationType = declarationType,
89+ declarationType = DeclarationType .Interface ,
7390 ) {
74- if (isInterfaceMode) {
75- fields.forEach {
76- code(" val ${it.first} " )
77- newLine()
78- }
91+ declaration.fields().forEach {
92+ code(" val ${it.first} " )
93+ newLine()
7994 }
8095
8196 // KRPC-147 OneOf Types
@@ -93,32 +108,31 @@ class ModelToKotlinGenerator(
93108// generateEnum(enum)
94109// }
95110
96- if (isInterfaceMode) {
97- clazz(" " , modifiers = " companion" , declarationType = DeclarationType .Object )
98- }
111+ clazz(" " , modifiers = " companion" , declarationType = DeclarationType .Object )
99112 }
113+ }
100114
101- if (isInterfaceMode) {
102- clazz(
103- name = " ${declaration.name.simpleName} Builder " ,
104- declarationType = DeclarationType . Class ,
105- superTypes = listOf (declaration.name.simpleName) ,
106- ) {
107- fields.forEach {
108- code( " override var ${it.first} = ${it.second} " )
109- newLine( )
110- }
115+ @Suppress( " detekt.CyclomaticComplexMethod " )
116+ private fun CodeGenerator. generateInternalMessage ( declaration : MessageDeclaration ) {
117+ clazz(
118+ name = " ${declaration.name.simpleName} Builder " ,
119+ declarationType = DeclarationType . Class ,
120+ superTypes = listOf (declaration.name.simpleName),
121+ ) {
122+ declaration.fields().forEach {
123+ code( " override var ${it.first} = ${it.second} " )
124+ newLine()
111125 }
126+ }
112127
113- function(
114- name = " invoke" ,
115- modifiers = " operator" ,
116- args = " body: ${declaration.name.simpleName} Builder.() -> Unit" ,
117- contextReceiver = " ${declaration.name.simpleName} .Companion" ,
118- returnType = declaration.name.simpleName,
119- ) {
120- code(" return ${declaration.name.simpleName} Builder().apply(body)" )
121- }
128+ function(
129+ name = " invoke" ,
130+ modifiers = " operator" ,
131+ args = " body: ${declaration.name.simpleName} Builder.() -> Unit" ,
132+ contextReceiver = " ${declaration.name.simpleName} .Companion" ,
133+ returnType = declaration.name.simpleName,
134+ ) {
135+ code(" return ${declaration.name.simpleName} Builder().apply(body)" )
122136 }
123137
124138 val platformType = " ${declaration.outerClassName.simpleName} .${declaration.name.simpleName} "
@@ -175,7 +189,7 @@ class ModelToKotlinGenerator(
175189 }
176190 }
177191
178- private fun FieldDeclaration.generateFieldDeclaration (): String {
192+ private fun FieldDeclaration.transformToFieldDeclaration (): String {
179193 return " ${name} : ${typeFqName()} "
180194 }
181195
@@ -219,7 +233,7 @@ class ModelToKotlinGenerator(
219233 superTypes = listOf (interfaceName),
220234 )
221235
222- additionalImports .add(" kotlin.jvm.JvmInline" )
236+ additionalPublicImports .add(" kotlin.jvm.JvmInline" )
223237 }
224238 }
225239 }
@@ -247,7 +261,7 @@ class ModelToKotlinGenerator(
247261 }
248262
249263 @Suppress(" detekt.LongMethod" )
250- private fun CodeGenerator.generateService (service : ServiceDeclaration ) {
264+ private fun CodeGenerator.generatePublicService (service : ServiceDeclaration ) {
251265 code(" @kotlinx.rpc.grpc.annotations.Grpc" )
252266 clazz(service.name.simpleName, declarationType = DeclarationType .Interface ) {
253267 service.methods.forEach { method ->
@@ -262,9 +276,9 @@ class ModelToKotlinGenerator(
262276 )
263277 }
264278 }
279+ }
265280
266- newLine()
267-
281+ private fun CodeGenerator.generateInternalService (service : ServiceDeclaration ) {
268282 code(" @Suppress(\" unused\" , \" all\" )" )
269283 clazz(
270284 modifiers = " private" ,
@@ -373,3 +387,7 @@ class ModelToKotlinGenerator(
373387 return " ${outerClassName.simpleName} .${name.simpleName.removePrefix(name.parentNameAsPrefix)} "
374388 }
375389}
390+
391+ internal fun String.packageNameSuffixed (suffix : String ): String {
392+ return if (isEmpty()) suffix else " $this .$suffix "
393+ }
0 commit comments