[Lombok] Fix MISSING_DEPENDENCY_CLASS for Lombok-generated builder types

When a Java class uses @Builder with a custom builderMethodName, a user
can write a hand-crafted factory method whose return type is the
Lombok-generated builder class (e.g. TestJavaBuilder).  PSI cannot
resolve that class because it is synthesised by Lombok at compile time
and is absent from the Java source file.  In this situation
JavaClassifierTypeImpl.classifier is null, causing JavaTypeConversion
to fall into the `null` branch which creates ClassId.topLevel(…) for
the builder name.  The resulting ConeClassLikeType has no resolvable
FIR symbol, so FirMissingDependencyClassChecker reports
MISSING_DEPENDENCY_CLASS.

Fix by introducing FirUnresolvedJavaClassNamesProvider in the fir-jvm
module — an optional FirSessionComponent that maps simple class names
to their correct nested ClassIds.  The Lombok plugin provides
LombokUnresolvedJavaClassNamesProvider, which implements this interface
and registers itself in FirSession using FirUnresolvedJavaClassNamesProvider
as the component class (via an unchecked cast in componentClass).

The alias (simpleName → nestedClassId) is registered in
AbstractBuilderGenerator.addEntityMethods, which runs during
getCallableNamesForClass for the entity class.  This is guaranteed to
execute before the return-type enhancement of any user-defined methods
on the same class, ensuring the registry is populated in time for
JavaTypeConversion to consult it.

JavaTypeConversion.toConeKotlinTypeForFlexibleBound now looks up the
provider in the null-classifier case:
  val simpleName = Name.identifier(qualifiedName.substringAfterLast('.'))
  val redirectClassId = session.unresolvedJavaClassNamesProvider
      ?.findClassIdBySimpleName(simpleName)
  val classId = redirectClassId ?: ClassId.topLevel(FqName(qualifiedName))
If the redirect is found the resulting ConeClassLikeType carries the
nested ClassId, FirExtensionDeclarationsSymbolProvider resolves it to
the Lombok-generated FirJavaClass, and no error is emitted.

^KT-83329 Fixed
diff --git a/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/FirUnresolvedJavaClassNamesProvider.kt b/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/FirUnresolvedJavaClassNamesProvider.kt
index 7160351..e2e1cd6 100644
--- a/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/FirUnresolvedJavaClassNamesProvider.kt
+++ b/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/FirUnresolvedJavaClassNamesProvider.kt
@@ -11,10 +11,10 @@
 import org.jetbrains.kotlin.name.Name
 
 /**
- * Allows compiler plugins to register simple-name → [ClassId] mappings for classes that Java PSI cannot resolve
+ * Allows compiler plugins to register simple-name to [ClassId] mappings for classes that Java PSI cannot resolve
  * (e.g., Lombok-generated builder classes that do not appear in Java source).
  *
- * Used by [JavaTypeConversion] to recover the correct nested [ClassId] when [JavaClassifierType.classifier] is null.
+ * Used by JavaTypeConversion to recover the correct nested ClassId when the PSI classifier is null.
  */
 interface FirUnresolvedJavaClassNamesProvider : FirSessionComponent {
     fun findClassIdBySimpleName(simpleName: Name): ClassId?
diff --git a/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt b/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt
index 1514056..e095b3f 100644
--- a/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt
+++ b/compiler/fir/fir-jvm/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt
@@ -21,6 +21,7 @@
 import org.jetbrains.kotlin.load.java.structure.*
 import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.name.StandardClassIds
 import org.jetbrains.kotlin.types.Variance
 import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
@@ -246,7 +247,10 @@
         }
 
         null -> {
-            val classId = ClassId.topLevel(FqName(this.classifierQualifiedName))
+            val qualifiedName = this.classifierQualifiedName
+            val simpleName = Name.identifier(qualifiedName.substringAfterLast('.'))
+            val redirectClassId = session.unresolvedJavaClassNamesProvider?.findClassIdBySimpleName(simpleName)
+            val classId = redirectClassId ?: ClassId.topLevel(FqName(qualifiedName))
             classId.constructClassLikeType(isMarkedNullable = lowerBound != null, attributes = attributes)
         }
 
