Make androidx.room and androidx.sqlite target Kotlin 2.0

This required the following changes:

 * Suppress 'ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT' in SQLiteException.android.kt and ThreadLocal.jvmAndroid.kt due to being impossible to match annotations in expect when actual is a typealias to a platform type. Meanwhile in room-common repeatable annotations in JVM use @JvmRepeatable while expect uses Kotlin's @Repeatable and while trying to match actual with expect, an error is produced due to @JvmRepeatable and @Repeatable being used together.

 * Fix various annotations mismatch between actual / expect.

 * Removing @JvmField from common code as expect properties have no backing field and @JvmField targets FIELD.

 * Smart-cast is not possible for expect properties, therefore first store in local variable before smart-case usage. Observed in TableInfo, FtsTableInfo, ViewInfo and MigrationUtil.

 * Adding load() and getRefreshKey() to expect LimitOffsetPagingSource to conform to modality of actual overriding those functions.

 * Make a XProcessingEnvConfig a normal class (instead of a data class) since it has a private constructor with a public copy() usage which is now invalid.

 * Set useKsp2=true on projects with KSP and Kotlin language 2.0 (Room KMP test apps).

 * Workaround KSP2 issue with default value of annotations not appearing in value list. Added a get() that returns nullable XAnnotationValue.

 * Workaround KSP2 issue of projecting value class constructor as member of (to support generics).

 * Workaround XPoet creating JavaPoet types of invalid methods (internal) when XProcessingEnvConfig.excludeMethodsWithInvalidJvmSourceNames is set to true due to Kotlin codegen.

Bug: 315461431
Bug: 384600605
Test: Existing
Relnote: "Native APIs updated due to Kotlin 2.0"
Change-Id: I8efb015c88682921780370c8bed5931d9933a319
diff --git a/room/integration-tests/kotlintestapp/build.gradle b/room/integration-tests/kotlintestapp/build.gradle
index ec3391c..8568128 100644
--- a/room/integration-tests/kotlintestapp/build.gradle
+++ b/room/integration-tests/kotlintestapp/build.gradle
@@ -139,3 +139,7 @@
         )
     )
 }
+
+ksp {
+    useKsp2 = true
+}
\ No newline at end of file
diff --git a/room/integration-tests/multiplatformtestapp/build.gradle b/room/integration-tests/multiplatformtestapp/build.gradle
index eeb3329..8d15d0c 100644
--- a/room/integration-tests/multiplatformtestapp/build.gradle
+++ b/room/integration-tests/multiplatformtestapp/build.gradle
@@ -15,6 +15,7 @@
  */
 
 import androidx.build.KmpPlatformsKt
+import androidx.build.KotlinTarget
 import org.apache.commons.io.FileUtils
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
@@ -126,3 +127,11 @@
             provider { layout.projectDirectory.dir("schemas-ksp").getAsFile().getAbsolutePath() }
     )
 }
+
+androidx {
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
+}
+
+ksp {
+    useKsp2 = true
+}
\ No newline at end of file
diff --git a/room/room-common/bcv/native/current.txt b/room/room-common/bcv/native/current.txt
index 627ec0d..b3fd591 100644
--- a/room/room-common/bcv/native/current.txt
+++ b/room/room-common/bcv/native/current.txt
@@ -32,6 +32,9 @@
         enum entry ENABLED // androidx.room/BuiltInTypeConverters.State.ENABLED|null[0]
         enum entry INHERITED // androidx.room/BuiltInTypeConverters.State.INHERITED|null[0]
 
+        final val entries // androidx.room/BuiltInTypeConverters.State.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/BuiltInTypeConverters.State> // androidx.room/BuiltInTypeConverters.State.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/BuiltInTypeConverters.State // androidx.room/BuiltInTypeConverters.State.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/BuiltInTypeConverters.State> // androidx.room/BuiltInTypeConverters.State.values|values#static(){}[0]
     }
@@ -255,6 +258,9 @@
         enum entry ASC // androidx.room/Index.Order.ASC|null[0]
         enum entry DESC // androidx.room/Index.Order.DESC|null[0]
 
+        final val entries // androidx.room/Index.Order.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/Index.Order> // androidx.room/Index.Order.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/Index.Order // androidx.room/Index.Order.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/Index.Order> // androidx.room/Index.Order.values|values#static(){}[0]
     }
@@ -492,6 +498,9 @@
         enum entry FTS3 // androidx.room/FtsOptions.MatchInfo.FTS3|null[0]
         enum entry FTS4 // androidx.room/FtsOptions.MatchInfo.FTS4|null[0]
 
+        final val entries // androidx.room/FtsOptions.MatchInfo.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/FtsOptions.MatchInfo> // androidx.room/FtsOptions.MatchInfo.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/FtsOptions.MatchInfo // androidx.room/FtsOptions.MatchInfo.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/FtsOptions.MatchInfo> // androidx.room/FtsOptions.MatchInfo.values|values#static(){}[0]
     }
@@ -500,6 +509,9 @@
         enum entry ASC // androidx.room/FtsOptions.Order.ASC|null[0]
         enum entry DESC // androidx.room/FtsOptions.Order.DESC|null[0]
 
+        final val entries // androidx.room/FtsOptions.Order.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/FtsOptions.Order> // androidx.room/FtsOptions.Order.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/FtsOptions.Order // androidx.room/FtsOptions.Order.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/FtsOptions.Order> // androidx.room/FtsOptions.Order.values|values#static(){}[0]
     }
diff --git a/room/room-common/build.gradle b/room/room-common/build.gradle
index bc1ac61..2e36b7e 100644
--- a/room/room-common/build.gradle
+++ b/room/room-common/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import androidx.build.LibraryType
 import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
