[Swift Export]: Convert hierarchy-dependent computed properties into resettable lazyvars with parent-observing
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt
index feed4f3..7edd649 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Implementation.kt
@@ -7,15 +7,12 @@
 
 import org.jetbrains.kotlin.generators.tree.AbstractImplementation
 import org.jetbrains.kotlin.generators.tree.ImplementationKind
-import org.jetbrains.kotlin.generators.tree.printer.ImportCollectingPrinter
 
 class Implementation(element: Element, name: String?) : AbstractImplementation<Implementation, Element, Field>(element, name) {
     override val allFields: List<Field> = element.allFields.map { it.copy() }
 
     override var kind: ImplementationKind? = ImplementationKind.FinalClass
 
-    var generationCallback: (ImportCollectingPrinter.() -> Unit)? = null
-
     var hasConstructorIndicator = false
     var bindOwnedSymbol = true
     override var doPrint = true
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/symbol/SymbolImplementation.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/symbol/SymbolImplementation.kt
index 39b3d96..9b35e2e 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/symbol/SymbolImplementation.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/symbol/SymbolImplementation.kt
@@ -6,16 +6,12 @@
 package org.jetbrains.kotlin.ir.generator.model.symbol
 
 import org.jetbrains.kotlin.generators.tree.AbstractImplementation
-import org.jetbrains.kotlin.generators.tree.printer.ImportCollectingPrinter
-import org.jetbrains.kotlin.ir.generator.idSignatureType
 
 class SymbolImplementation(
     symbol: Symbol,
     name: String?
 ) : AbstractImplementation<SymbolImplementation, Symbol, SymbolField>(symbol, name) {
 
-    var generationCallback: (ImportCollectingPrinter.() -> Unit)? = null
-
     override val allFields: List<SymbolField>
         get() = emptyList()
 
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt
index 529d7c4..ed9f127 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ImplementationPrinter.kt
@@ -36,8 +36,6 @@
         get() = true
 
     override fun ImportCollectingPrinter.printAdditionalMethods(implementation: Implementation) {
-        implementation.generationCallback?.invoke(this)
-
         if (implementation.element.isSubclassOf(IrTree.symbolOwner) && implementation.bindOwnedSymbol) {
             val symbolField = implementation.getOrNull("symbol")
             if (symbolField != null) {
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/symbol/SymbolImplementationPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/symbol/SymbolImplementationPrinter.kt
index e27f4b0..883c073 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/symbol/SymbolImplementationPrinter.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/symbol/SymbolImplementationPrinter.kt
@@ -40,8 +40,4 @@
             add(FunctionParameter("signature", idSignatureType.copy(nullable = true), "null"))
         }
     }
-
-    override fun ImportCollectingPrinter.printAdditionalMethods(implementation: SymbolImplementation) {
-        implementation.generationCallback?.invoke(this)
-    }
 }
\ No newline at end of file
diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt
index 9a54b6b1..3b621d9 100644
--- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt
+++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractFieldPrinter.kt
@@ -69,7 +69,7 @@
             )
             println()
 
-            if (defaultValue != null && defaultValue.withGetter) {
+            if (!inConstructor && defaultValue != null && defaultValue.withGetter) {
                 withIndent {
                     println("get() = ${defaultValue.defaultValue}")
                 }
diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt
index 7f1c09e..b3de409 100644
--- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt
+++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementation.kt
@@ -7,6 +7,7 @@
 
 import org.jetbrains.kotlin.generators.tree.imports.ImportCollecting
 import org.jetbrains.kotlin.generators.tree.imports.Importable
+import org.jetbrains.kotlin.generators.tree.printer.ImportCollectingPrinter
 
 /**
  * A class representing a non-abstract implementation of an abstract class/interface of a tree node.
@@ -76,12 +77,14 @@
     private fun withDefault(field: Field) =
         !field.isFinal && field.implementationDefaultStrategy !is AbstractField.ImplementationDefaultStrategy.Required
 
-    val fieldsInConstructor by lazy { allFields.filter { !withDefault(it) || it.customSetter != null } }
+    val fieldsInConstructor by lazy { allFields.filterNot(this::withDefault) }
 
     val fieldsInBody by lazy { allFields.filter { withDefault(it) || it.customSetter != null } }
 
     var requiresOptIn = false
 
+    var generationCallback: (ImportCollectingPrinter.() -> Unit)? = null
+
     override var kind: ImplementationKind? = null
         set(value) {
             field = value
diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt
index 39bbf38..5bff664 100644
--- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt
+++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractImplementationPrinter.kt
@@ -126,6 +126,7 @@
                         )
                     }
 
+                    implementation.generationCallback?.invoke(this)
                     printAdditionalMethods(implementation)
                 }
             }
diff --git a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirClassFromKtSymbol.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirClassFromKtSymbol.kt
index cb69422..b79e45f 100644
--- a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirClassFromKtSymbol.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirClassFromKtSymbol.kt
@@ -25,7 +25,9 @@
 import org.jetbrains.sir.lightclasses.extensions.documentation
 import org.jetbrains.sir.lightclasses.extensions.lazyWithSessions
 import org.jetbrains.sir.lightclasses.extensions.withSessions
+import org.jetbrains.sir.lightclasses.utils.LazyVar
 import org.jetbrains.sir.lightclasses.utils.computeIsOverride
+import org.jetbrains.sir.lightclasses.utils.lazyVar
 import org.jetbrains.sir.lightclasses.utils.translatedAttributes
 
 internal fun createSirClassFromKtSymbol(
@@ -186,9 +188,16 @@
     override val documentation: String? = null
     override val isRequired: Boolean = false
     override val isConvenience: Boolean = false
-    override val isOverride: Boolean get() = computeIsOverride()
+    override val isOverride: Boolean by lazyVar { computeIsOverride() }
     override lateinit var parent: SirDeclarationParent
     override val attributes: MutableList<SirAttribute> = mutableListOf()
     override val errorType: SirType get() = SirType.never
     override var body: SirFunctionBody? = null
+
+    @Suppress("NO_REFLECTION_IN_CLASS_PATH")
+    override fun onParentChange(from: SirDeclarationParent?, to: SirDeclarationParent) {
+        super.onParentChange(from, to)
+
+        LazyVar.reset(this::isOverride)
+    }
 }
diff --git a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirFunctionFromKtSymbol.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirFunctionFromKtSymbol.kt
index ba1d55b..be1fff6 100644
--- a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirFunctionFromKtSymbol.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirFunctionFromKtSymbol.kt
@@ -54,13 +54,14 @@
         }
         set(_) = Unit
 
-    override val isOverride: Boolean
-        get() = isInstance && overridableCandidates.any {
+    override val isOverride: Boolean by lazyVar {
+        isInstance && overridableCandidates.any {
             this.name == it.name &&
-            this.parameters.isSuitableForOverrideOf(it.parameters) &&
-            this.returnType.isSubtypeOf(it.returnType) &&
-            this.isInstance == it.isInstance
+                    this.parameters.isSuitableForOverrideOf(it.parameters) &&
+                    this.returnType.isSubtypeOf(it.returnType) &&
+                    this.isInstance == it.isInstance
         }
+    }
 
     override val isInstance: Boolean
         get() = !ktSymbol.isTopLevel && !ktSymbol.isStatic
@@ -73,4 +74,11 @@
     override val errorType: SirType get() = if (ktSymbol.throwsAnnotation != null) SirType.any else SirType.never
 
     override var body: SirFunctionBody? = null
+
+    @Suppress("NO_REFLECTION_IN_CLASS_PATH")
+    override fun onParentChange(from: SirDeclarationParent?, to: SirDeclarationParent) {
+        super.onParentChange(from, to)
+
+        LazyVar.reset(this::isOverride)
+    }
 }
diff --git a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirInitFromKtSymbol.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirInitFromKtSymbol.kt
index dad2626..2bc6a33 100644
--- a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirInitFromKtSymbol.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirInitFromKtSymbol.kt
@@ -15,7 +15,10 @@
 import org.jetbrains.sir.lightclasses.extensions.documentation
 import org.jetbrains.sir.lightclasses.extensions.lazyWithSessions
 import org.jetbrains.sir.lightclasses.extensions.withSessions
+import org.jetbrains.sir.lightclasses.utils.*
+import org.jetbrains.sir.lightclasses.utils.LazyVar
 import org.jetbrains.sir.lightclasses.utils.computeIsOverride
+import org.jetbrains.sir.lightclasses.utils.lazyVar
 import org.jetbrains.sir.lightclasses.utils.translateParameters
 import org.jetbrains.sir.lightclasses.utils.translatedAttributes
 
@@ -45,7 +48,7 @@
 
     override val isConvenience: Boolean = false
 
-    override val isOverride: Boolean get() = computeIsOverride()
+    override val isOverride: Boolean by lazyVar { computeIsOverride() }
 
     override var parent: SirDeclarationParent
         get() = withSessions {
@@ -58,4 +61,11 @@
     override val errorType: SirType get() = if (ktSymbol.throwsAnnotation != null) SirType.any else SirType.never
 
     override var body: SirFunctionBody? = null
+
+    @Suppress("NO_REFLECTION_IN_CLASS_PATH")
+    override fun onParentChange(from: SirDeclarationParent?, to: SirDeclarationParent) {
+        super.onParentChange(from, to)
+
+        LazyVar.reset(this::isOverride)
+    }
 }
\ No newline at end of file
diff --git a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirTypealiasFromKtSymbol.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirTypealiasFromKtSymbol.kt
index 79f7dcf..8c16e53 100644
--- a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirTypealiasFromKtSymbol.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirTypealiasFromKtSymbol.kt
@@ -16,6 +16,7 @@
 import org.jetbrains.sir.lightclasses.extensions.documentation
 import org.jetbrains.sir.lightclasses.extensions.lazyWithSessions
 import org.jetbrains.sir.lightclasses.extensions.withSessions
+import org.jetbrains.sir.lightclasses.utils.LazyVar
 import org.jetbrains.sir.lightclasses.utils.translatedAttributes
 
 internal class SirTypealiasFromKtSymbol(
diff --git a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirVariableFromKtSymbol.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirVariableFromKtSymbol.kt
index bf9d5c3..a592143 100644
--- a/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirVariableFromKtSymbol.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirVariableFromKtSymbol.kt
@@ -22,7 +22,9 @@
 import org.jetbrains.sir.lightclasses.extensions.documentation
 import org.jetbrains.sir.lightclasses.extensions.lazyWithSessions
 import org.jetbrains.sir.lightclasses.extensions.withSessions
+import org.jetbrains.sir.lightclasses.utils.*
 import org.jetbrains.sir.lightclasses.utils.isSubtypeOf
+import org.jetbrains.sir.lightclasses.utils.lazyVar
 import org.jetbrains.sir.lightclasses.utils.overridableCandidates
 import org.jetbrains.sir.lightclasses.utils.translateReturnType
 import org.jetbrains.sir.lightclasses.utils.translatedAttributes
@@ -72,17 +74,25 @@
         }
         set(_) = Unit
 
-    override val attributes: List<SirAttribute> by lazy { this.translatedAttributes }
+    override val attributes: List<SirAttribute> by lazyVar { this.translatedAttributes }
 
-    override val isOverride: Boolean
-        get() = isInstance && overridableCandidates.any {
+    override val isOverride: Boolean by lazyVar {
+        isInstance && overridableCandidates.any {
             this.name == it.name &&
-            (it.setter == null && this.type.isSubtypeOf(it.type) || this.type == it.type) &&
-            this.isInstance == it.isInstance
+                    (it.setter == null && this.type.isSubtypeOf(it.type) || this.type == it.type) &&
+                    this.isInstance == it.isInstance
         }
+    }
 
     override val modality: SirModality
         get() = ktSymbol.modality.sirModality
+
+    @Suppress("NO_REFLECTION_IN_CLASS_PATH")
+    override fun onParentChange(from: SirDeclarationParent?, to: SirDeclarationParent) {
+        super.onParentChange(from, to)
+
+        LazyVar.reset(this::isOverride)
+    }
 }
 
 internal class SirVariableFromKtSymbol(
diff --git a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/LazyVar.kt b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/utils/LazyVar.kt
similarity index 65%
rename from native/swift/sir/src/org/jetbrains/kotlin/sir/util/LazyVar.kt
rename to native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/utils/LazyVar.kt
index 21635db..f952fed 100644
--- a/native/swift/sir/src/org/jetbrains/kotlin/sir/util/LazyVar.kt
+++ b/native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/utils/LazyVar.kt
@@ -3,14 +3,31 @@
  * 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.sir.util
+package org.jetbrains.sir.lightclasses.utils
 
 import kotlin.reflect.KProperty
+import kotlin.reflect.KProperty0
+import kotlin.reflect.KProperty1
+import kotlin.reflect.KProperty2
 
 internal interface LazyVar<T> : Lazy<T> {
+    @Suppress("UNCHECKED_CAST", "NO_REFLECTION_IN_CLASS_PATH")
+    companion object {
+        fun <V> reset(property: KProperty0<V>): V? =
+            (property.getDelegate() as? LazyVar<V>)?.reset()
+
+        fun <U, V> reset(property: KProperty1<U, V>, receiver: U): V? =
+            (property.getDelegate(receiver) as? LazyVar<V>)?.reset()
+
+        fun <T, U, V> reset(property: KProperty2<T, U, V>, receiver1: T, receiver2: U): V? =
+            (property.getDelegate(receiver1, receiver2) as? LazyVar<V>)?.reset()
+    }
+
     override var value: T
 
     operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) { value = newValue }
+
+    fun reset(): T?
 }
 
 internal fun <T> lazyVar(initializer: () -> T): LazyVar<T> = SynchronizedMutableLazyImpl(initializer)
@@ -52,5 +69,15 @@
 
     override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
 
+    override fun reset(): T? {
+        var oldValue: T?
+        synchronized(lock) {
+            @Suppress("UNCHECKED_CAST")
+            oldValue = _value.takeIf { it != UNINITIALIZED_VALUE } as T?
+            _value = UNINITIALIZED_VALUE
+        }
+        return oldValue
+    }
+
     override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirDeclaration.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirDeclaration.kt
index 0e8e6e2..7db0a3d 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirDeclaration.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/SirDeclaration.kt
@@ -11,7 +11,7 @@
 /**
  * Generated from: [org.jetbrains.kotlin.sir.tree.generator.SwiftIrTree.declaration]
  */
-sealed interface SirDeclaration : SirElement {
+sealed interface SirDeclaration : SirElement, SirHierarchyParticipant {
     val origin: SirOrigin
     val visibility: SirVisibility
     val documentation: String?
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirClassImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirClassImpl.kt
index a67207e..1477fe4 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirClassImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirClassImpl.kt
@@ -23,5 +23,13 @@
     override val protocols: MutableList<SirProtocol>,
     override val modality: SirModality,
 ) : SirClass() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt
index 39cc1d3..bb5d783 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirEnumImpl.kt
@@ -21,5 +21,13 @@
     override val declarations: MutableList<SirDeclaration>,
     override val cases: MutableList<SirEnumCase>,
 ) : SirEnum() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirExtensionImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirExtensionImpl.kt
index 0595312..d5502b6 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirExtensionImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirExtensionImpl.kt
@@ -20,5 +20,13 @@
     override val declarations: MutableList<SirDeclaration>,
     override val extendedType: SirType,
 ) : SirExtension() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt
index 6d1bbfe..faa0deb 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirFunctionImpl.kt
@@ -27,5 +27,13 @@
     override val parameters: MutableList<SirParameter>,
     override val returnType: SirType,
 ) : SirFunction() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirGetterImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirGetterImpl.kt
index e01b524..9dace4a 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirGetterImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirGetterImpl.kt
@@ -20,5 +20,13 @@
     override var body: SirFunctionBody?,
     override val errorType: SirType,
 ) : SirGetter() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt
