All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.ch.softappeal.yass2.generate.BinarySerializerGenerate.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
package ch.softappeal.yass2.generate

import ch.softappeal.yass2.serialize.binary.*
import kotlin.reflect.*
import kotlin.reflect.full.*

fun generateBinarySerializer(
    baseEncoders: List>, concreteClasses: List>, functionName: String = "generatedBinarySerializer"
): String {
    val baseEncoderTypes = baseEncoders.map { it.type }
    val buffer = StringBuilder(10_000)
    fun out(s: String, level: Int = 0) = buffer.append(s.replaceIndent("    ".repeat(level))).append('\n')
    fun MProperty.encoderId(tail: String = "") = if (kind != MKind.WithId) encoderId.toString() + tail else ""
    out("""
        @Suppress("UNCHECKED_CAST", "RemoveRedundantQualifierName", "SpellCheckingInspection")
        fun $functionName(
            baseEncoders: List<${BaseEncoder::class.qualifiedName}<*>>
        ) = ${BinarySerializer::class.qualifiedName}(baseEncoders + listOf(
    """)
    concreteClasses.withIndex().forEach { (index, klass) ->
        out("""
            ${ClassEncoder::class.qualifiedName}(${klass.qualifiedName}::class, // ${index + baseEncoders.size + FirstEncoderId}
        """, 1)
        val properties = klass.mClass(baseEncoderTypes, concreteClasses).properties
        if (properties.isEmpty()) out("{ _, _ -> },", 2) else {
            out("""
                { w, i ->
            """, 2)
            properties.forEach { out("w.write${it.kind}(${it.encoderId(", ")}i.${it.property.name})", 3) }
            out("""
                },
            """, 2)
        }
        out("""
            {${if (properties.isEmpty()) "" else " r ->"}
        """, 2)
        properties.forEach {
            out(
                "val p${it.property.name} = r.read${it.kind}(${it.encoderId()})" +
                    if (it.property.returnType.needsCast()) " as ${it.property.returnType}" else "",
                3
            )
        }
        val parameterNames = klass.primaryConstructor!!.valueParameters.map { it.name }
        out("""
            val i = ${klass.qualifiedName}(${parameterNames.joinToString(", ") { "p$it" }})
        """, 3)
        properties.filter { it.property.name !in parameterNames }.forEach {
            out("i.${it.property.name} = p${it.property.name}", 3)
        }
        out("""
                    i
                }
            )${if (index + 1 == concreteClasses.size) "" else ","}
        """, 1)
    }
    out("""
        ))
    """)
    return buffer.toString()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy