Extensible mechanism for plugin metadata during descriptor serialization

A mechanism that allows kotlinx.serialization plugin to preserve the
correct (program) order of properties after serializing/deserializing
descriptors to kotlin metadata, which is needed for correct and stable
json serialization of class hierarchies in incremental/multi-module scenario.
It uses protobuf extensions.
This commit is contained in:
Leonid Startsev
2020-04-27 17:26:51 +03:00
parent 8d05253369
commit 7c8c5b057f
26 changed files with 225 additions and 129 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -45,7 +45,8 @@ class DescriptorSerializer private constructor(
private val extension: SerializerExtension,
val typeTable: MutableTypeTable,
private val versionRequirementTable: MutableVersionRequirementTable?,
private val serializeTypeTableToFunction: Boolean
private val serializeTypeTableToFunction: Boolean,
val plugins: List<DescriptorSerializerPlugin> = emptyList()
) {
private val contractSerializer = ContractSerializer()
@@ -152,6 +153,8 @@ class DescriptorSerializer private constructor(
extension.serializeClass(classDescriptor, builder, versionRequirementTable, this)
plugins.forEach { it.afterClass(classDescriptor, builder, versionRequirementTable, this, extension) }
writeVersionRequirementForInlineClasses(classDescriptor, builder, versionRequirementTable)
val versionRequirementTableProto = versionRequirementTable.serialize()
@@ -741,6 +744,13 @@ class DescriptorSerializer private constructor(
)
companion object {
private val plugins: MutableSet<DescriptorSerializerPlugin> = mutableSetOf()
@JvmStatic
fun registerSerializerPlugin(plugin: DescriptorSerializerPlugin) {
plugins.add(plugin)
}
@JvmStatic
fun createTopLevel(extension: SerializerExtension): DescriptorSerializer =
DescriptorSerializer(
@@ -775,7 +785,8 @@ class DescriptorSerializer private constructor(
MutableTypeTable(),
if (container is ClassDescriptor && !isVersionRequirementTableWrittenCorrectly(extension.metadataVersion))
parent.versionRequirementTable else MutableVersionRequirementTable(),
serializeTypeTableToFunction = false
serializeTypeTableToFunction = false,
plugins.toList()
)
for (typeParameter in descriptor.declaredTypeParameters) {
serializer.typeParameters.intern(typeParameter)
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
interface DescriptorSerializerPlugin {
fun afterClass(
descriptor: ClassDescriptor,
proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: DescriptorSerializer,
extension: SerializerExtension
) {
}
}