[K/N] Serialize full IdSignatures to caches

^KT-61642 Fixed
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt
index 1fa9b19..f341d5b 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrLinker.kt
@@ -20,8 +20,8 @@
 import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker
 import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
 import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter
-import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
-import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
+import org.jetbrains.kotlin.backend.common.serialization.*
+import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
 import org.jetbrains.kotlin.backend.konan.CacheDeserializationStrategy
 import org.jetbrains.kotlin.backend.konan.CachedLibraries
 import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo
@@ -45,7 +45,12 @@
 import org.jetbrains.kotlin.ir.types.classOrNull
 import org.jetbrains.kotlin.ir.util.*
 import org.jetbrains.kotlin.library.KotlinLibrary
+import org.jetbrains.kotlin.library.encodings.WobblyTF8
+import org.jetbrains.kotlin.library.impl.IrArrayMemoryReader
+import org.jetbrains.kotlin.library.impl.IrMemoryArrayWriter
+import org.jetbrains.kotlin.library.impl.IrMemoryStringWriter
 import org.jetbrains.kotlin.library.metadata.impl.KlibResolvedModuleDescriptorsFactoryImpl.Companion.FORWARD_DECLARATIONS_MODULE_NAME
+import org.jetbrains.kotlin.name.FqName
 
 data class SerializedFileReference(val fqName: String, val path: String) {
     constructor(irFile: IrFile) : this(irFile.packageFqName.asString(), irFile.path)
@@ -120,11 +125,35 @@
     }
 }
 
-class SerializedClassFields(val file: SerializedFileReference, val classSignature: Int, val typeParameterSigs: IntArray,
+class SerializedClassFields(val file: SerializedFileReference, val classSignature: IdSignature, val typeParameterSigs: IntArray,
                             val outerThisIndex: Int, val fields: Array<SerializedClassFieldInfo>)
 
 internal object ClassFieldsSerializer {
+
     fun serialize(classFields: List<SerializedClassFields>): ByteArray {
+
+        val protoStringMap = hashMapOf<String, Int>()
+        val protoStringArray = arrayListOf<String>()
+        val protoIdSignatureMap = mutableMapOf<IdSignature, Int>()
+        val protoIdSignatureArray = arrayListOf<ProtoIdSignature>()
+
+        fun serializeString(value: String): Int = protoStringMap.getOrPut(value) {
+            protoStringArray.add(value)
+            protoStringArray.size - 1
+        }
+
+        val idSignatureSerializer = IdSignatureSerializer(
+            ::serializeString,
+            ::serializeString,
+            protoIdSignatureMap,
+            protoIdSignatureArray
+        )
+
+        classFields.forEach {
+            idSignatureSerializer.protoIdSignature(it.classSignature)
+        }
+        val signatures = IrMemoryArrayWriter(protoIdSignatureArray.map { it.toByteArray() }).writeIntoMemory()
+        val signatureStrings = IrMemoryStringWriter(protoStringArray).writeIntoMemory()
         val stringTable = buildStringTable {
             classFields.forEach {
                 +it.file.fqName
@@ -137,7 +166,7 @@
         classFields.forEach {
             stream.writeInt(stringTable.indices[it.file.fqName]!!)
             stream.writeInt(stringTable.indices[it.file.path]!!)
-            stream.writeInt(it.classSignature)
+            stream.writeInt(protoIdSignatureMap[it.classSignature]!!)
             stream.writeIntArray(it.typeParameterSigs)
             stream.writeInt(it.outerThisIndex)
             stream.writeInt(it.fields.size)
@@ -149,16 +178,36 @@
                 stream.writeInt(field.alignment)
             }
         }
-        return stream.buf
+        return IrMemoryArrayWriter(listOf(signatures, signatureStrings, stream.buf)).writeIntoMemory()
     }
 
     fun deserializeTo(data: ByteArray, result: MutableList<SerializedClassFields>) {
-        val stream = ByteArrayStream(data)
+        val reader = IrArrayMemoryReader(data)
+        val signatures = IrArrayMemoryReader(reader.tableItemBytes(0))
+        val signatureStrings = IrArrayMemoryReader(reader.tableItemBytes(1))
+        val libFile: IrLibraryFile = object: IrLibraryFile() {
+            override fun declaration(index: Int) = error("Declarations are not needed for IdSignature deserialization")
+            override fun type(index: Int) = error("Types are not needed for IdSignature deserialization")
+            override fun expressionBody(index: Int) = error("Expression bodies are not needed for IdSignature deserialization")
+            override fun statementBody(index: Int) = error("Statement bodies are not needed for IdSignature deserialization")
+
+            override fun signature(index: Int): ProtoIdSignature {
+                val bytes = signatures.tableItemBytes(index)
+                return ProtoIdSignature.parseFrom(bytes.codedInputStream)
+            }
+
+            private fun deserializeString(index: Int): String = WobblyTF8.decode(signatureStrings.tableItemBytes(index))
+
+            override fun string(index: Int): String = deserializeString(index)
+            override fun debugInfo(index: Int): String = deserializeString(index)
+        }
+        val interner = IrInterningService()
+        val stream = ByteArrayStream(reader.tableItemBytes(2))
         val stringTable = StringTable.deserialize(stream)
         while (stream.hasData()) {
             val fileFqName = stringTable[stream.readInt()]
             val filePath = stringTable[stream.readInt()]
-            val classSignature = stream.readInt()
+            val signatureIndex = stream.readInt()
             val typeParameterSigs = stream.readIntArray()
             val outerThisIndex = stream.readInt()
             val fieldsCount = stream.readInt()
@@ -170,6 +219,13 @@
                 val alignment = stream.readInt()
                 SerializedClassFieldInfo(name, binaryType, type, flags, alignment)
             }
+            val fileSignature = IdSignature.FileSignature(
+                id = Any(),
+                fqName = FqName(fileFqName),
+                fileName = filePath
+            )
+            val idSignatureDeserializer = IdSignatureDeserializer(libFile, fileSignature, interner)
+            val classSignature = idSignatureDeserializer.deserializeIdSignature(signatureIndex)
             result.add(SerializedClassFields(
                     SerializedFileReference(fileFqName, filePath), classSignature, typeParameterSigs, outerThisIndex, fields)
             )
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt
index 83b61ac..7a12b72 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanPartialModuleDeserializer.kt
@@ -229,7 +229,7 @@
         val compatibleMode = CompatibilityMode(libraryAbiVersion).oldSignatures
         return SerializedClassFields(
             SerializedFileReference(fileDeserializationState.file),
-            BinarySymbolData.decode(protoClass.base.symbol).signatureId,
+            signature,
             typeParameterSigs.toIntArray(),
             outerThisIndex,
             Array(fields.size) {
@@ -432,7 +432,7 @@
     private val classesFields by lazy {
         val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
         cache.serializedClassFields.associateBy {
-            it.file.deserializationState.declarationDeserializer.symbolDeserializer.deserializeIdSignature(it.classSignature)
+            it.classSignature
         }
     }