index 13d9618..6881529 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirInitImpl.kt
@@ -25,5 +25,13 @@
     override val isRequired: Boolean,
     override val isOverride: Boolean,
 ) : SirInit() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirProtocolImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirProtocolImpl.kt
index 862c1e8..2159729 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirProtocolImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirProtocolImpl.kt
@@ -20,5 +20,13 @@
     override val name: String,
     override val declarations: MutableList<SirDeclaration>,
 ) : SirProtocol() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirSetterImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirSetterImpl.kt
index 18cd07f..7edc4b9 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirSetterImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirSetterImpl.kt
@@ -21,5 +21,13 @@
     override val errorType: SirType,
     override val parameterName: String,
 ) : SirSetter() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt
index 3851901..bb91b26 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirStructImpl.kt
@@ -20,5 +20,13 @@
     override val name: String,
     override val declarations: MutableList<SirDeclaration>,
 ) : SirStruct() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirTypealiasImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirTypealiasImpl.kt
index 0ed53d1..b174bb3 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirTypealiasImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirTypealiasImpl.kt
@@ -20,5 +20,13 @@
     override val name: String,
     override val type: SirType,
 ) : SirTypealias() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirVariableImpl.kt b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirVariableImpl.kt
index be7e3f2..6a04e8d 100644
--- a/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirVariableImpl.kt
+++ b/native/swift/sir/gen/org/jetbrains/kotlin/sir/impl/SirVariableImpl.kt
@@ -25,5 +25,13 @@
     override val getter: SirGetter,
     override val setter: SirSetter?,
 ) : SirVariable() {
-    override lateinit var parent: SirDeclarationParent
+    override var parent: SirDeclarationParent
+        get() = _parent
+        set(value) {
+            val oldParent = if (this::_parent.isInitialized) _parent else null
+            _parent = value
+            onParentChange(from = oldParent, to = _parent)
+        }
+
+    private lateinit var _parent: SirDeclarationParent
 }
