Is there a way to post process the output of a plu...
# serialization
a
Is there a way to post process the output of a plugin generated serializer with
JsonTransformingSerializer
on a root class? Looking to try to handle JSON Schema
additionalProperties: true
by having a hash map be merged with the parent JsonObject with something like
Copy code
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonTransformingSerializer
import kotlinx.serialization.json.jsonObject

@Serializable(with = RootSerializer::class)
data class Root(val foo: String, val bar: String, val additionalProperties: Map<String, String>)
object RootSerializer : KSerializer<Root> by AdditionalPropertiesSerializer(Root.serializer())

class AdditionalPropertiesSerializer<T: Any>(serializer: KSerializer<T>) : JsonTransformingSerializer<T>(serializer) {
    override fun transformSerialize(element: JsonElement): JsonElement {
        if (element is JsonObject) {
            val additionalProperties = element["additionalProperties"]
            if(additionalProperties != null) {
                val entries = element.toMutableMap()
                entries.remove("additionalProperties")

                additionalProperties.jsonObject.entries.forEach {
                    entries[it.key] = it.value
                }

                JsonObject(entries)
            } else {
                return element
            }
        }

        return element
    }
}

fun main() {
    Json.encodeToString(Root("Foo", "bar", mapOf("hello" to "world")))
}
but this leads to the exception
Copy code
Exception in thread "main" java.lang.ExceptionInInitializerError
	at Root$Companion.serializer(Example.kt:12)
	at ExampleKt.main(Example.kt:42)
	at ExampleKt.main(Example.kt)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method AdditionalPropertiesSerializer.<init>, parameter serializer
	at AdditionalPropertiesSerializer.<init>(Example.kt)
	at RootSerializer.<init>(Example.kt:15)
	at RootSerializer.<clinit>(Example.kt)
Oh, guess its this issue: https://github.com/Kotlin/kotlinx.serialization/issues/1169 This hack seems to work though
Copy code
@Serializable(with = RootSerializer::class)
data class Root(val foo: String, val bar: String, val additionalProperties: Map<String, String>)

@Serializer(Root::class)
object RootGeneratedSerializer : KSerializer<Root>
object RootSerializer : KSerializer<Root> by AdditionalPropertiesSerializer(RootGeneratedSerializer)