[FIR] forbid resolve from `currentDeclarationDeprecationsAreDefinitelyEmpty`

as `currentDeclarationDeprecationsAreDefinitelyEmpty` should be a check for a fast path.

KT-70114
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirLazyDeclarationResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirLazyDeclarationResolver.kt
index 14b1ba6..5a2a4f2 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirLazyDeclarationResolver.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirLazyDeclarationResolver.kt
@@ -22,6 +22,7 @@
     override fun finishResolvingPhase(phase: FirResolvePhase) {}
 
     override fun lazyResolveToPhase(element: FirElementWithResolveState, toPhase: FirResolvePhase) {
+        assertLazyResolveAllowed()
         val session = element.llFirResolvableSession ?: return
         session.moduleComponents.firModuleLazyDeclarationResolver.lazyResolve(
             target = element,
@@ -30,6 +31,7 @@
     }
 
     override fun lazyResolveToPhaseWithCallableMembers(clazz: FirClass, toPhase: FirResolvePhase) {
+        assertLazyResolveAllowed()
         val fir = clazz as? FirRegularClass ?: return
         val session = fir.llFirResolvableSession ?: return
         session.moduleComponents.firModuleLazyDeclarationResolver.lazyResolveWithCallableMembers(
@@ -46,6 +48,7 @@
     }
 
     override fun lazyResolveToPhaseRecursively(element: FirElementWithResolveState, toPhase: FirResolvePhase) {
+        assertLazyResolveAllowed()
         val session = element.llFirResolvableSession ?: return
         session.moduleComponents.firModuleLazyDeclarationResolver.lazyResolveRecursively(
             target = element,
diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirLazyDeclarationResolver.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirLazyDeclarationResolver.kt
index 0c2bc69..68add2f 100644
--- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirLazyDeclarationResolver.kt
+++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirLazyDeclarationResolver.kt
@@ -31,6 +31,11 @@
     val lazyResolveContractChecksEnabled: Boolean
         get() = _lazyResolveContractChecksEnabled.get()
 
+
+    @PrivateForInline
+    @Suppress("PropertyName")
+    val _lazyResolveIsAllowed: ThreadLocal<Boolean> = ThreadLocal.withInitial { true }
+
     abstract fun startResolvingPhase(phase: FirResolvePhase)
 
     abstract fun finishResolvingPhase(phase: FirResolvePhase)
@@ -51,6 +56,24 @@
         }
     }
 
+    @OptIn(PrivateForInline::class)
+    inline fun <T> forbidLazyResolveInside(action: () -> T): T {
+        val current = _lazyResolveIsAllowed.get()
+        _lazyResolveIsAllowed.set(false)
+        try {
+            return action()
+        } finally {
+            _lazyResolveIsAllowed.set(current)
+        }
+    }
+
+    @OptIn(PrivateForInline::class)
+    protected fun assertLazyResolveAllowed() {
+        if (!_lazyResolveIsAllowed.get()) {
+            throw FirLazyResolveForbiddenException()
+        }
+    }
+
     /**
      * @see org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
      */
@@ -67,6 +90,8 @@
     abstract fun lazyResolveToPhaseRecursively(element: FirElementWithResolveState, toPhase: FirResolvePhase)
 }
 
+class FirLazyResolveForbiddenException() : IllegalStateException("Lazy resolve is forbidden")
+
 class FirLazyResolveContractViolationException(
     currentPhase: FirResolvePhase,
     requestedPhase: FirResolvePhase,
diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt
index 8ec25b5..f75e849 100644
--- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt
+++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt
@@ -8,6 +8,7 @@
 import org.jetbrains.kotlin.config.LanguageVersionSettings
 import org.jetbrains.kotlin.fir.declarations.*
 import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
+import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
 import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
 import org.jetbrains.kotlin.fir.types.*
 import org.jetbrains.kotlin.mpp.CallableSymbolMarker
@@ -114,15 +115,17 @@
      * such as parent or child declarations.
      */
     internal fun currentDeclarationDeprecationsAreDefinitelyEmpty(): Boolean {
-        if (origin is FirDeclarationOrigin.Java) {
-            // Java may perform lazy resolution when accessing FIR tree internals, see KT-55387
+        moduleData.session.lazyDeclarationResolver.forbidLazyResolveInside {
+            if (origin is FirDeclarationOrigin.Java) {
+                // Java may perform lazy resolution when accessing FIR tree internals, see KT-55387
+                return false
+            }
+            if (annotations.isEmpty() && fir.versionRequirements.isNullOrEmpty() && !rawStatus.isOverride) return true
+            if (fir.deprecationsProvider == EmptyDeprecationsProvider) {
+                return true
+            }
             return false
         }
-        if (annotations.isEmpty() && fir.versionRequirements.isNullOrEmpty() && !rawStatus.isOverride) return true
-        if (fir.deprecationsProvider == EmptyDeprecationsProvider) {
-            return true
-        }
-        return false
     }
 
     private fun ensureType(typeRef: FirTypeRef?) {