diff --git a/native/swift/sir/src/org/jetbrains/kotlin/sir/SirHierarchyParticipant.kt b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirHierarchyParticipant.kt
new file mode 100644
index 0000000..1092bd2
--- /dev/null
+++ b/native/swift/sir/src/org/jetbrains/kotlin/sir/SirHierarchyParticipant.kt
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010-2023 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.sir
+
+sealed interface SirHierarchyParticipant : SirElement {
+    fun onParentChange(from: SirDeclarationParent?, to: SirDeclarationParent) {
+        (this as? SirDeclarationContainer)?.declarations?.forEach { it.onParentChange(from, to) }
+    }
+}
diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt
index 1725b49..8751140 100644
--- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt
+++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/ImplementationConfigurator.kt
@@ -18,8 +18,19 @@
         configureFieldInAllImplementations(
             fieldName = "parent",
         ) {
-            isMutable(it)
-            isLateinit(it)
+            implementation.generationCallback = {
+                println()
+                println("private lateinit var _parent: ", SwiftIrTree.declarationParent.render())
+            }
+            default(it) {
+                value = "_parent"
+                withGetter = true
+                customSetter = """
+                               val oldParent = if (this::_parent.isInitialized) _parent else null
+                               _parent = value
+                               onParentChange(from = oldParent, to = _parent)
+                               """
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt
index 7593c8c..c86fff6 100644
--- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt
+++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/SwiftIrTree.kt
@@ -44,6 +44,7 @@
 
     val declaration by sealedElement {
         customParentInVisitor = rootElement
+        parent(hierarchyParticipant)
         +field("origin", originType)
         +field("visibility", swiftVisibilityType)
         +field(name = "documentation", string, nullable = true, mutable = false)
diff --git a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt
index 9247095..5fb1e73 100644
--- a/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt
+++ b/native/swift/sir/tree-generator/src/org/jetbrains/kotlin/sir/tree/generator/Types.kt
@@ -9,6 +9,7 @@
 import org.jetbrains.kotlin.generators.tree.type
 
 val pureAbstractElementType = type(BASE_PACKAGE, "SirElementBase", TypeKind.Class)
+val hierarchyParticipant = type(BASE_PACKAGE, "SirHierarchyParticipant", TypeKind.Interface)
 val swiftVisibilityType = type(BASE_PACKAGE, "SirVisibility", TypeKind.Class)
 val originType = type(BASE_PACKAGE, "SirOrigin", TypeKind.Class)
 val parameterType = type(BASE_PACKAGE, "SirParameter", TypeKind.Class)