Add generation of first set of androidx keep annotations

* @UsesReflectionToConstruct
* @UsesReflectionToAccessMethod
* @UsesReflectionToAccessField

The CL does not add actual support to process these annotations.

Bug: b/392865072
Change-Id: I621403525607dc66e04843d3006a812c01010f54
diff --git a/src/keepanno/java/androidx/annotation/keep/AnnotationPattern.kt b/src/keepanno/java/androidx/annotation/keep/AnnotationPattern.kt
index a9eb9f8..623b80d 100644
--- a/src/keepanno/java/androidx/annotation/keep/AnnotationPattern.kt
+++ b/src/keepanno/java/androidx/annotation/keep/AnnotationPattern.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/ClassNamePattern.kt b/src/keepanno/java/androidx/annotation/keep/ClassNamePattern.kt
index 4abf83c..cf646db 100644
--- a/src/keepanno/java/androidx/annotation/keep/ClassNamePattern.kt
+++ b/src/keepanno/java/androidx/annotation/keep/ClassNamePattern.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/InstanceOfPattern.kt b/src/keepanno/java/androidx/annotation/keep/InstanceOfPattern.kt
index 01a1e51..ad1b9e8 100644
--- a/src/keepanno/java/androidx/annotation/keep/InstanceOfPattern.kt
+++ b/src/keepanno/java/androidx/annotation/keep/InstanceOfPattern.kt
@@ -24,9 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
-
 /**
  * A pattern structure for matching instances of classes and interfaces.
  *
diff --git a/src/keepanno/java/androidx/annotation/keep/KeepBinding.kt b/src/keepanno/java/androidx/annotation/keep/KeepBinding.kt
index 526d374..0be3b9e 100644
--- a/src/keepanno/java/androidx/annotation/keep/KeepBinding.kt
+++ b/src/keepanno/java/androidx/annotation/keep/KeepBinding.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/KeepCondition.kt b/src/keepanno/java/androidx/annotation/keep/KeepCondition.kt
index f64cc7f..4219dc5 100644
--- a/src/keepanno/java/androidx/annotation/keep/KeepCondition.kt
+++ b/src/keepanno/java/androidx/annotation/keep/KeepCondition.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/KeepForApi.kt b/src/keepanno/java/androidx/annotation/keep/KeepForApi.kt
index aa8f2fe..070926c 100644
--- a/src/keepanno/java/androidx/annotation/keep/KeepForApi.kt
+++ b/src/keepanno/java/androidx/annotation/keep/KeepForApi.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/KeepTarget.kt b/src/keepanno/java/androidx/annotation/keep/KeepTarget.kt
index d8a5926..0bf1cdb 100644
--- a/src/keepanno/java/androidx/annotation/keep/KeepTarget.kt
+++ b/src/keepanno/java/androidx/annotation/keep/KeepTarget.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/StringPattern.kt b/src/keepanno/java/androidx/annotation/keep/StringPattern.kt
index a81c2b0..34e8e59 100644
--- a/src/keepanno/java/androidx/annotation/keep/StringPattern.kt
+++ b/src/keepanno/java/androidx/annotation/keep/StringPattern.kt
@@ -24,9 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
-
 /**
  * A pattern structure for matching strings.
  *
diff --git a/src/keepanno/java/androidx/annotation/keep/TypePattern.kt b/src/keepanno/java/androidx/annotation/keep/TypePattern.kt
index 3d9c032..3f4a779 100644
--- a/src/keepanno/java/androidx/annotation/keep/TypePattern.kt
+++ b/src/keepanno/java/androidx/annotation/keep/TypePattern.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/UnconditionallyKeep.kt b/src/keepanno/java/androidx/annotation/keep/UnconditionallyKeep.kt
new file mode 100644
index 0000000..544b54e
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/UnconditionallyKeep.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// GENERATED FILE. DO NOT EDIT! See KeepItemAnnotationGenerator.java.
+// ***********************************************************************************
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+/**
+ * Indicates code which is accessed by references from outside of the application code directly,
+ * such as via JNI, reflection, or instantiation from platform framework code.
+ *
+ * NOTE: This keep rule is unconditional, meaning that the annotated class, method, or field will
+ * always be preserved in the final application even if, for example, the surrounding code is never
+ * used.
+ *
+ * If reflection or JNI access occurs inside the application, instead prefer the
+ * `@UsesReflection***` annotations, as they will keep conditionally, rather than unconditionally as
+ * this annotation does.
+ *
+ * @see UsesReflectionToConstruct
+ * @see UsesReflectionToAccessMethod
+ * @see UsesReflectionToAccessField
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(
+    AnnotationTarget.CLASS,
+    AnnotationTarget.FIELD,
+    AnnotationTarget.FUNCTION,
+    AnnotationTarget.CONSTRUCTOR,
+)
+public annotation class UnconditionallyKeep(
+
+    /**
+     * Should the name be preserved.
+     *
+     * Generally this is true if the reference is external, but this can be disabled if the name
+     * isn't important.
+     */
+    val shouldPreserveName: Boolean = true
+)
diff --git a/src/keepanno/java/androidx/annotation/keep/Unspecified.kt b/src/keepanno/java/androidx/annotation/keep/Unspecified.kt
new file mode 100644
index 0000000..101ec13
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/Unspecified.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+/**
+ * Used to define an unspecified class value in the Keep annotations.
+ *
+ * For example, when a method return class isn't important to specify in
+ * [UsesReflectionToAccessMethod.returnClass], it defaults to `Unspecified::class`, which signifies
+ * that any class is accepted.
+ *
+ * This is used as `null` cannot be used as a default in annotations.
+ */
+public class Unspecified
diff --git a/src/keepanno/java/androidx/annotation/keep/UsedByNative.kt b/src/keepanno/java/androidx/annotation/keep/UsedByNative.kt
index 668c549..c807dc8 100644
--- a/src/keepanno/java/androidx/annotation/keep/UsedByNative.kt
+++ b/src/keepanno/java/androidx/annotation/keep/UsedByNative.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/UsedByReflection.kt b/src/keepanno/java/androidx/annotation/keep/UsedByReflection.kt
index 6d29600d..b624aa0 100644
--- a/src/keepanno/java/androidx/annotation/keep/UsedByReflection.kt
+++ b/src/keepanno/java/androidx/annotation/keep/UsedByReflection.kt
@@ -24,8 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
 import kotlin.reflect.KClass
 
 /**
diff --git a/src/keepanno/java/androidx/annotation/keep/UsesReflection.kt b/src/keepanno/java/androidx/annotation/keep/UsesReflection.kt
index 102fe77..6690527 100644
--- a/src/keepanno/java/androidx/annotation/keep/UsesReflection.kt
+++ b/src/keepanno/java/androidx/annotation/keep/UsesReflection.kt
@@ -24,9 +24,6 @@
 
 package androidx.annotation.keep
 
-import kotlin.annotation.Retention
-import kotlin.annotation.Target
-
 /**
  * Annotation to declare the reflective usages made by a class, method or field.
  *
diff --git a/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessField.kt b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessField.kt
new file mode 100644
index 0000000..d80fb81
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessField.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// GENERATED FILE. DO NOT EDIT! See KeepItemAnnotationGenerator.java.
+// ***********************************************************************************
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+import kotlin.reflect.KClass
+
+/**
+ * The annotated code uses reflection to indirectly access a field of the specified class/interface,
+ * or its subclasses / interface implementers.
+ *
+ * This annotation indicates to optimizers or shrinkers that the target field should be preserved if
+ * the annotated code is reachable in the final application build.
+ *
+ * @see UsesReflectionToConstruct
+ * @see UsesReflectionToAccessMethod
+ */
+@Repeatable
+@Retention(AnnotationRetention.BINARY)
+@Target(
+    AnnotationTarget.CLASS,
+    AnnotationTarget.FIELD,
+    AnnotationTarget.FUNCTION,
+    AnnotationTarget.CONSTRUCTOR,
+)
+public annotation class UsesReflectionToAccessField(
+
+    /**
+     * Class containing the field accessed by reflection.
+     *
+     * Mutually exclusive with [className].
+     */
+    val classConstant: KClass<*> = Unspecified::class,
+
+    /**
+     * Class name (or pattern) containing the field accessed by reflection.
+     *
+     * Mutually exclusive with [classConstant].
+     */
+    val className: String = "",
+
+    /** Field name (or pattern) accessed by reflection. */
+    val fieldName: String,
+
+    /**
+     * Class of field accessed by reflection.
+     *
+     * Ignored if not specified.
+     *
+     * Mutually exclusive with [fieldClassName].
+     */
+    val fieldClass: KClass<*> = Unspecified::class,
+
+    /**
+     * Class (or class pattern) of field accessed by reflection.
+     *
+     * Ignored if not specified.
+     *
+     * Mutually exclusive with [fieldClass].
+     */
+    val fieldClassName: String = "",
+)
diff --git a/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessMethod.kt b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessMethod.kt
new file mode 100644
index 0000000..ad67456
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToAccessMethod.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// GENERATED FILE. DO NOT EDIT! See KeepItemAnnotationGenerator.java.
+// ***********************************************************************************
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+import kotlin.reflect.KClass
+
+/**
+ * The annotated code uses reflection to indirectly access a method of the specified
+ * class/interface, or its subclasses / interface implementers.
+ *
+ * This annotation indicates to optimizers or shrinkers that the target method should be preserved
+ * if the annotated code is reachable in the final application build.
+ *
+ * @see UsesReflectionToConstruct
+ * @see UsesReflectionToAccessField
+ */
+@Repeatable
+@Retention(AnnotationRetention.BINARY)
+@Target(
+    AnnotationTarget.CLASS,
+    AnnotationTarget.FIELD,
+    AnnotationTarget.FUNCTION,
+    AnnotationTarget.CONSTRUCTOR,
+)
+public annotation class UsesReflectionToAccessMethod(
+
+    /**
+     * Class containing the method accessed by reflection.
+     *
+     * Mutually exclusive with [className].
+     */
+    val classConstant: KClass<*> = Unspecified::class,
+
+    /**
+     * Class name (or pattern) containing the method accessed by reflection.
+     *
+     * Mutually exclusive with [classConstant].
+     */
+    val className: String = "",
+
+    /** Method name (or pattern) accessed by reflection. */
+    val methodName: String,
+
+    /**
+     * Defines which method to keep by specifying set of parameter classes passed.
+     *
+     * If neither `param` nor `paramClassNames` is specified then methods with all parameter lists
+     * are kept.
+     *
+     * Mutually exclusive with [paramClassNames].
+     */
+    val params: Array<KClass<*>> = [Unspecified::class],
+
+    /**
+     * Defines which method to keep by specifying set of parameter classes passed.
+     *
+     * If neither `param` nor `paramClassNames` is specified then methods with all parameter lists
+     * are kept.
+     *
+     * Mutually exclusive with [params].
+     */
+    val paramClassNames: Array<String> = [""],
+
+    /**
+     * Return type of the method accessed by reflection.
+     *
+     * Ignored if not specified.
+     *
+     * Mutually exclusive with [returnClassName].
+     */
+    val returnClass: KClass<*> = Unspecified::class,
+
+    /**
+     * Return type (or type pattern) of the method accessed by reflection.
+     *
+     * Ignored if not specified.
+     *
+     * Mutually exclusive with [returnClass].
+     */
+    val returnClassName: String = "",
+)
diff --git a/src/keepanno/java/androidx/annotation/keep/UsesReflectionToConstruct.kt b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToConstruct.kt
new file mode 100644
index 0000000..0741c2f
--- /dev/null
+++ b/src/keepanno/java/androidx/annotation/keep/UsesReflectionToConstruct.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************************************************
+// GENERATED FILE. DO NOT EDIT! See KeepItemAnnotationGenerator.java.
+// ***********************************************************************************
+
+// ***********************************************************************************
+// MAINTAINED AND TESTED IN THE R8 REPO. PLEASE MAKE CHANGES THERE AND REPLICATE.
+// ***********************************************************************************
+
+package androidx.annotation.keep
+
+import kotlin.reflect.KClass
+
+/**
+ * The annotated code uses reflection to indirectly invoke a constructor of a class/interface, or
+ * its subclasses / interface implementers.
+ *
+ * This annotation indicates to optimizers or shrinkers that the target constructor should be kept
+ * if the annotated code is reachable in the final application build.
+ *
+ * `@UsesReflectionToConstruct()` is a convenience for `@UsesReflectionToAccessMethod(methodName =
+ * "<init>")`
+ *
+ * @see UsesReflectionToAccessMethod
+ * @see UsesReflectionToAccessField
+ */
+@Repeatable
+@Retention(AnnotationRetention.BINARY)
+@Target(
+    AnnotationTarget.CLASS,
+    AnnotationTarget.FIELD,
+    AnnotationTarget.FUNCTION,
+    AnnotationTarget.CONSTRUCTOR,
+)
+public annotation class UsesReflectionToConstruct(
+
+    /**
+     * Class to be instantiated.
+     *
+     * Mutually exclusive with [className].
+     */
+    val classConstant: KClass<*> = Unspecified::class,
+
+    /**
+     * Class to be instantiated.
+     *
+     * Mutually exclusive with [classConstant].
+     */
+    val className: String = "",
+
+    /**
+     * Defines which constructor to keep by specifying the parameter list types.
+     *
+     * If neither `param` nor `paramClassNames` is specified then constructors with all parameter
+     * lists are kept.
+     *
+     * Mutually exclusive with [paramClassNames].
+     */
+    val params: Array<KClass<*>> = [Unspecified::class],
+
+    /**
+     * Defines which constructor to keep by specifying the parameter list types.
+     *
+     * If neither `param` nor `paramClassNames` is specified then constructors with all parameter
+     * lists are kept.
+     *
+     * Mutually exclusive with [params].
+     */
+    val paramClassNames: Array<String> = [""],
+)
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
index c174fa7..59bd281 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
@@ -131,6 +131,89 @@
     }
   }
 