@@ -87,4 +89,5 @@
     description = "Android Room-Common"
     legacyDisableKotlinStrictApiMode = true
     metalavaK2UastEnabled = false
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
diff --git a/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteColumn.jvm.kt b/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteColumn.jvm.kt
index 83774be..7d76cd47 100644
--- a/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteColumn.jvm.kt
+++ b/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteColumn.jvm.kt
@@ -25,6 +25,10 @@
 @JvmRepeatable(DeleteColumn.Entries::class)
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.BINARY)
+@Suppress(
+    // Due to @JvmRepeatable in this actual while expect has @Repeatable
+    "ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT"
+)
 actual annotation class DeleteColumn
 actual constructor(actual val tableName: String, actual val columnName: String) {
     /** Container annotation for the repeatable annotation [DeleteColumn]. */
diff --git a/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteTable.jvm.kt b/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteTable.jvm.kt
index edea11b..10f463a 100644
--- a/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteTable.jvm.kt
+++ b/room/room-common/src/jvmMain/kotlin/androidx/room/DeleteTable.jvm.kt
@@ -25,6 +25,10 @@
 @JvmRepeatable(DeleteTable.Entries::class)
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.BINARY)
+@Suppress(
+    // Due to @JvmRepeatable in this actual while expect has @Repeatable
+    "ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT"
+)
 public actual annotation class DeleteTable(
     /**
      * Name of the table in the [AutoMigration.from] version of the database to be deleted.
diff --git a/room/room-common/src/jvmMain/kotlin/androidx/room/RenameColumn.jvm.kt b/room/room-common/src/jvmMain/kotlin/androidx/room/RenameColumn.jvm.kt
index 621fcb3..3f50825 100644
--- a/room/room-common/src/jvmMain/kotlin/androidx/room/RenameColumn.jvm.kt
+++ b/room/room-common/src/jvmMain/kotlin/androidx/room/RenameColumn.jvm.kt
@@ -25,6 +25,10 @@
 @JvmRepeatable(RenameColumn.Entries::class)
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.BINARY)
+@Suppress(
+    // Due to @JvmRepeatable in this actual while expect has @Repeatable
+    "ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT"
+)
 public actual annotation class RenameColumn(
     /**
      * Name of the table in the [AutoMigration.from] version of the database the renamed column is
diff --git a/room/room-common/src/jvmMain/kotlin/androidx/room/RenameTable.jvm.kt b/room/room-common/src/jvmMain/kotlin/androidx/room/RenameTable.jvm.kt
index 7c9dfa6..8a5cb21 100644
--- a/room/room-common/src/jvmMain/kotlin/androidx/room/RenameTable.jvm.kt
+++ b/room/room-common/src/jvmMain/kotlin/androidx/room/RenameTable.jvm.kt
@@ -24,6 +24,10 @@
 @JvmRepeatable(RenameTable.Entries::class)
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.BINARY)
+@Suppress(
+    // Due to @JvmRepeatable in this actual while expect has @Repeatable
+    "ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT"
+)
 public actual annotation class RenameTable(
     /**
      * Name of the table in the [AutoMigration.from] version of the database.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/InternalXAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/InternalXAnnotation.kt
index 0b33cf5..dbafb33 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/InternalXAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/InternalXAnnotation.kt
@@ -25,6 +25,10 @@
         annotationValues.associateBy { it.name }
     }
 
+    override operator fun get(methodName: String): XAnnotationValue? {
+        return valuesByName[methodName]
+    }
+
     override fun getAnnotationValue(methodName: String): XAnnotationValue {
         return valuesByName[methodName]
             ?: error("No property named $methodName was found in annotation $name")
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
index 03d88b1..7ffccf0 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
@@ -15,6 +15,7 @@
  */
 package androidx.room.compiler.processing
 
+import androidx.room.compiler.processing.util.sanitizeAsJavaMethodName
 import com.squareup.javapoet.AnnotationSpec
 import com.squareup.javapoet.MethodSpec
 import com.squareup.javapoet.ParameterSpec
@@ -172,7 +173,14 @@
         resolvedType: XMethodType = executableElement.executableType,
         vararg paramModifiers: Modifier
     ): MethodSpec.Builder {
-        return MethodSpec.methodBuilder(executableElement.jvmName).apply {
+        val methodJvmName =
+            if (executableElement.hasValidJvmSourceName()) {
+                executableElement.jvmName
+            } else {
+                // Workaround for b/384600605
+                executableElement.jvmName.sanitizeAsJavaMethodName()
+            }
+        return MethodSpec.methodBuilder(methodJvmName).apply {
             addTypeVariables(
                 resolvedType.typeVariables.map { it.asTypeName().java as JTypeVariableName }
             )
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotation.kt
index d14f9a1..35376ce3 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotation.kt
@@ -154,6 +154,12 @@
         getAnnotationValue(methodName).asAnnotationValueList()
 
     /** Returns the value of the given [methodName] as a [XAnnotationValue]. */
+    operator fun get(methodName: String): XAnnotationValue?
+
+    /**
+     * Returns the value of the given [methodName] as a [XAnnotationValue], throwing an exception if
+     * the method is not found.
+     */
     fun getAnnotationValue(methodName: String): XAnnotationValue
 }
 
@@ -161,22 +167,6 @@
  * Returns the value of the given [methodName], throwing an exception if the method is not found or
  * if the given type [T] does not match the actual type.
  *
- * Note that non primitive types are wrapped by interfaces in order to allow them to be represented
- * by the process:
- * - "Class" types are represented with [XType]
- * - Annotations are represented with [XAnnotation]
- * - Enums are represented with [XEnumEntry]
- *
- * For convenience, wrapper functions are provided for these types, eg [XAnnotation.getAsType]
- */
-// TODO: Consider deprecating this method for getAs*() methods
-@Suppress("DEPRECATION")
-inline fun <reified T> XAnnotation.get(methodName: String): T = get(methodName, T::class.java)
-
-/**
- * Returns the value of the given [methodName], throwing an exception if the method is not found or
- * if the given type [T] does not match the actual type.
- *
  * This uses a non-reified type and takes in a Class so it is callable by Java users.
  *
  * Note that non primitive types are wrapped by interfaces in order to allow them to be represented
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingEnvConfig.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingEnvConfig.kt
index 0671dc4..9be897c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingEnvConfig.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XProcessingEnvConfig.kt
@@ -28,8 +28,7 @@
  * `XProcessingEnvironmentTestConfigProvider` via a service configuration to load your default
  * configuration in `runProcessorTest` calls.
  */
-@Suppress("SyntheticAccessor", "DataClassPrivateConstructor")
-data class XProcessingEnvConfig
+class XProcessingEnvConfig
 private constructor(
     /**
      * When set to `true`, XProcessingEnv will hide all methods that have invalid source names in
@@ -54,6 +53,45 @@
      */
     val disableAnnotatedElementValidation: Boolean = false,
 ) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is XProcessingEnvConfig) return false
+
+        if (
+            excludeMethodsWithInvalidJvmSourceNames != other.excludeMethodsWithInvalidJvmSourceNames
+        ) {
+            return false
+        }
+        if (disableAnnotatedElementValidation != other.disableAnnotatedElementValidation) {
+            return false
+        }
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = excludeMethodsWithInvalidJvmSourceNames.hashCode()
+        result = 31 * result + disableAnnotatedElementValidation.hashCode()
+        return result
+    }
+
+    override fun toString(): String {
+        return "XProcessingEnvConfig(" +
+            "excludeMethodsWithInvalidJvmSourceNames=$excludeMethodsWithInvalidJvmSourceNames, " +
+            "disableAnnotatedElementValidation=$disableAnnotatedElementValidation" +
+            ")"
+    }
+
+    fun copy(
+        excludeMethodsWithInvalidJvmSourceNames: Boolean =
+            this.excludeMethodsWithInvalidJvmSourceNames,
+        disableAnnotatedElementValidation: Boolean = this.disableAnnotatedElementValidation
+    ) =
+        XProcessingEnvConfig(
+            excludeMethodsWithInvalidJvmSourceNames = excludeMethodsWithInvalidJvmSourceNames,
+            disableAnnotatedElementValidation = disableAnnotatedElementValidation
+        )
+
     fun toBuilder() = Builder(this)
 
     class Builder(baseline: XProcessingEnvConfig = XProcessingEnvConfig()) {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt
index 3987cd9..880ada6 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt
@@ -29,5 +29,7 @@
         "p$argIndex"
     }
 
