WIP 3
diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt
index a295948..cbd0f56 100644
--- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt
+++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt
@@ -36,9 +36,7 @@
     }
 
     open fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<FirAnnotation> {
-        if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) return emptyList()
-        val annotations = classProto.getExtension(protocol.classAnnotation).orEmpty()
-        return annotations.map { deserializeAnnotation(session, it, nameResolver) }
+        return classProto.loadAnnotations(session, protocol.classAnnotation, classProto.flags, nameResolver)
     }
 
     fun loadTypeAliasAnnotations(aliasProto: ProtoBuf.TypeAlias, nameResolver: NameResolver): List<FirAnnotation> {
@@ -194,3 +192,5 @@
         return annotations.map { deserializeAnnotation(session, it, nameResolver, useSiteTarget) }
     }
 }
+
+
diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AnnotationDeserializationUtil.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AnnotationDeserializationUtil.kt
index c944d54..1eed61c 100644
--- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AnnotationDeserializationUtil.kt
+++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AnnotationDeserializationUtil.kt
@@ -57,6 +57,8 @@
 import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.name.StandardClassIds
+import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
+import org.jetbrains.kotlin.protobuf.GeneratedMessageLite.ExtendableMessage
 import org.jetbrains.kotlin.serialization.deserialization.getClassId
 import org.jetbrains.kotlin.serialization.deserialization.getName
 import org.jetbrains.kotlin.types.ConstantValueKind
@@ -81,6 +83,29 @@
     }
 }
 
+fun <T : ExtendableMessage<T>> T.loadAnnotations(
+    session: FirSession,
+    extension: GeneratedMessageLite.GeneratedExtension<T, List<ProtoBuf.Annotation>>?,
+    flags: Int,
+    nameResolver: NameResolver,
+    useSiteTarget: AnnotationUseSiteTarget? = null
+): List<FirAnnotation> {
+    if (extension == null || flags >= 0 && !Flags.HAS_ANNOTATIONS.get(flags)) return emptyList()
+    val annotations = getExtension(extension)
+    return annotations.map { deserializeAnnotation(session, it, nameResolver, useSiteTarget) }
+}
+
+fun <T : ExtendableMessage<T>> T.loadAnnotations(
+    session: FirSession,
+    extension: GeneratedMessageLite.GeneratedExtension<T, List<ProtoBuf.Annotation>>?,
+    nameResolver: NameResolver,
+    useSiteTarget: AnnotationUseSiteTarget? = null
+): List<FirAnnotation> {
+    if (extension == null) return emptyList()
+    val annotations = getExtension(extension)
+    return annotations.map { deserializeAnnotation(session, it, nameResolver, useSiteTarget) }
+}
+
 private fun createArgumentMapping(
     session: FirSession,
     proto: ProtoBuf.Annotation,
diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt
index 032570b..b1293c4 100644
--- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt
+++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt
@@ -7,14 +7,151 @@
 
 import org.jetbrains.kotlin.fir.FirSession
 import org.jetbrains.kotlin.fir.expressions.FirAnnotation
+import org.jetbrains.kotlin.fir.expressions.FirExpression
+import org.jetbrains.kotlin.fir.types.FirTypeRef
 import org.jetbrains.kotlin.metadata.ProtoBuf
 import org.jetbrains.kotlin.metadata.deserialization.Flags
 import org.jetbrains.kotlin.metadata.deserialization.NameResolver
+import org.jetbrains.kotlin.metadata.deserialization.TypeTable
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.protobuf.MessageLite
 import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
+import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
 
 class FirBuiltinAnnotationDeserializer(
-    session: FirSession
-) : AbstractAnnotationDeserializer(session, BuiltInSerializerProtocol) {
+    private val session: FirSession
+) : AnnotationDeserializer {
+
+    override fun inheritAnnotationInfo(parent: AnnotationDeserializer) = Unit
+
+    override fun loadClassAnnotations(
+        classProto: ProtoBuf.Class,
+        nameResolver: NameResolver,
+    ): List<FirAnnotation> {
+        return classProto.loadAnnotations(session, BuiltInSerializerProtocol.classAnnotation, classProto.flags, nameResolver)
+    }
+
+    override fun loadTypeAliasAnnotations(
+        aliasProto: ProtoBuf.TypeAlias,
+        nameResolver: NameResolver,
+    ): List<FirAnnotation> {
+        if (!Flags.HAS_ANNOTATIONS.get(aliasProto.flags)) return emptyList()
+        return aliasProto.annotationList.map { deserializeAnnotation(session, it, nameResolver) }
+    }
+
+    override fun loadFunctionAnnotations(
+        containerSource: DeserializedContainerSource?,
+        functionProto: ProtoBuf.Function,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): List<FirAnnotation> {
+        return functionProto.loadAnnotations(session, BuiltInSerializerProtocol.functionAnnotation, functionProto.flags, nameResolver)
+    }
+
+    override fun loadPropertyAnnotations(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        containingClassProto: ProtoBuf.Class?,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadPropertyBackingFieldAnnotations(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadPropertyDelegatedFieldAnnotations(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadPropertyGetterAnnotations(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+        getterFlags: Int,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadPropertySetterAnnotations(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+        setterFlags: Int,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadConstructorAnnotations(
+        containerSource: DeserializedContainerSource?,
+        constructorProto: ProtoBuf.Constructor,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadValueParameterAnnotations(
+        containerSource: DeserializedContainerSource?,
+        callableProto: MessageLite,
+        valueParameterProto: ProtoBuf.ValueParameter,
+        classProto: ProtoBuf.Class?,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+        kind: AnnotationDeserializer.CallableKind,
+        parameterIndex: Int,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadEnumEntryAnnotations(
+        classId: ClassId,
+        enumEntryProto: ProtoBuf.EnumEntry,
+        nameResolver: NameResolver,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadExtensionReceiverParameterAnnotations(
+        containerSource: DeserializedContainerSource?,
+        callableProto: MessageLite,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+        kind: AnnotationDeserializer.CallableKind,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadAnnotationPropertyDefaultValue(
+        containerSource: DeserializedContainerSource?,
+        propertyProto: ProtoBuf.Property,
+        expectedPropertyType: FirTypeRef,
+        nameResolver: NameResolver,
+        typeTable: TypeTable,
+    ): FirExpression? {
+        TODO("Not yet implemented")
+    }
+
+    override fun loadTypeParameterAnnotations(
+        typeParameterProto: ProtoBuf.TypeParameter,
+        nameResolver: NameResolver,
+    ): List<FirAnnotation> {
+        TODO("Not yet implemented")
+    }
 
     override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotation> {
         if (!Flags.HAS_ANNOTATIONS.get(typeProto.flags)) return emptyList()
@@ -22,3 +159,5 @@
         return annotations.map { deserializeAnnotation(session, it, nameResolver) }
     }
 }
+
+