diff --git a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/FirLombokJavaRegistrar.kt b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/FirLombokJavaRegistrar.kt
index 0459359..8655f5b 100644
--- a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/FirLombokJavaRegistrar.kt
+++ b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/FirLombokJavaRegistrar.kt
@@ -10,6 +10,7 @@
 
 class FirLombokJavaRegistrar : FirExtensionRegistrar() {
     override fun ExtensionRegistrarContext.configurePlugin() {
+        +LombokUnresolvedJavaClassNamesProvider.Factory
         +::AccessorGenerator
         +::WithGenerator
         +::BuilderGenerator
diff --git a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/LombokUnresolvedJavaClassNamesProvider.kt b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/LombokUnresolvedJavaClassNamesProvider.kt
index acab671..f6ff710 100644
--- a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/LombokUnresolvedJavaClassNamesProvider.kt
+++ b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/LombokUnresolvedJavaClassNamesProvider.kt
@@ -15,8 +15,8 @@
 
 class LombokUnresolvedJavaClassNamesProvider(session: FirSession) :
     FirExtensionSessionComponent(session),
-    FirUnresolvedJavaClassNamesProvider
-{
+    FirUnresolvedJavaClassNamesProvider {
+
     private val registry = ConcurrentHashMap<Name, ClassId>()
 
     override fun findClassIdBySimpleName(simpleName: Name): ClassId? = registry[simpleName]
@@ -30,8 +30,6 @@
         get() = FirUnresolvedJavaClassNamesProvider::class as KClass<out FirExtensionSessionComponent>
 
     companion object {
-        val Factory: FirExtensionSessionComponent.Factory = FirExtensionSessionComponent.Factory {
-            LombokUnresolvedJavaClassNamesProvider(it)
-        }
+        val Factory: Factory = Factory { LombokUnresolvedJavaClassNamesProvider(it) }
     }
 }
diff --git a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/generators/AbstractBuilderGenerator.kt b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/generators/AbstractBuilderGenerator.kt
index 4cf6bab..1a21470 100644
--- a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/generators/AbstractBuilderGenerator.kt
+++ b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/generators/AbstractBuilderGenerator.kt
@@ -32,6 +32,7 @@
 import org.jetbrains.kotlin.fir.extensions.NestedClassGenerationContext
 import org.jetbrains.kotlin.fir.java.JavaScopeProvider
 import org.jetbrains.kotlin.fir.java.MutableJavaTypeParameterStack
+import org.jetbrains.kotlin.fir.java.unresolvedJavaClassNamesProvider
 import org.jetbrains.kotlin.fir.java.declarations.*
 import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
 import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
@@ -227,6 +228,12 @@
 
             val existingFunctionNames = context.getExistingFunctionNames()
 
+            // Register alias eagerly so JavaTypeConversion can find Lombok-generated builder classes
+            // by simple name when PSI cannot resolve them (they are absent from Java source).
+            // This must happen before Java type enhancement, hence registration here rather than in
+            // createAndInitializeBuilders (which may be invoked after enhancement).
+            session.unresolvedJavaClassNamesProvider?.registerSimpleNameAlias(builderClassName, builderClassId)
+
             var existingBuilder: FirClassSymbol<*>? = null
             context?.declaredScope?.processClassifiersByName(builderClassName) {
                 if (existingBuilder == null && it is FirClassSymbol<*>) {
@@ -708,4 +715,3 @@
 
 fun JavaType.makeNullable(): JavaType = withAnnotations(annotations + NullabilityJavaAnnotation.Nullable)
 fun JavaType.makeNotNullable(): JavaType = withAnnotations(annotations + NullabilityJavaAnnotation.NotNull)
-