+internal fun String.sanitizeAsJavaMethodName(): String = this.substringBefore('$')
+
 /** Returns true if the given name can be used in generated java sources. */
 internal fun String.isValidJavaSourceName() = SourceVersion.isName(this)
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
index e495cf9..9200fa6 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XAnnotationTest.kt
@@ -207,7 +207,7 @@
             assertThat(annotation1.qualifiedName).isEqualTo("MyAnnotation1")
             assertThat(annotation1.type.typeElement)
                 .isEqualTo(invocation.processingEnv.requireTypeElement("MyAnnotation1"))
-            assertThat(annotation1.get<Int>("bar")).isEqualTo(1)
+            assertThat(annotation1.getAsInt("bar")).isEqualTo(1)
             assertThat(annotation1.annotationValues).hasSize(1)
             assertThat(annotation1.annotationValues.first().name).isEqualTo("bar")
             assertThat(annotation1.annotationValues.first().value).isEqualTo(1)
@@ -401,24 +401,24 @@
             val element = invocation.processingEnv.requireTypeElement("foo.bar.Baz")
             val annotation = element.requireAnnotation<MainAnnotation>()
 
-            assertThat(annotation.get<List<XType>>("typeList"))
+            assertThat(annotation.getAsTypeList("typeList"))
                 .containsExactly(
                     invocation.processingEnv.requireType(java.lang.String::class),
                     invocation.processingEnv.requireType(Integer::class)
                 )
-            assertThat(annotation.get<XType>("singleType"))
+            assertThat(annotation.getAsType("singleType"))
                 .isEqualTo(invocation.processingEnv.requireType(java.lang.Long::class))
 
-            assertThat(annotation.get<Int>("intMethod")).isEqualTo(3)
-            annotation.get<XAnnotation>("singleOtherAnnotation").let { other ->
+            assertThat(annotation.getAsInt("intMethod")).isEqualTo(3)
+            annotation.getAsAnnotation("singleOtherAnnotation").let { other ->
                 assertThat(other.name).isEqualTo(OtherAnnotation::class.simpleName)
                 assertThat(other.qualifiedName).isEqualTo(OtherAnnotation::class.qualifiedName)
-                assertThat(other.get<String>("value")).isEqualTo("other single")
+                assertThat(other.getAsString("value")).isEqualTo("other single")
             }
-            annotation.get<List<XAnnotation>>("otherAnnotationArray").let { boxArray ->
+            annotation.getAsAnnotationList("otherAnnotationArray").let { boxArray ->
                 assertThat(boxArray).hasSize(2)
-                assertThat(boxArray[0].get<String>("value")).isEqualTo("other list 1")
-                assertThat(boxArray[1].get<String>("value")).isEqualTo("other list 2")
+                assertThat(boxArray[0].getAsString("value")).isEqualTo("other list 1")
+                assertThat(boxArray[1].getAsString("value")).isEqualTo("other list 2")
             }
         }
     }
@@ -441,7 +441,7 @@
             val annotation = element.requireAnnotation<TestSuppressWarnings>()
 
             assertThat(annotation).isNotNull()
-            assertThat(annotation.get<List<String>>("value"))
+            assertThat(annotation.getAsStringList("value"))
                 .isEqualTo(listOf("warning1", "warning 2"))
         }
     }
@@ -478,21 +478,21 @@
             val element = invocation.processingEnv.requireTypeElement("Subject")
             val annotation = element.requireAnnotation<MainAnnotation>()
 
-            assertThat(annotation.get<List<XType>>("typeList").map { it.asTypeName() })
+            assertThat(annotation.getAsTypeList("typeList").map { it.asTypeName() })
                 .containsExactly(String::class.asClassName(), XTypeName.PRIMITIVE_INT)
-            assertThat(annotation.get<XType>("singleType"))
+            assertThat(annotation.getAsType("singleType"))
                 .isEqualTo(invocation.processingEnv.requireType(Long::class))
 
-            assertThat(annotation.get<Int>("intMethod")).isEqualTo(3)
-            annotation.get<XAnnotation>("singleOtherAnnotation").let { other ->
+            assertThat(annotation.getAsInt("intMethod")).isEqualTo(3)
+            annotation.getAsAnnotation("singleOtherAnnotation").let { other ->
                 assertThat(other.name).isEqualTo(OtherAnnotation::class.simpleName)
                 assertThat(other.qualifiedName).isEqualTo(OtherAnnotation::class.qualifiedName)
-                assertThat(other.get<String>("value")).isEqualTo("other single")
+                assertThat(other.getAsString("value")).isEqualTo("other single")
             }
-            annotation.get<List<XAnnotation>>("otherAnnotationArray").let { boxArray ->
+            annotation.getAsAnnotationList("otherAnnotationArray").let { boxArray ->
                 assertThat(boxArray).hasSize(2)
-                assertThat(boxArray[0].get<String>("value")).isEqualTo("other list 1")
-                assertThat(boxArray[1].get<String>("value")).isEqualTo("other list 2")
+                assertThat(boxArray[0].getAsString("value")).isEqualTo("other list 1")
+                assertThat(boxArray[1].getAsString("value")).isEqualTo("other list 2")
             }
         }
     }
@@ -514,7 +514,7 @@
             if (!invocation.isKsp) return@runTest
             val subject = invocation.processingEnv.requireTypeElement("Subject")
             val annotation = subject.requireAnnotation<JavaAnnotationWithTypeReferences>()
-            val annotationValue = annotation.get<List<XType>>("value").single()
+            val annotationValue = annotation.getAsTypeList("value").single()
             assertThat(annotationValue.asTypeName().java).isEqualTo(String::class.asJTypeName())
         }
     }
@@ -704,11 +704,11 @@
                         )
                         .inOrder()
 
-                    assertThat(annotation.get<Int>("intVal")).isEqualTo(3)
-                    assertThat(annotation.get<List<Int>>("intArrayVal")).isEqualTo(listOf(1, 3, 5))
-                    assertThat(annotation.get<List<String>>("stringArrayVal"))
+                    assertThat(annotation.getAsInt("intVal")).isEqualTo(3)
+                    assertThat(annotation.getAsIntList("intArrayVal")).isEqualTo(listOf(1, 3, 5))
+                    assertThat(annotation.getAsStringList("stringArrayVal"))
                         .isEqualTo(listOf("x", "y"))