+  public static final class UsesReflectionToConstruct {
+    private static final String DESCRIPTOR = "Landroidx/annotation/keep/UsesReflectionToConstruct;";
+    private static final String DESCRIPTOR_CONTAINER =
+        "Landroidx/annotation/keep/UsesReflectionToConstruct$Container;";
+    private static final String DESCRIPTOR_LEGACY =
+        "Lcom/android/tools/r8/keepanno/annotations/UsesReflectionToConstruct;";
+
+    public static boolean isDescriptor(String descriptor) {
+      return DESCRIPTOR.equals(descriptor) || DESCRIPTOR_LEGACY.equals(descriptor);
+    }
+
+    public static boolean isKotlinRepeatableContainerDescriptor(String descriptor) {
+      return DESCRIPTOR_CONTAINER.equals(descriptor);
+    }
+
+    public static String getDescriptor() {
+      return DESCRIPTOR;
+    }
+
+    public static final String classSelectionGroup = "class-selection";
+    public static final String classConstant = "classConstant";
+    public static final String className = "className";
+    public static final String constructorParametersGroup = "constructor-parameters";
+    public static final String params = "params";
+    public static final String paramClassNames = "paramClassNames";
+  }
+
+  public static final class UsesReflectionToAccessMethod {
+    private static final String DESCRIPTOR =
+        "Landroidx/annotation/keep/UsesReflectionToAccessMethod;";
+    private static final String DESCRIPTOR_CONTAINER =
+        "Landroidx/annotation/keep/UsesReflectionToAccessMethod$Container;";
+    private static final String DESCRIPTOR_LEGACY =
+        "Lcom/android/tools/r8/keepanno/annotations/UsesReflectionToAccessMethod;";
+
+    public static boolean isDescriptor(String descriptor) {
+      return DESCRIPTOR.equals(descriptor) || DESCRIPTOR_LEGACY.equals(descriptor);
+    }
+
+    public static boolean isKotlinRepeatableContainerDescriptor(String descriptor) {
+      return DESCRIPTOR_CONTAINER.equals(descriptor);
+    }
+
+    public static String getDescriptor() {
+      return DESCRIPTOR;
+    }
+
+    public static final String classSelectionGroup = "class-selection";
+    public static final String classConstant = "classConstant";
+    public static final String className = "className";
+    public static final String constructorParametersGroup = "constructor-parameters";
+    public static final String params = "params";
+    public static final String paramClassNames = "paramClassNames";
+  }
+
+  public static final class UsesReflectionToAccessField {
+    private static final String DESCRIPTOR =
+        "Landroidx/annotation/keep/UsesReflectionToAccessField;";
+    private static final String DESCRIPTOR_CONTAINER =
+        "Landroidx/annotation/keep/UsesReflectionToAccessField$Container;";
+    private static final String DESCRIPTOR_LEGACY =
+        "Lcom/android/tools/r8/keepanno/annotations/UsesReflectionToAccessField;";
+
+    public static boolean isDescriptor(String descriptor) {
+      return DESCRIPTOR.equals(descriptor) || DESCRIPTOR_LEGACY.equals(descriptor);
+    }
+
+    public static boolean isKotlinRepeatableContainerDescriptor(String descriptor) {
+      return DESCRIPTOR_CONTAINER.equals(descriptor);
+    }
+
+    public static String getDescriptor() {
+      return DESCRIPTOR;
+    }
+
+    public static final String classSelectionGroup = "class-selection";
+    public static final String classConstant = "classConstant";
+    public static final String className = "className";
+    public static final String constructorParametersGroup = "constructor-parameters";
+    public static final String params = "params";
+    public static final String paramClassNames = "paramClassNames";
+  }
+
   /** Item properties common to binding items, conditions and targets. */
   public static final class Item {
     public static final String classGroup = "class";
diff --git a/src/test/java/com/android/tools/r8/keepanno/utils/DocPrinterBase.java b/src/test/java/com/android/tools/r8/keepanno/utils/DocPrinterBase.java
index 6aacce6..d2c6b45 100644
--- a/src/test/java/com/android/tools/r8/keepanno/utils/DocPrinterBase.java
+++ b/src/test/java/com/android/tools/r8/keepanno/utils/DocPrinterBase.java
@@ -35,7 +35,7 @@
 
   public T setDocTitle(String title) {
     assert this.title == null;
-    assert title.endsWith(".");
+    assert title.endsWith(".") : "Title '" + title + "' should end with a dot.";
     this.title = title;
     return self();
   }
@@ -54,6 +54,25 @@
     return self();
   }
 
+  public T addLines(String... lines) {
+    return addLines(Arrays.asList(lines));
+  }
+
+  public T addLines(List<String> lines) {
+    additionalLines.addAll(lines);
+    return self();
+  }
+
+  public T addSection(String... lines) {
+    return addSection(Arrays.asList(lines));
+  }
+
+  public T addSection(List<String> lines) {
+    additionalLines.add("");
+    additionalLines.addAll(lines);
+    return self();
+  }
+
   public T addParagraph(String... lines) {
     return addParagraph(Arrays.asList(lines));
   }
diff --git a/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java b/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
index b0089be..17ab6c3 100644
--- a/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
+++ b/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.cfmethodgeneration.CodeGenerationBase;
 import com.android.tools.r8.keepanno.annotations.KeepItemKind;
 import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.StringUtils;
@@ -23,6 +24,7 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
@@ -90,6 +92,7 @@
   }
 
   public static class EnumReference {
+
     public final ClassReference enumClass;
     public final String enumValue;
 
@@ -177,17 +180,23 @@
       }
     }
 
-    private String kotlinValueType() {
-      if (valueType.equals("Class<?>")) {
+    private static String kotlinValueType(String type) {
+      if (type.equals("Class<?>")) {
         return "KClass<*>";
       }
-      if (valueType.equals("boolean")) {
+      if (type.equals("boolean")) {
         return "Boolean";
       }
+      return type;
+    }
+
+    private String kotlinValueType() {
       if (valueType.endsWith("[]")) {
-        return "Array<" + valueType.substring(0, valueType.length() - 2) + ">";
+        String baseType = valueType.substring(0, valueType.length() - 2);
+        assert !baseType.endsWith("[]") : "Multi dimensional arrays are not supported";
+        return "Array<" + kotlinValueType(baseType) + ">";
       }
-      return valueType;
+      return kotlinValueType(valueType);
     }
 
     private String kotlinValueDefault() {
@@ -235,6 +244,11 @@
       return setValue("{" + value + "}");
     }
 
+    public GroupMember defaultArrayClass(String value) {
+      setType("Class<?>" + "[]");
+      return setValue("{" + value + "}");
+    }
+
     public GroupMember defaultEmptyString() {
       return defaultValue(JAVA_STRING, quote(""));
     }
@@ -246,10 +260,19 @@
     public GroupMember defaultArrayEmpty(ClassReference type) {
       return defaultArrayValue(type, "");
     }
+
+    public GroupMember defaultUnspecifiedClass() {
+      return setType("Class<?>").setValue("Unspecified::class");
+    }
+
+    public GroupMember defaultUnspecifiedArray() {
+      return setType("Array<KClass<*>>").setValue("[Unspecified::class]");
+    }
   }
 
   public static class Group {
 
+    boolean forAndroidX = false;
     final String name;
     final List<GroupMember> members = new ArrayList<>();
     final List<String> footers = new ArrayList<>();
@@ -261,6 +284,15 @@
       this.name = name;
     }
 
+    Group forAndroidX(boolean forAndroidX) {
+      this.forAndroidX = forAndroidX;
+      return this;
+    }
+
+    Group forAndroidX() {
+      return forAndroidX(true);
+    }
+
     Group allowMutuallyExclusiveWithOtherGroups() {
       mutuallyExclusiveWithOtherGroups = true;
       return this;
@@ -293,12 +325,17 @@
               group.members.forEach(m -> mutuallyExclusiveProperties.add(m.name));
             });
         if (mutuallyExclusiveProperties.size() == 1) {
-          member.addParagraph(
-              "Mutually exclusive with the property `"
-                  + mutuallyExclusiveProperties.get(0)
-                  + "` also defining "
-                  + name
-                  + ".");
+          if (forAndroidX) {
+            member.addSection(
+                "Mutually exclusive with [" + mutuallyExclusiveProperties.get(0) + "].");
+          } else {
+            member.addParagraph(
+                "Mutually exclusive with the property `"
+                    + mutuallyExclusiveProperties.get(0)
+                    + "` also defining "
+                    + name
+                    + ".");
+          }
         } else if (mutuallyExclusiveProperties.size() > 1) {
           member.addParagraph(
               "Mutually exclusive with the following other properties defining " + name + ":");
@@ -361,6 +398,12 @@
     final ClassReference KEEP_CONDITION;
     final ClassReference KEEP_FOR_API;
 
+    final ClassReference USES_REFLECTION_TO_CONSTRUCT;
+    final ClassReference USES_REFLECTION_TO_ACCESS_METHOD;
+    final ClassReference USES_REFLECTION_TO_ACCESS_FIELD;
+    final ClassReference UNCONDITIONALLY_KEEP;
+    final List<ClassReference> REPEATABLE_ANNOTATIONS;
+
     final ClassReference KEEP_ITEM_KIND;
     final EnumReference KIND_ONLY_CLASS;
     final EnumReference KIND_ONLY_MEMBERS;
@@ -422,8 +465,6 @@
 
     final List<Class<?>> ANNOTATION_IMPORTS =
         ImmutableList.of(ElementType.class, Retention.class, RetentionPolicy.class, Target.class);
-    final List<Class<?>> KOTLIN_ANNOTATION_IMPORTS =
-        ImmutableList.of(kotlin.annotation.Retention.class, kotlin.annotation.Target.class);
 
     private final PrintStream writer;
     private final String pkg;
@@ -451,6 +492,15 @@
       KEEP_CONDITION = annoClass("KeepCondition");
       KEEP_FOR_API = annoClass("KeepForApi");
 
+      USES_REFLECTION_TO_CONSTRUCT = annoClass("UsesReflectionToConstruct");
+      USES_REFLECTION_TO_ACCESS_METHOD = annoClass("UsesReflectionToAccessMethod");
+      USES_REFLECTION_TO_ACCESS_FIELD = annoClass("UsesReflectionToAccessField");
+      UNCONDITIONALLY_KEEP = annoClass("UnconditionallyKeep");
+      REPEATABLE_ANNOTATIONS =
+          ImmutableList.of(
+              USES_REFLECTION_TO_CONSTRUCT,
+              USES_REFLECTION_TO_ACCESS_METHOD,
+              USES_REFLECTION_TO_ACCESS_FIELD);
       KEEP_ITEM_KIND = annoClass("KeepItemKind");
       KIND_ONLY_CLASS = enumRef(KEEP_ITEM_KIND, "ONLY_CLASS");
       KIND_ONLY_MEMBERS = enumRef(KEEP_ITEM_KIND, "ONLY_MEMBERS");
@@ -612,7 +662,18 @@
     }
 
     private void printAnnotationImports() {
-      printImports(generateKotlin() ? KOTLIN_ANNOTATION_IMPORTS : ANNOTATION_IMPORTS);
+      printAnnotationImports(false);
+    }
+
+    private void printAnnotationImports(boolean incluceRepeatable) {
+      if (generateKotlin()) {
+        // Classes in kotlin.annotation does not need to be imported.
+        return;
+      }
+      if (incluceRepeatable) {
+        printImports(ImmutableList.of(Repeatable.class));
+      }
+      printImports(ANNOTATION_IMPORTS);
     }
 
     private void printOpenAnnotationClassTargettingAnnotations(String clazz) {
@@ -627,7 +688,7 @@
       }
     }
 
