@@ -78,6 +78,9 @@ class ModelToKotlinCommonGenerator(
7878
7979 generateInternalDeclaredEntities(this @generateInternalKotlinFile)
8080
81+ import(" kotlinx.rpc.internal.utils.*" )
82+ import(" kotlinx.coroutines.flow.*" )
83+
8184 additionalInternalImports.forEach {
8285 import(it)
8386 }
@@ -279,12 +282,15 @@ class ModelToKotlinCommonGenerator(
279282 code(" return msg" )
280283 }
281284
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+ ) {
285290 when (val fieldType = field.type) {
286291 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)} " )
288294 }
289295
290296 is FieldType .List -> if (field.dec.isPacked) {
@@ -299,11 +305,22 @@ class ModelToKotlinCommonGenerator(
299305
300306 is FieldType .Enum -> whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.VARINT" ) {
301307 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+ }
303321 }
304322
305323 is FieldType .Map -> TODO ()
306- is FieldType .OneOf -> TODO ()
307324 is FieldType .Reference -> TODO ()
308325 }
309326 }
@@ -323,42 +340,54 @@ class ModelToKotlinCommonGenerator(
323340 val fieldName = field.name
324341 if (field.nullable) {
325342 scope(" $fieldName ?.also" ) {
326- code (field.writeValue( " it" ) )
343+ writeFieldValue (field, " it" )
327344 }
328345 } else if (! field.dec.hasPresence()) {
329346 ifBranch(condition = field.defaultCheck(), ifBlock = {
330- code (field.writeValue( field.name) )
347+ writeFieldValue (field, field.name)
331348 })
332349 } else {
333- code (field.writeValue( field.name) )
350+ writeFieldValue (field, field.name)
334351 }
335352 }
336353 }
337354
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 )" )
344365
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+ } )"
349371 )
350- } )"
351372
352- else ->
353- " $variable .forEach { encoder.write ${fieldType.value.decodeEncodeFuncName()} ( $number , it) } "
373+ else -> code( " $valueVar .forEach { encoder.write ${encFunc !! } ( $number , it) } " )
374+ }
354375 }
355376
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+ }
357386
358387 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()>" )
361389 }
390+
362391 }
363392
364393
@@ -370,9 +399,9 @@ class ModelToKotlinCommonGenerator(
370399 contextReceiver = " ${enum.name.safeFullName()} .Companion" ,
371400 returnType = enum.name.safeFullName(),
372401 ) {
373- whenBlock(prefix = " return" ) {
402+ whenBlock(prefix = " return" , condition = " number " ) {
374403 enum.originalEntries.forEach { entry ->
375- whenCase(" number == ${entry.dec.number} " ) {
404+ whenCase(" ${entry.dec.number} " ) {
376405 code(" ${entry.name} " )
377406 }
378407 }
@@ -408,7 +437,8 @@ class ModelToKotlinCommonGenerator(
408437
409438
410439 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 )"
412442 return when (val fieldType = type) {
413443 is FieldType .IntegralType -> when {
414444 fieldType.wireType == WireType .FIXED32 -> " 32"
@@ -444,7 +474,7 @@ class ModelToKotlinCommonGenerator(
444474 }
445475 }
446476
447- private fun FieldType.decodeEncodeFuncName (): String = when (this ) {
477+ private fun FieldType.decodeEncodeFuncName (): String? = when (this ) {
448478 FieldType .IntegralType .STRING -> " String"
449479 FieldType .IntegralType .BYTES -> " Bytes"
450480 FieldType .IntegralType .BOOL -> " Bool"
@@ -462,9 +492,9 @@ class ModelToKotlinCommonGenerator(
462492 FieldType .IntegralType .SFIXED64 -> " SFixed64"
463493 is FieldType .List -> " Packed${value.decodeEncodeFuncName()} "
464494 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
468498 }
469499
470500 private fun FieldDeclaration.transformToFieldDeclaration (): String {
@@ -480,10 +510,7 @@ class ModelToKotlinCommonGenerator(
480510
481511 is FieldType .Enum -> type.dec.name.safeFullName()
482512
483- is FieldType .OneOf -> {
484- val value by type.value
485- value.safeFullName()
486- }
513+ is FieldType .OneOf -> type.dec.name.safeFullName()
487514
488515 is FieldType .IntegralType -> {
489516 type.fqName.simpleName
0 commit comments