-                    assertThat(annotation.get<String>("stringVal")).isEqualTo("foo")
+                    assertThat(annotation.getAsString("stringVal")).isEqualTo("foo")
                     assertThat(annotation.getAsType("typeVal").rawType.asTypeName().java)
                         .isEqualTo(HashMap::class.asJTypeName())
                     assertThat(
@@ -749,12 +749,12 @@
 
                         annotation.getAsAnnotation("otherAnnotationVal").let { other ->
                             assertThat(other.name).isEqualTo("OtherAnnotation")
-                            assertThat(other.get<String>("value")).isEqualTo("def")
+                            assertThat(other.getAsString("value")).isEqualTo("def")
                         }
 
                         annotation.getAsAnnotationList("otherAnnotationArrayVal").forEach { other ->
                             assertThat(other.name).isEqualTo("OtherAnnotation")
-                            assertThat(other.get<String>("value")).isEqualTo("v1")
+                            assertThat(other.getAsString("value")).isEqualTo("v1")
                         }
                     }
                 }
@@ -796,7 +796,7 @@
                         subject
                             .getField("annotated1")
                             .requireAnnotation<JavaAnnotationWithPrimitiveArray>()
-                    assertThat(annotation.get<List<Int>>("intArray")).isEqualTo(listOf(1, 2, 3))
+                    assertThat(annotation.getAsIntList("intArray")).isEqualTo(listOf(1, 2, 3))
                 }
         }
     }
@@ -955,7 +955,7 @@
                             it.name == "RepeatableJavaAnnotation" ||
                                 it.name == "RepeatableKotlinAnnotation"
                         }
-                    val values = annotations.map { it.get<String>("value") }
+                    val values = annotations.map { it.getAsString("value") }
                     assertWithMessage(subject.qualifiedName)
                         .that(values)
                         .containsExactly("x", "y", "z")
@@ -991,7 +991,7 @@
                 .forEach { subject ->
                     val annotations =
                         subject.getAllAnnotations().filter { it.name == "RepeatableJavaAnnotation" }
-                    val values = annotations.map { it.get<String>("value") }
+                    val values = annotations.map { it.getAsString("value") }
                     assertWithMessage(subject.qualifiedName).that(values).containsExactly("x")
                 }
         }
@@ -1014,7 +1014,7 @@
                 subject ->
                 val annotations =
                     subject.getAllAnnotations().filter { it.name == "RepeatableKotlinAnnotation" }
-                val values = annotations.map { it.get<String>("value") }
+                val values = annotations.map { it.getAsString("value") }
                 assertWithMessage(subject.qualifiedName).that(values).containsExactly("x")
             }
         }
@@ -1066,8 +1066,8 @@
             val annotation =
                 element.requireAnnotation(JClassName.get(JavaAnnotationWithDefaults::class.java))
 
-            assertThat(annotation.get<String>("stringVal")).isEqualTo("test")
-            assertThat(annotation.get<Int>("intVal")).isEqualTo(3)
+            assertThat(annotation.getAsString("stringVal")).isEqualTo("test")
+            assertThat(annotation.getAsInt("intVal")).isEqualTo(3)
 
             // Also test reading theses values through getAs*() methods
             assertThat(annotation.getAsString("stringVal")).isEqualTo("test")
@@ -1553,9 +1553,7 @@
             assertThat(subject.typeParameters.first().getAllAnnotations().first().name)
                 .isEqualTo("A")
 
-            assertThat(
-                    subject.typeParameters.first().getAllAnnotations().first().get("value") as Int
-                )
+            assertThat(subject.typeParameters.first().getAllAnnotations().first().getAsInt("value"))
                 .isEqualTo(42)
         }
 
@@ -1596,7 +1594,7 @@
 
     // helper function to read what we need
     private fun XAnnotated.getSuppressValues(): List<String>? {
-        return this.findAnnotation<TestSuppressWarnings>()?.get<List<String>>("value")
+        return this.findAnnotation<TestSuppressWarnings>()?.getAsStringList("value")
     }
 
     private inline fun <reified T : Annotation> XAnnotated.requireAnnotation(): XAnnotation {
@@ -1620,7 +1618,7 @@
     }
 
     private fun XAnnotated.getOtherAnnotationValue(): String? {
-        return this.findAnnotation<OtherAnnotation>()?.get<String>("value")
+        return this.findAnnotation<OtherAnnotation>()?.getAsString("value")
     }
 
     companion object {
diff --git a/room/room-compiler/build.gradle b/room/room-compiler/build.gradle
index 4c41d18..6865f7b 100644
--- a/room/room-compiler/build.gradle
+++ b/room/room-compiler/build.gradle
@@ -241,5 +241,5 @@
     type = LibraryType.ANNOTATION_PROCESSOR
     inceptionYear = "2017"
     description = "Android Room annotation processor"
-    kotlinTarget = KotlinTarget.KOTLIN_1_9
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
index 31bb21d..b2a9f1a 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
@@ -385,7 +385,13 @@
                 findColumnTypeAdapter(
                     // Find an adapter for the non-null underlying type, nullability will be handled
                     // by the value class adapter.
-                    out = underlyingInfo.parameter.asMemberOf(type).makeNonNullable(),
+                    out =
+                        try {
+                            // Workaround for KSP2
+                            underlyingInfo.parameter.asMemberOf(type).makeNonNullable()
+                        } catch (ex: Throwable) {
+                            underlyingInfo.parameter.type.makeNonNullable()
+                        },
                     affinity = affinity,
                     skipDefaultConverter = false
                 ) ?: return null
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt
index 63dbe76..92d8536 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/MultimapQueryResultAdapter.kt
@@ -177,9 +177,7 @@
             val annotation = type.getAnnotation(MapColumn::class.asClassName()) ?: return null
 
             val mapColumnName = annotation.getAsString("columnName")
-            // TODO: Temporary workaround below due to XAnnotation bug
-            val mapColumnTableName =
-                (annotation.getAnnotationValue("tableName").value ?: "") as String
+            val mapColumnTableName = (annotation["tableName"]?.value ?: "") as String
 
             fun List<ColumnInfo>.contains(columnName: String, tableName: String?) =
                 any { resultColumn ->
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/BaseDaoKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/BaseDaoKotlinCodeGenTest.kt
index aa49a17..279b6df 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/BaseDaoKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/BaseDaoKotlinCodeGenTest.kt
@@ -19,6 +19,7 @@
 import androidx.room.DatabaseProcessingStep
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
+import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.processor.Context
 import androidx.room.runKspTestWithK1
 import java.io.File
@@ -35,14 +36,12 @@
         expectedFilePath: String,
         compiledFiles: List<File> = emptyList(),
         jvmDefaultMode: String = "disable",
+        withKsp2: Boolean = true,
         handler: (XTestInvocation) -> Unit = {}
     ) {
-        runKspTestWithK1(
-            sources = sources,
-            classpath = compiledFiles,
-            options = mapOf(Context.BooleanProcessorOptions.GENERATE_KOTLIN.argName to "true"),
-            kotlincArguments = listOf("-jvm-target=11", "-Xjvm-default=${jvmDefaultMode}")
-        ) {
+        val options = mapOf(Context.BooleanProcessorOptions.GENERATE_KOTLIN.argName to "true")
+        val kotlincArguments = listOf("-jvm-target=11", "-Xjvm-default=${jvmDefaultMode}")
+        val invocationHandler: (XTestInvocation) -> Unit = {
             val databaseFqn = "androidx.room.Database"
             DatabaseProcessingStep()
                 .process(
@@ -67,5 +66,22 @@
             }
             handler.invoke(it)
         }
+        if (withKsp2) {
+            runKspTest(
+                sources = sources,
+                classpath = compiledFiles,
+                options = options,
+                kotlincArguments = kotlincArguments,
+                handler = invocationHandler
+            )
+        } else {
+            runKspTestWithK1(
+                sources = sources,
+                classpath = compiledFiles,
+                options = options,
+                kotlincArguments = kotlincArguments,
+                handler = invocationHandler
+            )
+        }
     }
 }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
index 47a2205..ec8ee0d 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
@@ -716,6 +716,7 @@
 
             @Entity
             @TypeConverters(FooConverter::class)
+            @ConsistentCopyVisibility
             internal data class MyEntity internal constructor(
                 @PrimaryKey
                 internal val pk: Int,
@@ -1955,7 +1956,8 @@
         runTest(
             sources =
                 listOf(src, databaseSrc, COMMON.DATA_SOURCE_FACTORY, COMMON.POSITIONAL_DATA_SOURCE),
-            expectedFilePath = getTestGoldenPath(testName.methodName)
+            expectedFilePath = getTestGoldenPath(testName.methodName),
+            withKsp2 = false
         )
     }
 
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoRelationshipKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoRelationshipKotlinCodeGenTest.kt
index 26ec990..fbc0bc9 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoRelationshipKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoRelationshipKotlinCodeGenTest.kt
@@ -553,7 +553,8 @@
         runTest(
             sources =
                 listOf(src, databaseSrc, COMMON.DATA_SOURCE_FACTORY, COMMON.POSITIONAL_DATA_SOURCE),
-            expectedFilePath = getTestGoldenPath(testName.methodName)
+            expectedFilePath = getTestGoldenPath(testName.methodName),
+            withKsp2 = false
         )
     }
 }
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DatabaseKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DatabaseKotlinCodeGenTest.kt
index 51af49e..60014dd 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DatabaseKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DatabaseKotlinCodeGenTest.kt
@@ -19,8 +19,8 @@
 import androidx.room.DatabaseProcessingStep
 import androidx.room.compiler.processing.util.Source
 import androidx.room.compiler.processing.util.XTestInvocation