-    private void printOpenAnnotationClassTargettingClassFieldlMethodCtor(String clazz) {
+    private void printOpenAnnotationClassTargetingClassFieldMethodCtor(String clazz) {
       if (generateKotlin()) {
         println("@Retention(AnnotationRetention.BINARY)");
         println("@Target(");
@@ -1684,7 +1745,7 @@
               "When a member is annotated, the member patterns cannot be used as the annotated"
                   + " member itself fully defines the item to be kept (i.e., itself).")
           .printDoc(this::println);
-      printOpenAnnotationClassTargettingClassFieldlMethodCtor("KeepForApi");
+      printOpenAnnotationClassTargetingClassFieldMethodCtor("KeepForApi");
       println();
       withIndent(
           () -> {
@@ -1773,7 +1834,7 @@
               "    // unreachable",
               "  }")
           .printDoc(this::println);
-      printOpenAnnotationClassTargettingClassFieldlMethodCtor(getUnqualifiedName(USES_REFLECTION));
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(getUnqualifiedName(USES_REFLECTION));
       println();
       withIndent(
           () -> {
@@ -1786,6 +1847,267 @@
       printCloseAnnotationClass();
     }
 
+    private Group createAndroidXClassSelection(
+        Consumer<GroupMember> classConstantConsumer, Consumer<GroupMember> classNameConsumer) {
+      GroupMember classConstant = new GroupMember("classConstant").defaultUnspecifiedClass();
+      classConstantConsumer.accept(classConstant);
+      GroupMember className = new GroupMember("className").defaultEmptyString();
+      classNameConsumer.accept(className);
+      return new Group("class-selection")
+          .forAndroidX()
+          .addMember(classConstant)
+          .addMember(className);
+    }
+
+    private Group createAndroidXParameterSelection(
+        Consumer<GroupMember> paramsConsumer, Consumer<GroupMember> paramClassNamesConsumer) {
+      GroupMember params = new GroupMember("params").defaultUnspecifiedArray();
+      paramsConsumer.accept(params);
+      GroupMember paramClassNames =
+          new GroupMember("paramClassNames")
+              .defaultArrayValue(Reference.classFromClass(String.class), "\"\"");
+      paramClassNamesConsumer.accept(paramClassNames);
+      return new Group("constructor-parameters")
+          .forAndroidX()
+          .addMember(params)
+          .addMember(paramClassNames);
+    }
+
+    private Group createMethodNameSelection() {
+      return new Group("method-name")
+          .addMember(
+              new GroupMember("methodName")
+                  .setDocTitle("Method name (or pattern) accessed by reflection.")
+                  .requiredStringValue());
+    }
+
+    private Group createAndroidXReturnTypeSelection() {
+      return new Group("return-selection")
+          .forAndroidX()
+          .addMember(
+              new GroupMember("returnClass")
+                  .setDocTitle("Return type of the method accessed by reflection.")
+                  .addSection("Ignored if not specified.")
+                  .defaultUnspecifiedClass())
+          .addMember(
+              new GroupMember("returnClassName")
+                  .setDocTitle(
+                      "Return type (or type pattern) of the method accessed by" + " reflection.")
+                  .addSection("Ignored if not specified.")
+                  .defaultEmptyString());
+    }
+
+    private Group createAndroidXFieldNameSelection() {
+      return new Group("field-name")
+          .addMember(
+              new GroupMember("fieldName")
+                  .setDocTitle("Field name (or pattern) accessed by reflection.")
+                  .requiredStringValue());
+    }
+
+    private Group createAndroidXFieldTypeSelection() {
+      return new Group("field-type-selection")
+          .forAndroidX()
+          .addMember(
+              new GroupMember("fieldClass")
+                  .setDocTitle("Class of field accessed by reflection.")
+                  .addSection("Ignored if not specified.")
+                  .defaultUnspecifiedClass())
+          .addMember(
+              new GroupMember("fieldClassName")
+                  .setDocTitle("Class (or class pattern) of field accessed by reflection.")
+                  .addSection("Ignored if not specified.")
+                  .defaultEmptyString());
+    }
+
+    private void generateUsesReflectionToConstruct() {
+      printCopyRight(2025);
+      printPackage();
+      printAnnotationImports(true);
+      if (generateKotlin()) {
+        println("import kotlin.reflect.KClass");
+      }
+      DocPrinter.printer()
+          .setDocTitle(
+              "The annotated code uses reflection to indirectly invoke a constructor of a"
+                  + " class/interface, or its subclasses / interface implementers.")
+          .addSection(
+              "This annotation indicates to optimizers or shrinkers that the target constructor"
+                  + " should be kept if the annotated code is reachable in the final application"
+                  + " build.")
+          .addSection(
+              "`@UsesReflectionToConstruct()` is a convenience for"
+                  + " `@UsesReflectionToAccessMethod(methodName = \"<init>\")`")
+          .addSection("@see UsesReflectionToAccessMethod")
+          .addSection("@see UsesReflectionToAccessField")
+          .printDoc(this::println);
+      println("@Repeatable");
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(
+          getUnqualifiedName(USES_REFLECTION_TO_CONSTRUCT));
+      println();
+      withIndent(
+          () -> {
+            createAndroidXClassSelection(
+                    g -> g.setDocTitle("Class to be instantiated."),
+                    g -> g.setDocTitle("Class to be instantiated."))
+                .generate(this);
+            println();
+            createAndroidXParameterSelection(
+                    g ->
+                        g.setDocTitle(
+                                "Defines which constructor to keep by specifying the parameter list"
+                                    + " types.")
+                            .addSection(
+                                "If neither `param` nor `paramClassNames` is specified then"
+                                    + " constructors with all parameter lists are kept."),
+                    g ->
+                        g.setDocTitle(
+                                "Defines which constructor to keep by specifying the parameter list"
+                                    + " types.")
+                            .addSection(
+                                "If neither `param` nor `paramClassNames` is specified then"
+                                    + " constructors with all parameter lists are kept."))
+                .generate(this);
+          });
+      printCloseAnnotationClass();
+    }
+
+    private void generateUsesReflectionToAccessMethod() {
+      printCopyRight(2025);
+      printPackage();
+      printAnnotationImports(true);
+      if (generateKotlin()) {
+        println("import kotlin.reflect.KClass");
+      }
+      DocPrinter.printer()
+          .setDocTitle(
+              "The annotated code uses reflection to indirectly access a method of the specified"
+                  + " class/interface, or its subclasses / interface implementers.")
+          .addSection(
+              "This annotation indicates to optimizers or shrinkers that the target method should"
+                  + " be preserved if the annotated code is reachable in the final application"
+                  + " build.")
+          .addSection("@see UsesReflectionToConstruct")
+          .addSection("@see UsesReflectionToAccessField")
+          .printDoc(this::println);
+      println("@Repeatable");
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(
+          getUnqualifiedName(USES_REFLECTION_TO_ACCESS_METHOD));
+      println();
+      withIndent(
+          () -> {
+            createAndroidXClassSelection(
+                    g -> g.setDocTitle("Class containing the method accessed by reflection."),
+                    g ->
+                        g.setDocTitle(
+                            "Class name (or pattern) containing the method accessed by"
+                                + " reflection."))
+                .generate(this);
+            println();
+            createMethodNameSelection().generate(this);
+            println();
+            createAndroidXParameterSelection(
+                    g ->
+                        g.setDocTitle(
+                                "Defines which method to keep by specifying set of parameter"
+                                    + " classes passed.")
+                            .addSection(
+                                "If neither `param` nor `paramClassNames` is specified then"
+                                    + " methods with all parameter lists are kept."),
+                    g ->
+                        g.setDocTitle(
+                                "Defines which method to keep by specifying set of parameter"
+                                    + " classes passed.")
+                            .addSection(
+                                "If neither `param` nor `paramClassNames` is specified then"
+                                    + " methods with all parameter lists are kept."))
+                .generate(this);
+            println();
+            createAndroidXReturnTypeSelection().generate(this);
+          });
+      printCloseAnnotationClass();
+    }
+
+    private void generateUsesReflectionToAccessField() {
+      printCopyRight(2025);
+      printPackage();
+      printAnnotationImports(true);
+      if (generateKotlin()) {
+        println("import kotlin.reflect.KClass");
+      }
+      DocPrinter.printer()
+          .setDocTitle(
+              "The annotated code uses reflection to indirectly access a field of the specified"
+                  + " class/interface, or its subclasses / interface implementers.")
+          .addSection(
+              "This annotation indicates to optimizers or shrinkers that the target field should be"
+                  + " preserved if the annotated code is reachable in the final application build.")
+          .addSection("@see UsesReflectionToConstruct", "@see UsesReflectionToAccessMethod")
+          .printDoc(this::println);
+      println("@Repeatable");
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(
+          getUnqualifiedName(USES_REFLECTION_TO_ACCESS_FIELD));
+      println();
+      withIndent(
+          () -> {
+            createAndroidXClassSelection(
+                    g -> g.setDocTitle("Class containing the field accessed by reflection."),
+                    g ->
+                        g.setDocTitle(
+                            "Class name (or pattern) containing the field accessed by"
+                                + " reflection."))
+                .generate(this);
+            println();
+            createAndroidXFieldNameSelection().generate(this);
+            println();
+            createAndroidXFieldTypeSelection().generate(this);
+          });
+      printCloseAnnotationClass();
+    }
+
+    private void generateUnconditionallyKeep() {
+      printCopyRight(2025);
+      printPackage();
+      printAnnotationImports(true);
+      if (generateKotlin()) {
+        println("import kotlin.reflect.KClass");
+      }
+      DocPrinter.printer()
+          .setDocTitle(
+              "Indicates code which is accessed by references from outside of the application code"
+                  + " directly, such as via JNI, reflection, or instantiation from platform"
+                  + " framework code.")
+          .addSection(
+              "NOTE: This keep rule is unconditional, meaning that the annotated class, method, or"
+                  + " field will always be preserved in the final application even if, for example,"
+                  + " the surrounding code is never used.")
+          .addSection(
+              "If reflection or JNI access occurs inside the application, instead prefer the"
+                  + " `@UsesReflection***` annotations, as they will keep conditionally, rather"
+                  + " than unconditionally as this annotation does.")
+          .addSection(
+              "@see UsesReflectionToConstruct",
+              "@see UsesReflectionToAccessMethod",
+              "@see UsesReflectionToAccessField")
+          .printDoc(this::println);
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(
+          getUnqualifiedName(UNCONDITIONALLY_KEEP));
+      println();
+      withIndent(
+          () -> {
+            new Group("should-preserve-name")
+                .addMember(
+                    new GroupMember("shouldPreserveName")
+                        .setDocTitle("Should the name be preserved.")
+                        .addSection(
+                            "Generally this is true if the reference is external, but this can be"
+                                + " disabled if the name isn't important.")
+                        .defaultBooleanValue(true))
+                .generate(this);
+          });
+      printCloseAnnotationClass();
+    }
+
     private void generateUsedByX(String annotationClassName, String doc) {
       printCopyRight(2023);
       printPackage();
@@ -1815,7 +2137,7 @@
               "When a member is annotated, the member patterns cannot be used as the annotated"
                   + " member itself fully defines the item to be kept (i.e., itself).")
           .printDoc(this::println);
-      printOpenAnnotationClassTargettingClassFieldlMethodCtor(annotationClassName);
+      printOpenAnnotationClassTargetingClassFieldMethodCtor(annotationClassName);
       println();
       withIndent(
           () -> {
@@ -1901,6 +2223,10 @@
             generateUsedByNativeConstants();
             generateCheckRemovedConstants();
             generateCheckOptimizedOutConstants();
+            // androidx annotations.
+            generateUsesReflectionToConstructConstants();
+            generateUsesReflectionToAccessMethodConstants();
+            generateUsesReflectionToAccessFieldConstants();
             // Common item fields.
             generateItemConstants();
             // Inner annotation classes.
@@ -1933,10 +2259,20 @@
           "Lcom/android/tools/r8/keepanno/annotations"
               + desc.substring(desc.lastIndexOf(DescriptorUtils.DESCRIPTOR_PACKAGE_SEPARATOR));
       println("private static final String DESCRIPTOR = " + quote(desc) + ";");
+      if (REPEATABLE_ANNOTATIONS.contains(clazz)) {
+        String desc_container = desc.substring(0, desc.length() - 1) + "$Container;";
+        println(
+            "private static final String DESCRIPTOR_CONTAINER = " + quote(desc_container) + ";");
+      }
       println("private static final String DESCRIPTOR_LEGACY = " + quote(desc_legacy) + ";");
       println("public static boolean isDescriptor(String descriptor) {");
       println("  return DESCRIPTOR.equals(descriptor) || DESCRIPTOR_LEGACY.equals(descriptor);");
       println("}");
+      if (REPEATABLE_ANNOTATIONS.contains(clazz)) {
+        println("public static boolean isKotlinRepeatableContainerDescriptor(String descriptor) {");
+        println("  return DESCRIPTOR_CONTAINER.equals(descriptor);");
+        println("}");
+      }
       println("public static String getDescriptor() {");
       println("  return DESCRIPTOR;");
       println("}");
@@ -2044,6 +2380,57 @@
       println();
     }
 
+    private void forEachUsesReflectionToConstructGroup(Consumer<Group> fn) {
+      fn.accept(createAndroidXClassSelection(g -> {}, g -> {}));
+      fn.accept(createAndroidXParameterSelection(g -> {}, g -> {}));
+    }
+
+    private void forEachUsesReflectionToAccessMethodGroup(Consumer<Group> fn) {
+      fn.accept(createAndroidXClassSelection(g -> {}, g -> {}));
+      fn.accept(createMethodNameSelection());
+      fn.accept(createAndroidXParameterSelection(g -> {}, g -> {}));
+      fn.accept(createAndroidXReturnTypeSelection());
+    }
+
+    private void forEachUsesReflectionToAccessFieldGroup(Consumer<Group> fn) {
+      fn.accept(createAndroidXClassSelection(g -> {}, g -> {}));
+      fn.accept(createAndroidXFieldNameSelection());
+      fn.accept(createAndroidXFieldTypeSelection());
+    }
+
+    private void generateUsesReflectionToConstructConstants() {
+      println("public static final class UsesReflectionToConstruct {");
+      withIndent(
+          () -> {
+            generateAnnotationConstants(USES_REFLECTION_TO_CONSTRUCT);
+            forEachUsesReflectionToConstructGroup(g -> g.generateConstants(this));
+          });
+      println("}");
+      println();
+    }
+
+    private void generateUsesReflectionToAccessMethodConstants() {
+      println("public static final class UsesReflectionToAccessMethod {");
+      withIndent(
+          () -> {
+            generateAnnotationConstants(USES_REFLECTION_TO_ACCESS_METHOD);
+            forEachUsesReflectionToConstructGroup(g -> g.generateConstants(this));
+          });
+      println("}");
+      println();
+    }
+
+    private void generateUsesReflectionToAccessFieldConstants() {
+      println("public static final class UsesReflectionToAccessField {");
+      withIndent(
+          () -> {
+            generateAnnotationConstants(USES_REFLECTION_TO_ACCESS_FIELD);
+            forEachUsesReflectionToConstructGroup(g -> g.generateConstants(this));
+          });
+      println("}");
+      println();
+    }
+
     private List<Group> getItemGroups() {
       return ImmutableList.of(
           // Bindings.
@@ -2440,6 +2827,26 @@
                 generator.generateUsedByX("UsedByNative", "accessed from native code via JNI"),
             write);
       }
+      writeFile(
+          ANDROIDX_ANNO_PKG,
+          generator -> generator.USES_REFLECTION_TO_CONSTRUCT,
+          Generator::generateUsesReflectionToConstruct,
+          write);
+      writeFile(
+          ANDROIDX_ANNO_PKG,
+          generator -> generator.USES_REFLECTION_TO_ACCESS_METHOD,
+          Generator::generateUsesReflectionToAccessMethod,
+          write);
+      writeFile(
+          ANDROIDX_ANNO_PKG,
+          generator -> generator.USES_REFLECTION_TO_ACCESS_FIELD,
+          Generator::generateUsesReflectionToAccessField,
+          write);
+      writeFile(
+          ANDROIDX_ANNO_PKG,
+          generator -> generator.UNCONDITIONALLY_KEEP,
+          Generator::generateUnconditionallyKeep,
+          write);
     }
   }
 }