@@ -282,44 +282,68 @@ class ModelToKotlinCommonGenerator(
282
282
private fun CodeGenerator.readMatchCase (
283
283
field : FieldDeclaration ,
284
284
lvalue : String = "msg.${field.name}",
285
- wrapperCtor : (String ) -> String = { it }
285
+ wrapperCtor : (String ) -> String = { it },
286
+ beforeValueDecoding : CodeGenerator .() -> Unit = {},
286
287
) {
287
288
when (val fieldType = field.type) {
288
289
is FieldType .IntegralType -> whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.${field.type.wireType.name} " ) {
290
+ beforeValueDecoding()
289
291
generateDecodeFieldValue(fieldType, lvalue, wrapperCtor = wrapperCtor)
290
292
}
291
293
292
294
is FieldType .List -> if (field.dec.isPacked) {
293
295
whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.LENGTH_DELIMITED" ) {
296
+ beforeValueDecoding()
294
297
generateDecodeFieldValue(fieldType, lvalue, isPacked = true , wrapperCtor = wrapperCtor)
295
298
}
296
299
} else {
297
300
whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.${fieldType.value.wireType.name} " ) {
301
+ beforeValueDecoding()
298
302
generateDecodeFieldValue(fieldType, lvalue, isPacked = false , wrapperCtor = wrapperCtor)
299
303
}
300
304
}
301
305
302
306
is FieldType .Enum -> whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.VARINT" ) {
307
+ beforeValueDecoding()
303
308
generateDecodeFieldValue(fieldType, lvalue, wrapperCtor = wrapperCtor)
304
309
}
305
310
306
311
is FieldType .OneOf -> {
307
312
fieldType.dec.variants.forEach { variant ->
308
313
val variantName = " ${fieldType.dec.name.safeFullName()} .${variant.name} "
309
- readMatchCase(
310
- field = variant,
311
- lvalue = lvalue,
312
- wrapperCtor = { " $variantName ($it )" }
313
- )
314
+ if (variant.type is FieldType .Message ) {
315
+ // in case of a message, we must construct an empty message before reading the message
316
+ readMatchCase(
317
+ field = variant,
318
+ lvalue = " field.value" ,
319
+ beforeValueDecoding = {
320
+ beforeValueDecoding()
321
+ scope(" val field = ($lvalue as? $variantName ) ?: $variantName (${variant.type.internalCtor()} ).also" ) {
322
+ // write the constructed oneof variant to the field
323
+ code(" $lvalue = it" )
324
+ }
325
+ })
326
+ } else {
327
+ readMatchCase(
328
+ field = variant,
329
+ lvalue = lvalue,
330
+ wrapperCtor = { " $variantName ($it )" },
331
+ beforeValueDecoding = beforeValueDecoding
332
+ )
333
+ }
314
334
}
315
335
}
316
336
317
337
is FieldType .Message -> {
318
338
whenCase(" tag.fieldNr == ${field.number} && tag.wireType == $PB_PKG .WireType.LENGTH_DELIMITED" ) {
319
- // check if the the current sub message object
320
- ifBranch(condition = " !msg.presenceMask[${field.presenceIdx} ]" , ifBlock = {
321
- code(" $lvalue = ${fieldType.dec.value.internalClassFullName()} ()" )
322
- })
339
+ if (field.presenceIdx != null ) {
340
+ // check if the current sub message object was already set, if not, set a new one
341
+ // to set the field's presence tracker to true
342
+ ifBranch(condition = " !msg.presenceMask[${field.presenceIdx} ]" , ifBlock = {
343
+ code(" $lvalue = ${fieldType.dec.value.internalClassFullName()} ()" )
344
+ })
345
+ }
346
+ beforeValueDecoding()
323
347
generateDecodeFieldValue(fieldType, lvalue, wrapperCtor = wrapperCtor)
324
348
}
325
349
}
@@ -820,6 +844,9 @@ class ModelToKotlinCommonGenerator(
820
844
}
821
845
}
822
846
847
+ private fun FieldType.Message.internalCtor () =
848
+ dec.value.internalClassFullName() + " ()"
849
+
823
850
private fun MessageDeclaration.internalClassFullName (): String {
824
851
return name.safeFullName(MSG_INTERNAL_SUFFIX )
825
852
}
0 commit comments