+import androidx.room.compiler.processing.util.runKspTest
 import androidx.room.processor.Context
-import androidx.room.runKspTestWithK1
 import loadTestSource
 import org.junit.Rule
 import org.junit.Test
@@ -146,6 +146,7 @@
             }
 
             @Entity
+            @ConsistentCopyVisibility
             internal data class MyEntity internal constructor(
                 @PrimaryKey
                 var pk: Int
@@ -245,7 +246,7 @@
         expectedFilePath: String,
         handler: (XTestInvocation) -> Unit = {}
     ) {
-        runKspTestWithK1(
+        runKspTest(
             sources = sources,
             options = mapOf(Context.BooleanProcessorOptions.GENERATE_KOTLIN.argName to "true"),
             kotlincArguments = listOf("-jvm-target=11")
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_daoProperty.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_daoProperty.kt
index b2b2e71..72687d1 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_daoProperty.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_daoProperty.kt
@@ -29,7 +29,6 @@
     MyDao_Impl(this)
   }
 
-
   public override val dao: MyDao
     get() = _myDao.value
 
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
index 1af517e..c33c9e4 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_internalVisibility.kt
@@ -29,7 +29,6 @@
     MyDao_Impl(this)
   }
 
-
   protected override fun createOpenDelegate(): RoomOpenDelegate {
     val _openDelegate: RoomOpenDelegate = object : RoomOpenDelegate(1,
         "195d7974660177325bd1a32d2c7b8b8c", "7458a901120796c5bbc554e2fefd262f") {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_javaSource.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_javaSource.kt
index e6d2c79..fc0c670 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_javaSource.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_javaSource.kt
@@ -29,7 +29,6 @@
     MyDao_Impl(this)
   }
 
-
   protected override fun createOpenDelegate(): RoomOpenDelegate {
     val _openDelegate: RoomOpenDelegate = object : RoomOpenDelegate(1,
         "195d7974660177325bd1a32d2c7b8b8c", "7458a901120796c5bbc554e2fefd262f") {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
index cc897ff..1c82c9a 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_simple.kt
@@ -29,7 +29,6 @@
     MyDao_Impl(this)
   }
 
-
   protected override fun createOpenDelegate(): RoomOpenDelegate {
     val _openDelegate: RoomOpenDelegate = object : RoomOpenDelegate(1,
         "195d7974660177325bd1a32d2c7b8b8c", "7458a901120796c5bbc554e2fefd262f") {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
index e2f4e84..7ed20a3 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/database_withFtsAndView.kt
@@ -33,7 +33,6 @@
     MyDao_Impl(this)
   }
 
-
   protected override fun createOpenDelegate(): RoomOpenDelegate {
     val _openDelegate: RoomOpenDelegate = object : RoomOpenDelegate(1,
         "89ba16fb8b062b50acf0eb06c853efcb", "8a71a68e07bdd62aa8c8324d870cf804") {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable_java.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable_java.kt
index 2a7655d..cdcb94b 100644
--- a/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable_java.kt
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/guavaCallable_java.kt
@@ -23,7 +23,7 @@
     this.__db = __db
   }
 
-  public override fun getListenableFuture(arg: Array<String?>?): ListenableFuture<MyEntity?>? {
+  public override fun getListenableFuture(arg: Array<out String?>?): ListenableFuture<MyEntity?>? {
     val _stringBuilder: StringBuilder = StringBuilder()
     _stringBuilder.append("SELECT * FROM MyEntity WHERE pk IN (")
     val _inputSize: Int = if (arg == null) 1 else arg.size
diff --git a/room/room-ktx/build.gradle b/room/room-ktx/build.gradle
index 32d0dd6..4a03955a 100644
--- a/room/room-ktx/build.gradle
+++ b/room/room-ktx/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import androidx.build.LibraryType
 
 plugins {
@@ -51,6 +53,7 @@
     type = LibraryType.PUBLISHED_LIBRARY_ONLY_USED_BY_KOTLIN_CONSUMERS
     inceptionYear = "2019"
     description = "Android Room Kotlin Extensions"
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
diff --git a/room/room-migration/build.gradle b/room/room-migration/build.gradle
index 50bf269..3145c0f 100644
--- a/room/room-migration/build.gradle
+++ b/room/room-migration/build.gradle
@@ -89,5 +89,5 @@
     inceptionYear = "2017"
     description = "Android Room Migration"
     legacyDisableKotlinStrictApiMode = true
-    kotlinTarget = KotlinTarget.KOTLIN_1_9
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
diff --git a/room/room-paging-guava/build.gradle b/room/room-paging-guava/build.gradle
index 73a8396..39cc34c 100644
--- a/room/room-paging-guava/build.gradle
+++ b/room/room-paging-guava/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 import androidx.build.LibraryType
 
@@ -55,8 +57,13 @@
     inceptionYear = "2022"
     description = "Guava integration in Room Paging"
     legacyDisableKotlinStrictApiMode = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
     namespace = "androidx.room.paging.guava"
 }
+
+ksp {
+    useKsp2 = true
+}
diff --git a/room/room-paging-rxjava2/build.gradle b/room/room-paging-rxjava2/build.gradle
index 2f4acc2..2f4d618 100644
--- a/room/room-paging-rxjava2/build.gradle
+++ b/room/room-paging-rxjava2/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 import androidx.build.LibraryType
 
@@ -54,8 +56,13 @@
     inceptionYear = "2022"
     description = "RxJava2 integration in Room Paging"
     legacyDisableKotlinStrictApiMode = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
     namespace = "androidx.room.paging.rxjava2"
 }
+
+ksp {
+    useKsp2 = true
+}
diff --git a/room/room-paging-rxjava3/build.gradle b/room/room-paging-rxjava3/build.gradle
index 350eea0..2009f45 100644
--- a/room/room-paging-rxjava3/build.gradle
+++ b/room/room-paging-rxjava3/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 import androidx.build.LibraryType
 
@@ -54,8 +56,13 @@
     inceptionYear = "2022"
     description = "RxJava3 integration in Room Paging"
     legacyDisableKotlinStrictApiMode = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
     namespace = "androidx.room.paging.rxjava3"
 }
+
+ksp {
+    useKsp2 = true
+}
diff --git a/room/room-paging/build.gradle b/room/room-paging/build.gradle
index 535f909..e0ab2c1 100644
--- a/room/room-paging/build.gradle
+++ b/room/room-paging/build.gradle
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+
+import androidx.build.KotlinTarget
 import androidx.build.PlatformIdentifier
 import androidx.build.LibraryType
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
@@ -102,4 +104,9 @@
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Room Paging integration"
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
+}
+
+ksp {
+    useKsp2 = true
 }
diff --git a/room/room-paging/src/androidMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.android.kt b/room/room-paging/src/androidMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.android.kt
index 13120a0..2ad4ea1 100644
--- a/room/room-paging/src/androidMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.android.kt
+++ b/room/room-paging/src/androidMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.android.kt
@@ -67,10 +67,11 @@
     override val jumpingSupported: Boolean
         get() = true
 
-    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value> =
+    actual override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value> =
         implementation.load(params)
 
-    override fun getRefreshKey(state: PagingState<Int, Value>): Int? = state.getClippedRefreshKey()
+    actual override fun getRefreshKey(state: PagingState<Int, Value>): Int? =
+        state.getClippedRefreshKey()
 
     protected open fun convertRows(cursor: Cursor): List<Value> {
         throw NotImplementedError(
diff --git a/room/room-paging/src/commonMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.kt b/room/room-paging/src/commonMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.kt
index 32296b1..edd5950 100644
--- a/room/room-paging/src/commonMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.kt
+++ b/room/room-paging/src/commonMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.kt
@@ -20,6 +20,7 @@
 import androidx.paging.PagingSource
 import androidx.paging.PagingSource.LoadParams
 import androidx.paging.PagingSource.LoadResult
+import androidx.paging.PagingState
 import androidx.room.RoomDatabase
 import androidx.room.RoomRawQuery
 import androidx.room.Transactor.SQLiteTransactionType
@@ -51,6 +52,10 @@
 
     public val itemCount: Int
 
+    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value>
+
+    override fun getRefreshKey(state: PagingState<Int, Value>): Int?
+
     protected open suspend fun convertRows(
         limitOffsetQuery: RoomRawQuery,
         itemCount: Int
diff --git a/room/room-paging/src/jvmNativeMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.jvmNative.kt b/room/room-paging/src/jvmNativeMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.jvmNative.kt
index 91d075a..1f4235e 100644
--- a/room/room-paging/src/jvmNativeMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.jvmNative.kt
+++ b/room/room-paging/src/jvmNativeMain/kotlin/androidx/room/paging/LimitOffsetPagingSource.jvmNative.kt
@@ -46,10 +46,11 @@
     override val jumpingSupported: Boolean
         get() = true
 
-    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value> =
+    actual override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value> =
         implementation.load(params)
 
-    override fun getRefreshKey(state: PagingState<Int, Value>): Int? = state.getClippedRefreshKey()
+    actual override fun getRefreshKey(state: PagingState<Int, Value>): Int? =
+        state.getClippedRefreshKey()
 
     protected actual open suspend fun convertRows(
         limitOffsetQuery: RoomRawQuery,
diff --git a/room/room-runtime/bcv/native/current.txt b/room/room-runtime/bcv/native/current.txt
index 0e4afff..984bd87 100644
--- a/room/room-runtime/bcv/native/current.txt
+++ b/room/room-runtime/bcv/native/current.txt
@@ -34,6 +34,9 @@
         enum entry EXCLUSIVE // androidx.room/Transactor.SQLiteTransactionType.EXCLUSIVE|null[0]
         enum entry IMMEDIATE // androidx.room/Transactor.SQLiteTransactionType.IMMEDIATE|null[0]
 
+        final val entries // androidx.room/Transactor.SQLiteTransactionType.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/Transactor.SQLiteTransactionType> // androidx.room/Transactor.SQLiteTransactionType.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/Transactor.SQLiteTransactionType // androidx.room/Transactor.SQLiteTransactionType.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/Transactor.SQLiteTransactionType> // androidx.room/Transactor.SQLiteTransactionType.values|values#static(){}[0]
     }
@@ -126,6 +129,9 @@
         enum entry TRUNCATE // androidx.room/RoomDatabase.JournalMode.TRUNCATE|null[0]
         enum entry WRITE_AHEAD_LOGGING // androidx.room/RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING|null[0]
 
+        final val entries // androidx.room/RoomDatabase.JournalMode.entries|#static{}entries[0]
+            final fun <get-entries>(): kotlin.enums/EnumEntries<androidx.room/RoomDatabase.JournalMode> // androidx.room/RoomDatabase.JournalMode.entries.<get-entries>|<get-entries>#static(){}[0]
+
         final fun valueOf(kotlin/String): androidx.room/RoomDatabase.JournalMode // androidx.room/RoomDatabase.JournalMode.valueOf|valueOf#static(kotlin.String){}[0]
         final fun values(): kotlin/Array<androidx.room/RoomDatabase.JournalMode> // androidx.room/RoomDatabase.JournalMode.values|values#static(){}[0]
     }
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 54f327a..dc736fd 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -23,6 +23,7 @@
  */
 
 
+import androidx.build.KotlinTarget
 import androidx.build.LibraryType
 import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
@@ -227,4 +228,9 @@
     metalavaK2UastEnabled = false
     // TODO: b/326456246
     optOutJSpecify = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
+}
+
+ksp {
+    useKsp2 = true
 }
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomConnectionManager.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomConnectionManager.kt
index 74799c8..0e0be20 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomConnectionManager.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/RoomConnectionManager.kt
@@ -28,7 +28,7 @@
 import androidx.sqlite.use
 
 /** Expect implementation declaration of Room's connection manager. */
-internal expect class RoomConnectionManager : BaseRoomConnectionManager
+internal expect class RoomConnectionManager
 
 /**
  * Base class for Room's database connection manager, responsible for opening and managing such
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/FtsTableInfo.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/FtsTableInfo.kt
index 0c6898d..f6fffde 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/FtsTableInfo.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/FtsTableInfo.kt
@@ -18,23 +18,22 @@
 
 import androidx.annotation.RestrictTo
 import androidx.sqlite.SQLiteConnection
-import kotlin.jvm.JvmField
 import kotlin.jvm.JvmStatic
 
 /** A data class that holds the information about an FTS table. */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
 expect class FtsTableInfo {
     /** The table name */
-    @JvmField val name: String
+    val name: String
 
     /** The column names */
-    @JvmField val columns: Set<String>
+    val columns: Set<String>
 
     /**
      * The set of options. Each value in the set contains the option in the following format: <key,
      * value>.
      */
-    @JvmField val options: Set<String>
+    val options: Set<String>
 
     constructor(name: String, columns: Set<String>, createSql: String)
 
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/MigrationUtil.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/MigrationUtil.kt
index 4596432..ab0a368 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/MigrationUtil.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/MigrationUtil.kt
@@ -40,12 +40,12 @@
     return if (isDowngrade && this.allowDestructiveMigrationOnDowngrade) {
         false
     } else {
+        val migrationNotRequiredFrom = this.migrationNotRequiredFrom
         // Migrations are required between the two versions if we generally require migrations
         // AND EITHER there are no exceptions OR the supplied fromVersion is not one of the
         // exceptions.
         this.requireMigration &&
-            (this.migrationNotRequiredFrom == null ||
-                !this.migrationNotRequiredFrom.contains(fromVersion))
+            (migrationNotRequiredFrom == null || !migrationNotRequiredFrom.contains(fromVersion))
     }
 }
 
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/TableInfo.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/TableInfo.kt
index feb7d93..2ac97ab 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/TableInfo.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/TableInfo.kt
@@ -18,7 +18,6 @@
 import androidx.annotation.RestrictTo
 import androidx.room.ColumnInfo.SQLiteTypeAffinity
 import androidx.sqlite.SQLiteConnection
-import kotlin.jvm.JvmField
 import kotlin.jvm.JvmStatic
 
 /**
@@ -38,10 +37,10 @@
     indices: Set<Index>? = null
 ) {
     /** The table name. */
-    @JvmField val name: String
-    @JvmField val columns: Map<String, Column>
-    @JvmField val foreignKeys: Set<ForeignKey>
-    @JvmField val indices: Set<Index>?
+    val name: String
+    val columns: Map<String, Column>
+    val foreignKeys: Set<ForeignKey>
+    val indices: Set<Index>?
 
     override fun equals(other: Any?): Boolean
 
@@ -86,14 +85,14 @@
         createdFrom: Int
     ) {
         /** The column name. */
-        @JvmField val name: String
+        val name: String
         /** The column type affinity. */
-        @JvmField val type: String
+        val type: String
         /** Whether or not the column can be NULL. */
-        @JvmField val notNull: Boolean
-        @JvmField val primaryKeyPosition: Int
-        @JvmField val defaultValue: String?
-        @JvmField val createdFrom: Int
+        val notNull: Boolean
+        val primaryKeyPosition: Int
+        val defaultValue: String?
+        val createdFrom: Int
 
         /**
          * The column type after it is normalized to one of the basic types according to
@@ -101,7 +100,7 @@
          *
          * This is the value Room uses for equality check.
          */
-        @SQLiteTypeAffinity @JvmField val affinity: Int
+        @SQLiteTypeAffinity val affinity: Int
 
         /**
          * Returns whether this column is part of the primary key or not.
@@ -126,11 +125,11 @@
         columnNames: List<String>,
         referenceColumnNames: List<String>
     ) {
-        @JvmField val referenceTable: String
-        @JvmField val onDelete: String
-        @JvmField val onUpdate: String
-        @JvmField val columnNames: List<String>
-        @JvmField val referenceColumnNames: List<String>
+        val referenceTable: String
+        val onDelete: String
+        val onUpdate: String
+        val columnNames: List<String>
+        val referenceColumnNames: List<String>
 
         override fun equals(other: Any?): Boolean
 
@@ -143,10 +142,10 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     class Index(name: String, unique: Boolean, columns: List<String>, orders: List<String>) {
 
-        @JvmField val name: String
-        @JvmField val unique: Boolean
-        @JvmField val columns: List<String>
-        @JvmField var orders: List<String>
+        val name: String
+        val unique: Boolean
+        val columns: List<String>
+        var orders: List<String>
 
         companion object {
             // should match the value in Index.kt
@@ -206,6 +205,8 @@
     if (notNull != other.notNull) return false
     // Only validate default value if it was defined in an entity, i.e. if the info
     // from the compiler itself has it. b/136019383
+    val defaultValue = this.defaultValue
+    val otherDefaultValue = other.defaultValue
     if (
         createdFrom == TableInfo.CREATED_FROM_ENTITY &&
             other.createdFrom == TableInfo.CREATED_FROM_DATABASE &&
@@ -216,15 +217,15 @@
     } else if (
         createdFrom == TableInfo.CREATED_FROM_DATABASE &&
             other.createdFrom == TableInfo.CREATED_FROM_ENTITY &&
-            other.defaultValue != null &&
-            !defaultValueEqualsCommon(other.defaultValue, defaultValue)
+            otherDefaultValue != null &&
+            !defaultValueEqualsCommon(otherDefaultValue, defaultValue)
     ) {
         return false
     } else if (
         createdFrom != TableInfo.CREATED_FROM_UNKNOWN &&
             createdFrom == other.createdFrom &&
-            (if (defaultValue != null) !defaultValueEqualsCommon(defaultValue, other.defaultValue)
-            else other.defaultValue != null)
+            (if (defaultValue != null) !defaultValueEqualsCommon(defaultValue, otherDefaultValue)
+            else otherDefaultValue != null)
     ) {
         return false
     }
diff --git a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/ViewInfo.kt b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/ViewInfo.kt
index 07d7449..0f80341 100644
--- a/room/room-runtime/src/commonMain/kotlin/androidx/room/util/ViewInfo.kt
+++ b/room/room-runtime/src/commonMain/kotlin/androidx/room/util/ViewInfo.kt
@@ -17,7 +17,6 @@
 
 import androidx.annotation.RestrictTo
 import androidx.sqlite.SQLiteConnection
-import kotlin.jvm.JvmField
 import kotlin.jvm.JvmStatic
 
 /**
@@ -30,9 +29,9 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
 expect class ViewInfo(name: String, sql: String?) {
     /** The view name */
-    @JvmField val name: String
+    val name: String
     /** The SQL of CREATE VIEW. */
-    @JvmField val sql: String?
+    val sql: String?
 
     override fun equals(other: Any?): Boolean
 
diff --git a/room/room-runtime/src/jvmAndroidMain/kotlin/androidx/room/concurrent/ThreadLocal.jvmAndroid.kt b/room/room-runtime/src/jvmAndroidMain/kotlin/androidx/room/concurrent/ThreadLocal.jvmAndroid.kt
index 206c1c9..b343d1a 100644
--- a/room/room-runtime/src/jvmAndroidMain/kotlin/androidx/room/concurrent/ThreadLocal.jvmAndroid.kt
+++ b/room/room-runtime/src/jvmAndroidMain/kotlin/androidx/room/concurrent/ThreadLocal.jvmAndroid.kt
@@ -20,6 +20,7 @@
 import kotlinx.coroutines.asContextElement
 
 /** Container of thread-local data. */
+@Suppress("ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT")
 actual typealias ThreadLocal<T> = java.lang.ThreadLocal<T>
 
 /**
diff --git a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/InvalidationTracker.jvmNative.kt b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/InvalidationTracker.jvmNative.kt
index 313c642..64020fb 100644
--- a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/InvalidationTracker.jvmNative.kt
+++ b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/InvalidationTracker.jvmNative.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.RestrictTo
 import androidx.sqlite.SQLiteConnection
 import kotlin.jvm.JvmOverloads
+import kotlin.jvm.JvmSuppressWildcards
 import kotlinx.coroutines.flow.Flow
 
 /**
@@ -34,7 +35,7 @@
 actual constructor(
     private val database: RoomDatabase,
     shadowTablesMap: Map<String, String>,
-    viewTables: Map<String, Set<String>>,
+    viewTables: Map<String, @JvmSuppressWildcards Set<String>>,
     vararg tableNames: String
 ) {
     private val implementation =
diff --git a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/TableInfo.jvmNative.kt b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/TableInfo.jvmNative.kt
index 0e2f13d..7bfa4b1 100644
--- a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/TableInfo.jvmNative.kt
+++ b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/TableInfo.jvmNative.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.RestrictTo
 import androidx.room.ColumnInfo.SQLiteTypeAffinity
 import androidx.sqlite.SQLiteConnection
+import kotlin.jvm.JvmStatic
 
 /**
  * A data class that holds the information about a table.
@@ -72,6 +73,7 @@
          * @param tableName The table name.
          * @return A TableInfo containing the schema information for the provided table name.
          */
+        @JvmStatic
         actual fun read(connection: SQLiteConnection, tableName: String): TableInfo {
             return readTableInfo(connection, tableName)
         }
diff --git a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/ViewInfo.jvmNative.kt b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/ViewInfo.jvmNative.kt
index b2a7a0c..60e07e7 100644
--- a/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/ViewInfo.jvmNative.kt
+++ b/room/room-runtime/src/jvmNativeMain/kotlin/androidx/room/util/ViewInfo.jvmNative.kt
@@ -17,6 +17,7 @@
 
 import androidx.annotation.RestrictTo
 import androidx.sqlite.SQLiteConnection
+import kotlin.jvm.JvmStatic
 
 /**
  * A data class that holds the information about a view.
@@ -47,6 +48,7 @@
          * @param viewName The view name.
          * @return A ViewInfo containing the schema information for the provided view name.
          */
+        @JvmStatic
         actual fun read(connection: SQLiteConnection, viewName: String): ViewInfo {
             return readViewInfo(connection, viewName)
         }
diff --git a/room/room-runtime/src/nativeMain/kotlin/androidx/room/concurrent/ThreadLocal.native.kt b/room/room-runtime/src/nativeMain/kotlin/androidx/room/concurrent/ThreadLocal.native.kt
index a285a1d..e6c1a36 100644
--- a/room/room-runtime/src/nativeMain/kotlin/androidx/room/concurrent/ThreadLocal.native.kt
+++ b/room/room-runtime/src/nativeMain/kotlin/androidx/room/concurrent/ThreadLocal.native.kt
@@ -16,6 +16,7 @@
 
 package androidx.room.concurrent
 
+import androidx.annotation.RestrictTo
 import kotlin.coroutines.CoroutineContext
 import kotlinx.atomicfu.atomic
 
@@ -29,6 +30,7 @@
 }
 
 /** Container of thread-local data. */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
 actual class ThreadLocal<T> {
     private val threadId = currentThreadId()
 
diff --git a/room/room-rxjava2/build.gradle b/room/room-rxjava2/build.gradle
index 96dc8c9..d5519cb 100644
--- a/room/room-rxjava2/build.gradle
+++ b/room/room-rxjava2/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import androidx.build.LibraryType
 
 plugins {
@@ -52,6 +54,7 @@
     inceptionYear = "2017"
     description = "Android Room RXJava2"
     legacyDisableKotlinStrictApiMode = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
diff --git a/room/room-rxjava3/build.gradle b/room/room-rxjava3/build.gradle
index de7e28d..c27019a 100644
--- a/room/room-rxjava3/build.gradle
+++ b/room/room-rxjava3/build.gradle
@@ -21,6 +21,8 @@
  * Please use that script when creating a new project, rather than copying an existing project and
  * modifying its settings.
  */
+
+import androidx.build.KotlinTarget
 import androidx.build.LibraryType
 
 plugins {
@@ -52,6 +54,7 @@
     inceptionYear = "2020"
     description = "Android Room RXJava3"
     legacyDisableKotlinStrictApiMode = true
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }
 
 android {
diff --git a/room/room-testing/build.gradle b/room/room-testing/build.gradle
index 4678633..625d4ed 100644
--- a/room/room-testing/build.gradle
+++ b/room/room-testing/build.gradle
@@ -104,5 +104,5 @@
     description = "Android Room Testing"
     legacyDisableKotlinStrictApiMode = true
     metalavaK2UastEnabled = false
-    kotlinTarget = KotlinTarget.KOTLIN_1_9
+    kotlinTarget = KotlinTarget.KOTLIN_2_0
 }