@@ -78,6 +78,9 @@ class ModelToKotlinCommonGenerator(
78
78
79
79
generateInternalDeclaredEntities(this @generateInternalKotlinFile)
80
80
81
+ import(" kotlinx.rpc.internal.utils.*" )
82
+ import(" kotlinx.coroutines.flow.*" )
83
+
81
84
additionalInternalImports.forEach {
82
85
import(it)
83
86
}
@@ -279,12 +282,15 @@ class ModelToKotlinCommonGenerator(
279
282
code(" return msg" )
280
283
}
281
284
282
- private fun CodeGenerator.readMatchCase (field : FieldDeclaration ) {
283
- val encFuncName = field.type.decodeEncodeFuncName()
284
- val assignment = " msg.${field.name} ="
285
+ private fun CodeGenerator.readMatchCase (
286
+ field : FieldDeclaration ,
287
+ assignment : String = "msg.${field.name} =",
288
+ wrapperCtor : (String ) -> String = { it }
289
+ ) {
285
290
when (val fieldType = field.type) {
286
291
is FieldType .IntegralType -> whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.${field.type.wireType.name} " ) {
287
- code(" $assignment decoder.read$encFuncName ()" )
292
+ val raw = " decoder.read${field.type.decodeEncodeFuncName()} ()"
293
+ code(" $assignment ${wrapperCtor(raw)} " )
288
294
}
289
295
290
296
is FieldType .List -> if (field.dec.isPacked) {
@@ -299,11 +305,22 @@ class ModelToKotlinCommonGenerator(
299
305
300
306
is FieldType .Enum -> whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.VARINT" ) {
301
307
val fromNum = " ${fieldType.dec.name.safeFullName()} .fromNumber"
302
- code(" $assignment $fromNum (decoder.read$encFuncName ())" )
308
+ val raw = " $fromNum (decoder.read${field.type.decodeEncodeFuncName()} ())"
309
+ code(" $assignment ${wrapperCtor(raw)} " )
310
+ }
311
+
312
+ is FieldType .OneOf -> {
313
+ fieldType.dec.variants.forEach { variant ->
314
+ val variantName = " ${fieldType.dec.name.safeFullName()} .${variant.name} "
315
+ readMatchCase(
316
+ field = variant,
317
+ assignment = assignment,
318
+ wrapperCtor = { " $variantName ($it )" }
319
+ )
320
+ }
303
321
}
304
322
305
323
is FieldType .Map -> TODO ()
306
- is FieldType .OneOf -> TODO ()
307
324
is FieldType .Reference -> TODO ()
308
325
}
309
326
}
@@ -323,42 +340,54 @@ class ModelToKotlinCommonGenerator(
323
340
val fieldName = field.name
324
341
if (field.nullable) {
325
342
scope(" $fieldName ?.also" ) {
326
- code (field.writeValue( " it" ) )
343
+ writeFieldValue (field, " it" )
327
344
}
328
345
} else if (! field.dec.hasPresence()) {
329
346
ifBranch(condition = field.defaultCheck(), ifBlock = {
330
- code (field.writeValue( field.name) )
347
+ writeFieldValue (field, field.name)
331
348
})
332
349
} else {
333
- code (field.writeValue( field.name) )
350
+ writeFieldValue (field, field.name)
334
351
}
335
352
}
336
353
}
337
354
338
- private fun FieldDeclaration.writeValue (variable : String ): String {
339
- return when (val fieldType = type) {
340
- is FieldType .IntegralType -> " encoder.write${type.decodeEncodeFuncName()} (fieldNr = $number , value = $variable )"
341
- is FieldType .List -> when {
342
- dec.isPacked && packedFixedSize ->
343
- " encoder.writePacked${fieldType.value.decodeEncodeFuncName()} (fieldNr = $number , value = $variable )"
355
+ private fun CodeGenerator.writeFieldValue (field : FieldDeclaration , valueVar : String ) {
356
+ var encFunc = field.type.decodeEncodeFuncName()
357
+ val number = field.number
358
+ when (val fieldType = field.type) {
359
+ is FieldType .IntegralType -> code(" encoder.write${encFunc!! } (fieldNr = $number , value = $valueVar )" )
360
+ is FieldType .List -> {
361
+ encFunc = fieldType.value.decodeEncodeFuncName()
362
+ when {
363
+ field.dec.isPacked && field.packedFixedSize ->
364
+ code(" encoder.writePacked${encFunc!! } (fieldNr = $number , value = $valueVar )" )
344
365
345
- dec.isPacked && ! packedFixedSize ->
346
- " encoder.writePacked${fieldType.value.decodeEncodeFuncName()} (fieldNr = $number , value = $variable , fieldSize = ${
347
- wireSizeCall(
348
- variable
366
+ field.dec.isPacked && ! field.packedFixedSize ->
367
+ code(
368
+ " encoder.writePacked${encFunc!! } (fieldNr = $number , value = $valueVar , fieldSize = ${
369
+ field.wireSizeCall(valueVar)
370
+ } )"
349
371
)
350
- } )"
351
372
352
- else ->
353
- " $variable .forEach { encoder.write ${fieldType.value.decodeEncodeFuncName()} ( $number , it) } "
373
+ else -> code( " $valueVar .forEach { encoder.write ${encFunc !! } ( $number , it) } " )
374
+ }
354
375
}
355
376
356
- is FieldType .Enum -> " encoder.write${type.decodeEncodeFuncName()} (fieldNr = $number , value = $variable .number)"
377
+ is FieldType .Enum -> code(" encoder.write${encFunc!! } (fieldNr = $number , value = ${valueVar} .number)" )
378
+
379
+ is FieldType .OneOf -> whenBlock(" val value = $valueVar " ) {
380
+ fieldType.dec.variants.forEach { variant ->
381
+ whenCase(" is ${fieldType.dec.name.safeFullName()} .${variant.name} " ) {
382
+ writeFieldValue(variant, " value.value" )
383
+ }
384
+ }
385
+ }
357
386
358
387
is FieldType .Map -> TODO ()
359
- is FieldType .OneOf -> TODO ()
360
- is FieldType .Reference -> " <TODO: Implement Reference writeValue()>"
388
+ is FieldType .Reference -> code(" <TODO: Implement Reference writeValue()>" )
361
389
}
390
+
362
391
}
363
392
364
393
@@ -370,9 +399,9 @@ class ModelToKotlinCommonGenerator(
370
399
contextReceiver = " ${enum.name.safeFullName()} .Companion" ,
371
400
returnType = enum.name.safeFullName(),
372
401
) {
373
- whenBlock(prefix = " return" ) {
402
+ whenBlock(prefix = " return" , condition = " number " ) {
374
403
enum.originalEntries.forEach { entry ->
375
- whenCase(" number == ${entry.dec.number} " ) {
404
+ whenCase(" ${entry.dec.number} " ) {
376
405
code(" ${entry.name} " )
377
406
}
378
407
}
@@ -408,7 +437,8 @@ class ModelToKotlinCommonGenerator(
408
437
409
438
410
439
private fun FieldDeclaration.wireSizeCall (variable : String ): String {
411
- val sizeFunc = " $PB_PKG .WireSize.${type.decodeEncodeFuncName().replaceFirstChar { it.lowercase() }} ($variable )"
440
+ val sizeFunc =
441
+ " $PB_PKG .WireSize.${type.decodeEncodeFuncName()!! .replaceFirstChar { it.lowercase() }} ($variable )"
412
442
return when (val fieldType = type) {
413
443
is FieldType .IntegralType -> when {
414
444
fieldType.wireType == WireType .FIXED32 -> " 32"
@@ -444,7 +474,7 @@ class ModelToKotlinCommonGenerator(
444
474
}
445
475
}
446
476
447
- private fun FieldType.decodeEncodeFuncName (): String = when (this ) {
477
+ private fun FieldType.decodeEncodeFuncName (): String? = when (this ) {
448
478
FieldType .IntegralType .STRING -> " String"
449
479
FieldType .IntegralType .BYTES -> " Bytes"
450
480
FieldType .IntegralType .BOOL -> " Bool"
@@ -462,9 +492,9 @@ class ModelToKotlinCommonGenerator(
462
492
FieldType .IntegralType .SFIXED64 -> " SFixed64"
463
493
is FieldType .List -> " Packed${value.decodeEncodeFuncName()} "
464
494
is FieldType .Enum -> " Enum"
465
- is FieldType .Map -> error( " No encoding/decoding function for map types " )
466
- is FieldType .OneOf -> error( " No encoding/decoding function for oneOf types " )
467
- is FieldType .Reference -> error( " No encoding/decoding function for sub message types " )
495
+ is FieldType .Map -> null
496
+ is FieldType .OneOf -> null
497
+ is FieldType .Reference -> null
468
498
}
469
499
470
500
private fun FieldDeclaration.transformToFieldDeclaration (): String {
@@ -480,10 +510,7 @@ class ModelToKotlinCommonGenerator(
480
510
481
511
is FieldType .Enum -> type.dec.name.safeFullName()
482
512
483
- is FieldType .OneOf -> {
484
- val value by type.value
485
- value.safeFullName()
486
- }
513
+ is FieldType .OneOf -> type.dec.name.safeFullName()
487
514
488
515
is FieldType .IntegralType -> {
489
516
type.fqName.simpleName
0 commit comments