diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt index 8e4c6bb9934..3fd34b85971 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt @@ -42,6 +42,7 @@ abstract class SerializerCodegen( val prop = generateSerializableClassPropertyIfNeeded() val save = generateSaveIfNeeded() val load = generateLoadIfNeeded() + generateDescriptorGetterIfNeeded() // if (save || load || prop) // generateSerialDesc() if (serializableDescriptor.declaredTypeParameters.isNotEmpty() && typedSerializerConstructorNotDeclared()) { @@ -49,6 +50,19 @@ abstract class SerializerCodegen( } } + private fun generateDescriptorGetterIfNeeded(): Boolean { + val function = getMemberToGenerate( + serializerDescriptor, SerialEntityNames.GENERATED_DESCRIPTOR_GETTER.identifier, + { true }, { true } + ) ?: return false + generateChildSerializersGetter(function) + return true + } + + protected open fun generateChildSerializersGetter(function: FunctionDescriptor) { + // TODO() + } + // checks if user didn't declared constructor (KSerializer, KSerializer...) on a KSerializer> private fun typedSerializerConstructorNotDeclared(): Boolean { val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializerDescriptor)?.arguments diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt index 24e133669c2..1b1b8b64fbc 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt @@ -55,6 +55,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter // todo: extract packages constants too? internal val descType = Type.getObjectType("kotlinx/serialization/$SERIAL_DESCRIPTOR_CLASS") internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/$SERIAL_DESCRIPTOR_CLASS_IMPL") +internal val generatedSerializerType = Type.getObjectType("kotlinx/serialization/internal/${SerialEntityNames.GENERATED_SERIALIZER_CLASS}") internal val kOutputType = Type.getObjectType("kotlinx/serialization/$STRUCTURE_ENCODER_CLASS") internal val encoderType = Type.getObjectType("kotlinx/serialization/$ENCODER_CLASS") internal val decoderType = Type.getObjectType("kotlinx/serialization/$DECODER_CLASS") @@ -168,6 +169,32 @@ internal fun InstructionAdapter.stackValueSerializerInstanceFromClass( } } +internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializerWithoutSti( + codegen: ClassBodyCodegen, + property: SerializableProperty, + serializerCodegen: AbstractSerialGenerator +): Boolean { + val serializer = + property.serializableWith?.toClassDescriptor + ?: if (!property.type.isTypeParameter()) serializerCodegen.findTypeSerializerOrContext( + property.module, + property.type, + property.descriptor.annotations, + property.descriptor.findPsi() + ) else null + return serializerCodegen.stackValueSerializerInstance( + codegen, + property.module, + property.type, + serializer, + this, + property.genericIndex + ) { idx -> + load(0, kSerializerType) + getfield(codegen.typeMapper.mapClass(codegen.descriptor).internalName, "$typeArgPrefix$idx", kSerializerType.descriptor) + }.also { if (it && property.type.isMarkedNullable) wrapStackValueIntoNullableSerializer() } +} + internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializer(codegen: ClassBodyCodegen, sti: JVMSerialTypeInfo, serializerCodegen: AbstractSerialGenerator): Boolean { return serializerCodegen.stackValueSerializerInstance( codegen, sti.property.module, sti.property.type, @@ -240,13 +267,19 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class } // all serializers get arguments with serializers of their generic types argSerializers.forEach { (argType, argSerializer) -> - assert(stackValueSerializerInstance(codegen, module, argType, argSerializer, this, argType.genericIndex, genericSerializerFieldGetter)) + assert( + stackValueSerializerInstance( + codegen, + module, + argType, + argSerializer, + this, + argType.genericIndex, + genericSerializerFieldGetter + ) + ) // wrap into nullable serializer if argType is nullable - if (argType.isMarkedNullable) { - invokestatic("kotlinx/serialization/internal/NullableSerializerKt", "makeNullable", // todo: extract? - "(" + kSerializerType.descriptor + ")" + kSerializerType.descriptor, false) - - } + if (argType.isMarkedNullable) wrapStackValueIntoNullableSerializer() signature.append(kSerializerType.descriptor) } signature.append(")V") @@ -256,6 +289,12 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class return true } +fun InstructionAdapter.wrapStackValueIntoNullableSerializer() = + invokestatic( + "kotlinx/serialization/internal/NullableSerializerKt", "makeNullable", + "(" + kSerializerType.descriptor + ")" + kSerializerType.descriptor, false + ) + // // ======= Serializers Resolving ======= // @@ -291,11 +330,13 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty, ty // reference elements serializer = property.module.findClassAcrossModuleDependencies(referenceArraySerializerId) } - // primitive elements are not supported yet + // primitive elements are not supported yet } } - return JVMSerialTypeInfo(property, Type.getType("Ljava/lang/Object;"), - if (property.type.isMarkedNullable) "Nullable" else "", serializer) + return JVMSerialTypeInfo( + property, Type.getType("Ljava/lang/Object;"), + if (property.type.isMarkedNullable) "Nullable" else "", serializer + ) } OBJECT -> { // no explicit serializer for this property. Check other built in types @@ -312,8 +353,10 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty, ty property.descriptor.annotations, property.descriptor.findPsi() ) - return JVMSerialTypeInfo(property, Type.getType("Ljava/lang/Object;"), - if (property.type.isMarkedNullable) "Nullable" else "", serializer) + return JVMSerialTypeInfo( + property, Type.getType("Ljava/lang/Object;"), + if (property.type.isMarkedNullable) "Nullable" else "", serializer + ) } else -> throw AssertionError("Unexpected sort for $type") // should not happen } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt index 88507ddd7c7..99b9396ddb2 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt @@ -40,6 +40,9 @@ class SerializerCodegenImpl( private val serializerAsmType = codegen.typeMapper.mapClass(codegen.descriptor) private val serializableAsmType = codegen.typeMapper.mapClass(serializableClass) + // if we have type parameters, descriptor initializing must be performed in constructor + private val staticDescriptor = serializableDescriptor.declaredTypeParameters.isEmpty() + companion object { fun generateSerializerExtensions(codegen: ImplementationBodyCodegen) { val serializableClass = getSerializableClassDescriptorBySerializer(codegen.descriptor) ?: return @@ -55,64 +58,86 @@ class SerializerCodegenImpl( ) } - codegen.generateMethod(typedConstructorDescriptor) { _, _ -> + var locals: Int = 0 + codegen.generateMethod(typedConstructorDescriptor) { _, exprGen -> load(0, serializerAsmType) invokespecial("java/lang/Object", "", "()V", false) serializableDescriptor.declaredTypeParameters.forEachIndexed { i, _ -> load(0, serializerAsmType) - load(i+1, kSerializerType) + load(++locals, kSerializerType) putfield(serializerAsmType.internalName, "$typeArgPrefix$i", kSerializerType.descriptor) } + if (!staticDescriptor) exprGen.generateSerialDescriptor(++locals, false) areturn(Type.VOID_TYPE) } } - override fun generateSerialDesc() { - codegen.v.newField(OtherOrigin(codegen.myClass.psiOrParent), ACC_PRIVATE or ACC_STATIC or ACC_FINAL or ACC_SYNTHETIC, - serialDescField, descType.descriptor, null, null) - // todo: lazy initialization of $$serialDesc that is performed only when save/load is invoked first time - val expr = codegen.createOrGetClInitCodegen() - with(expr.v) { - val classDescVar = 0 - anew(descImplType) - dup() - aconst(serialName) - invokespecial(descImplType.internalName, "", "(Ljava/lang/String;)V", false) - store(classDescVar, descImplType) - for (property in orderedProperties) { - if (property.transient) continue - load(classDescVar, descImplType) - aconst(property.name) - invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;)V", false) - // pushing annotations - for ((annotationClass, args, consParams) in property.annotationsWithArguments) { - if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet") - load(classDescVar, descImplType) - expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) - invokevirtual( - descImplType.internalName, - CallingConventions.addAnnotation, - "(Ljava/lang/annotation/Annotation;)V", - false - ) - } - } - // add annotations on class itself - for ((annotationClass, args, consParams) in serializableDescriptor.annotationsWithArguments()) { + private fun ExpressionCodegen.generateSerialDescriptor(descriptorVar: Int, isStatic: Boolean) = with(v) { + anew(descImplType) + dup() + aconst(serialName) + if (isStatic) { + assert(serializerDescriptor.kind == ClassKind.OBJECT) { "Serializer for type without type parameters must be an object" } + // static descriptor means serializer is an object. it is safer to get it from correct field + StackValue.singleton(serializerDescriptor, codegen.typeMapper).put(generatedSerializerType, this) + } else { + load(0, serializerAsmType) + } + invokespecial(descImplType.internalName, "", "(Ljava/lang/String;${generatedSerializerType.descriptor})V", false) + store(descriptorVar, descImplType) + for (property in orderedProperties) { + if (property.transient) continue + load(descriptorVar, descImplType) + aconst(property.name) + iconst(if (property.optional) 1 else 0) + invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;Z)V", false) + // pushing annotations + for ((annotationClass, args, consParams) in property.annotationsWithArguments) { if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet") - load(classDescVar, descImplType) - expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) + load(descriptorVar, descImplType) + generateSyntheticAnnotationOnStack(annotationClass, args, consParams) invokevirtual( descImplType.internalName, - CallingConventions.addClassAnnotation, + CallingConventions.addAnnotation, "(Ljava/lang/annotation/Annotation;)V", false ) } - load(classDescVar, descImplType) - putstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) } + // add annotations on class itself + for ((annotationClass, args, consParams) in serializableDescriptor.annotationsWithArguments()) { + if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet") + load(descriptorVar, descImplType) + generateSyntheticAnnotationOnStack(annotationClass, args, consParams) + invokevirtual( + descImplType.internalName, + CallingConventions.addClassAnnotation, + "(Ljava/lang/annotation/Annotation;)V", + false + ) + } + if (isStatic) { + load(descriptorVar, descImplType) + putstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) + } else { + load(0, serializerAsmType) + load(descriptorVar, descImplType) + putfield(serializerAsmType.internalName, serialDescField, descType.descriptor) + } + } + + override fun generateSerialDesc() { + var flags = ACC_PRIVATE or ACC_FINAL or ACC_SYNTHETIC + if (staticDescriptor) flags = flags or ACC_STATIC + codegen.v.newField( + OtherOrigin(codegen.myClass.psiOrParent), flags, + serialDescField, descType.descriptor, null, null + ) + // todo: lazy initialization of $$serialDesc ? + if (!staticDescriptor) return + val expr = codegen.createOrGetClInitCodegen() + expr.generateSerialDescriptor(0, true) } private fun ExpressionCodegen.generateSyntheticAnnotationOnStack( @@ -139,18 +164,44 @@ class SerializerCodegenImpl( } } - private fun InstructionAdapter.serialCLassDescToLocalVar(classDescVar: Int) { - getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) - store(classDescVar, descType) + // use null to put value on stack, use number to store it to var + private fun InstructionAdapter.stackSerialClassDesc(classDescVar: Int?) { + if (staticDescriptor) + getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) + else { + load(0, serializerAsmType) + getfield(serializerAsmType.internalName, serialDescField, descType.descriptor) + } + classDescVar?.let { store(it, descType) } } override fun generateSerializableClassProperty(property: PropertyDescriptor) { codegen.generateMethod(property.getter!!) { _, _ -> - getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) + stackSerialClassDesc(null) areturn(descType) } } + override fun generateChildSerializersGetter(function: FunctionDescriptor) { + codegen.generateMethod(function) { _, _ -> + val size = orderedProperties.size + iconst(size) + newarray(kSerializerType) + for (i in 0 until size) { + dup() // array + iconst(i) // index + val prop = orderedProperties[i] + stackValueSerializerInstanceFromSerializerWithoutSti( + codegen, + prop, + this@SerializerCodegenImpl + ) + astore(kSerializerType) + } + areturn(kSerializerArrayType) + } + } + override fun generateSave( function: FunctionDescriptor ) { @@ -159,7 +210,7 @@ class SerializerCodegenImpl( val outputVar = 1 val objVar = 2 val descVar = 3 - serialCLassDescToLocalVar(descVar) + stackSerialClassDesc(descVar) val objType = signature.valueParameters[1].asmType // output = output.writeBegin(classDesc, new KSerializer[0]) load(outputVar, encoderType) @@ -236,7 +287,7 @@ class SerializerCodegenImpl( val blocksCnt = orderedProperties.size / OPT_MASK_BITS + 1 fun bitMaskOff(i: Int) = bitMaskBase + (i / OPT_MASK_BITS) * OPT_MASK_TYPE.size val propsStartVar = bitMaskBase + OPT_MASK_TYPE.size * blocksCnt - serialCLassDescToLocalVar(descVar) + stackSerialClassDesc(descVar) // boolean readAll = false iconst(0) store(readAllVar, Type.BOOLEAN_TYPE) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt index bbe14f0bdf5..77322348301 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt @@ -35,21 +35,26 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackage fun isKSerializer(type: KotlinType?): Boolean = - type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.KSERIALIZER_NAME_FQ) + type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.KSERIALIZER_NAME_FQ) + +fun isGeneratedKSerializer(type: KotlinType?): Boolean = + type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.GENERATED_SERIALIZER_FQ) fun ClassDescriptor.getKSerializerDescriptor(): ClassDescriptor = - module.findClassAcrossModuleDependencies(ClassId(packageFqName, SerialEntityNames.KSERIALIZER_NAME))!! + module.getClassFromInternalSerializationPackage(SerialEntityNames.GENERATED_SERIALIZER_CLASS.identifier) -fun ClassDescriptor.getKSerializerType(argument: SimpleType): SimpleType { +fun ClassDescriptor.createGeneratedSerializerTypeFor(argument: SimpleType): SimpleType { val projectionType = Variance.INVARIANT val types = listOf(TypeProjectionImpl(projectionType, argument)) return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, getKSerializerDescriptor(), types) } internal fun extractKSerializerArgumentFromImplementation(implementationClass: ClassDescriptor): KotlinType? { - val kSerializerSupertype = implementationClass.typeConstructor.supertypes - .find { isKSerializer(it) } ?: return null + val supertypes = implementationClass.typeConstructor.supertypes + val kSerializerSupertype = supertypes.find { isGeneratedKSerializer(it) } + ?: supertypes.find { isKSerializer(it) } + ?: return null return kSerializerSupertype.arguments.first().type } @@ -140,7 +145,11 @@ fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor): fun getSerializableClassDescriptorBySerializer(serializerDescriptor: ClassDescriptor): ClassDescriptor? { val serializerForClass = serializerDescriptor.annotations.serializerForClass if (serializerForClass != null) return serializerForClass.toClassDescriptor - if (serializerDescriptor.name != SerialEntityNames.SERIALIZER_CLASS_NAME) return null + if (serializerDescriptor.name !in setOf( + SerialEntityNames.SERIALIZER_CLASS_NAME, + SerialEntityNames.GENERATED_SERIALIZER_CLASS + ) + ) return null val classDescriptor = (serializerDescriptor.containingDeclaration as? ClassDescriptor) ?: return null if (!classDescriptor.isInternalSerializable) return null return classDescriptor @@ -187,7 +196,7 @@ private fun ModuleDescriptor.getFromPackage(packageFqName: FqName, classSimpleNa Name.identifier(classSimpleName) ) ) -) { "Can't locate class $classSimpleName" } +) { "Can't locate class $classSimpleName from package $packageFqName" } fun ClassDescriptor.getClassFromSerializationPackage(classSimpleName: String) = requireNotNull(module.findClassAcrossModuleDependencies(ClassId(packageFqName, Name.identifier(classSimpleName)))) {"Can't locate class $classSimpleName"} diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index 9084552c1c1..635074aa6f5 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -57,7 +57,7 @@ object KSerializerDescriptorResolver { fun addSerializerSupertypes(classDescriptor: ClassDescriptor, supertypes: MutableList) { val serializableClassDescriptor = getSerializableClassDescriptorBySerializer(classDescriptor) ?: return if (supertypes.none(::isKSerializer)) { - supertypes.add(classDescriptor.getKSerializerType(serializableClassDescriptor.defaultType)) + supertypes.add(classDescriptor.createGeneratedSerializerTypeFor(serializableClassDescriptor.defaultType)) } } @@ -157,16 +157,15 @@ object KSerializerDescriptorResolver { fromSupertypes.none { checkParameters(it) && it.modality == Modality.FINAL } } - if (name == SerialEntityNames.SAVE_NAME && - shouldAddSerializerFunction { classDescriptor.checkSaveMethodParameters(it.valueParameters) } - ) { - result.add(createSaveFunctionDescriptor(thisDescriptor)) - } + val isSave = name == SerialEntityNames.SAVE_NAME && + shouldAddSerializerFunction { classDescriptor.checkSaveMethodParameters(it.valueParameters) } + val isLoad = name == SerialEntityNames.LOAD_NAME && + shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) } + val isDescriptorGetter = name == SerialEntityNames.GENERATED_DESCRIPTOR_GETTER && + shouldAddSerializerFunction { true /* TODO? */ } - if (name == SerialEntityNames.LOAD_NAME && - shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) } - ) { - result.add(createLoadFunctionDescriptor(thisDescriptor)) + if (isSave || isLoad || isDescriptorGetter) { + result.add(doCreateSerializerFunction(thisDescriptor, name)) } } @@ -176,12 +175,6 @@ object KSerializerDescriptorResolver { ): PropertyDescriptor = doCreateSerializerProperty(companionDescriptor, classDescriptor, SerialEntityNames.SERIAL_DESC_FIELD_NAME) - fun createSaveFunctionDescriptor(companionDescriptor: ClassDescriptor): SimpleFunctionDescriptor = - doCreateSerializerFunction(companionDescriptor, SerialEntityNames.SAVE_NAME) - - fun createLoadFunctionDescriptor(companionDescriptor: ClassDescriptor): SimpleFunctionDescriptor = - doCreateSerializerFunction(companionDescriptor, SerialEntityNames.LOAD_NAME) - private fun doCreateSerializerProperty( companionDescriptor: ClassDescriptor, classDescriptor: ClassDescriptor, diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt index 61717b797cf..eedd8947f68 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt @@ -38,6 +38,9 @@ object SerialEntityNames { val SERIALIZER_CLASS_NAME = Name.identifier(SERIALIZER_CLASS) val IMPL_NAME = Name.identifier("Impl") + val GENERATED_SERIALIZER_CLASS = Name.identifier("GeneratedSerializer") + val GENERATED_SERIALIZER_FQ = SerializationPackages.internalPackageFqName.child(GENERATED_SERIALIZER_CLASS) + const val ENCODER_CLASS = "Encoder" const val STRUCTURE_ENCODER_CLASS = "CompositeEncoder" const val DECODER_CLASS = "Decoder" @@ -58,6 +61,7 @@ object SerialEntityNames { val SERIAL_DESC_FIELD_NAME = Name.identifier(SERIAL_DESC_FIELD) val SAVE_NAME = Name.identifier(SAVE) val LOAD_NAME = Name.identifier(LOAD) + val GENERATED_DESCRIPTOR_GETTER = Name.identifier("childSerializers") val WRITE_SELF_NAME = Name.identifier("write\$Self") val SERIALIZER_PROVIDER_NAME = Name.identifier("serializer")