1## Annotations {#annotation}
2
3### Annotation processors {#annotation-processor}
4
5Annotation processors should opt-in to incremental annotation processing to
6avoid triggering a full recompilation on every client source code change. See
7Gradle's
8[Incremental annotation processing](https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing)
9documentation for information on how to opt-in.
10
11### `@RequiresOptIn` APIs {#experimental-api}
12
13Jetpack libraries may choose to annotate API surfaces as unstable using either
14Kotlin's
15[`@RequiresOptIn` meta-annotation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-requires-opt-in/)
16for APIs written in Kotlin or Jetpack's
17[`@RequiresOptIn` meta-annotation](https://developer.android.com/reference/kotlin/androidx/annotation/RequiresOptIn)
18for APIs written in Java.
19
20> `@RequiresOptIn` at-a-glance:
21>
22> *   Use for unstable API surfaces
23> *   Can be called by anyone
24> *   Documented in public documentation
25> *   Does not maintain compatibility
26
27For either annotation, API surfaces marked as opt-in are considered alpha and
28will be excluded from API compatibility guarantees. Due to the lack of
29compatibility guarantees, stable libraries *must never* call experimental APIs
30exposed by other libraries outside of their
31[same-version group](#same-version-atomic-groups) and *may not* use the `@OptIn`
32annotation except in the following cases:
33
34*   A library within a same-version group *may* call an experimental API exposed
35    by another library **within its same-version group**. In this case, API
36    compatibility guarantees are covered under the same-version group policies
37    and the library *may* use the `@OptIn` annotation to prevent propagation of
38    the experimental property. **Library owners must exercise care to ensure
39    that post-alpha APIs backed by experimental APIs actually meet the release
40    criteria for post-alpha APIs.**
41*   An `alpha` library may use experimental APIs from outside its same-version
42    group. These usages must be removed when the library moves to `beta`.
43
44NOTE JetBrains's own usage of `@RequiresOptIn` in Kotlin language libraries
45varies and may indicate binary instability, functional instability, or simply
46that an API is really difficult to use. Jetpack libraries should treat instances
47of `@RequiresOptIn` in JetBrains libraries as indicating **binary instability**
48and avoid using them outside of `alpha`; however, teams are welcome to obtain
49written assurance from JetBrains regarding binary stability of specific APIs.
50`@RequiresOptIn` APIs that are guaranteed to remain binary compatible *may* be
51used in `beta`, but usages must be removed when the library moves to `rc`.
52
53#### When to mark an API surface as experimental
54
55*Do not* use `@RequiresOptIn` for a stable API surface that is difficult to use.
56It is not a substitute for a properly-designed API surface.
57
58*Do not* use `@RequiresOptIn` for an API surface that is unreliable or unstable
59because it is missing tests. It is not a substitute for a properly-tested API
60surface, and all APIs -- including those in `alpha` -- are expected to be
61functionally stable.
62
63*Do not* use `@RequiresOptIn` for an internal-facing API surface. Use either the
64appropriate language visibility (ex. `private` or `internal`) or `@RestrictTo`.
65
66*Do not* use `@RequiresOptIn` for an API that you expect library developers to
67call. Experimental APIs do not maintain binary compatibility guarantees, and you
68will put external clients in a difficult situation.
69
70*Do* use `@RequiresOptIn` for API surfaces that must be publicly available and
71documented but need the flexibility to stay in `alpha` during the rest of the
72library's `beta`, `rc`, or stable cycles, and continue to break compatibility in
73`beta`.
74
75#### How to mark an API surface as experimental
76
77All libraries using `@RequiresOptIn` annotations *must* depend on the
78`androidx.annotation:annotation-experimental` artifact regardless of whether
79they are using the `androidx` or Kotlin annotation. This artifact provides Lint
80enforcement of experimental usage restrictions for Kotlin callers as well as
81Java (which the Kotlin annotation doesn't handle on its own, since it's a Kotlin
82compiler feature). Libraries *may* include the dependency as `api`-type to make
83`@OptIn` available to Java clients; however, this will also unnecessarily expose
84the `@RequiresOptIn` annotation.
85
86```java
87dependencies {
88    implementation(project(":annotation:annotation-experimental"))
89}
90```
91
92See Kotlin's
93[opt-in requirements documentation](https://kotlinlang.org/docs/reference/opt-in-requirements.html)
94for general usage information. If you are writing experimental Java APIs, you
95will use the Jetpack
96[`@RequiresOptIn` annotation](https://developer.android.com/reference/kotlin/androidx/annotation/RequiresOptIn)
97rather than the Kotlin compiler's annotation.
98
99#### How to transition an API out of experimental
100
101When an API surface is ready to transition out of experimental, the annotation
102may only be removed during an alpha pre-release stage. Removing the experimental
103marker from an API is equivalent to adding the API to the current API surface.
104
105When transitioning an entire feature surface out of experimental, you *should*
106remove the definition for the associated experimental marker annotation.
107
108When making any change to the experimental API surface, you *must* run
109`./gradlew updateApi` prior to uploading your change.
110
111NOTE Experimental marker annotation *are themselves* experimental, meaning that
112it's considered binary compatible to refactor or remove an experimental marker
113annotation.
114
115Note: Experimental APIs are reviewed by API Council both when the APIs are first
116introduced, and when they are stabilized. API Council may have additional
117feedback during stabilization.
118
119### `@RestrictTo` APIs {#restricted-api}
120
121Jetpack's library tooling supports hiding JVM-visible (ex. `public` and
122`protected`) APIs from developers using a combination of the `@RestrictTo`
123source annotation.
124
125> `@RestrictTo` at-a-glance:
126>
127> *   Use for internal-facing API surfaces
128> *   Can be called within the specified `Scope`
129> *   Does not appear in public documentation
130> *   Does not maintain compatibility in most scopes
131
132While restricted APIs do not appear in documentation and Android Studio will
133warn against calling them, hiding an API does *not* provide strong guarantees
134about usage:
135
136*   There are no runtime restrictions on calling hidden APIs
137*   Android Studio will not warn if hidden APIs are called using reflection
138*   Hidden APIs will still show in Android Studio's auto-complete
139
140These annotations indicate that developers should not call an API that is
141*technically* public from a JVM visibility perspective. Hiding APIs is often a
142sign of a poorly-abstracted API surface, and priority should be given to
143creating public, maintainable APIs and using Java visibility modifiers.
144
145*Do not* use `@RestrictTo` to bypass API tracking and review for production
146APIs; instead, rely on API+1 and API Council review to ensure APIs are reviewed
147on a timely basis.
148
149*Do not* use `@RestrictTo` for implementation detail APIs that are used between
150libraries and could reasonably be made public.
151
152*Do* use `@RestrictTo(LIBRARY)` for implementation detail APIs used within a
153single library (but prefer Java language `private` or `default` visibility).
154
155#### `RestrictTo.Scope` and inter- versus intra-library API surfaces {#private-api-types}
156
157To maintain binary compatibility between different versions of libraries,
158restricted API surfaces that are used between libraries within Jetpack
159(inter-library APIs) must follow the same Semantic Versioning rules as public
160APIs. Inter-library APIs should be annotated with the
161`@RestrictTo(LIBRARY_GROUP)` source annotation.
162
163Restricted API surfaces used within a single library (intra-library APIs), on
164the other hand, may be added or removed without any compatibility
165considerations. It is safe to assume that developers *never* call these APIs,
166even though it is technically feasible. Intra-library APIs should be annotated
167with the `@RestrictTo(LIBRARY)` source annotation.
168
169In all cases, correctness and compatibility tracking are handled by AndroidX's
170build system and lint checks.
171
172The following table shows the visibility of a hypothetical API within Maven
173coordinate `androidx.concurrent:concurrent` when annotated with a variety of
174scopes:
175
176<table>
177    <tr>
178        <td><code>RestrictTo.Scope</code></td>
179        <td>Visibility by Maven coordinate</td>
180        <td>Versioning</td>
181        <td>Note</td>
182    </tr>
183    <tr>
184        <td><code>LIBRARY</code></td>
185        <td><code>androidx.concurrent:concurrent</code></td>
186        <td>No compatibility guarantees (same as private)</td>
187        <td></td>
188    </tr>
189    <tr>
190        <td><code>LIBRARY_GROUP</code></td>
191        <td><code>androidx.concurrent:*</code></td>
192        <td>Semantic versioning (including deprecation)</td>
193        <td></td>
194    </tr>
195    <tr>
196        <td><code>LIBRARY_GROUP_PREFIX</code></td>
197        <td><code>androidx.*:*</code></td>
198        <td>Semantic versioning (including deprecation)</td>
199        <td></td>
200    </tr>
201    <tr>
202        <td><code>TEST</code></td>
203        <td><code>*</code></td>
204        <td>No compatibility guarantees (same as private)</td>
205        <td>Not allowed in Jetpack, use `@VisibleForTesting`</td>
206    </tr>
207</table>
208
209#### Test APIs and `@VisibleForTesting`
210
211For library APIs that should only be used from test code -- including the
212library's own tests, integration test apps, app developers' tests, or
213third-party testing libraries -- use the `@VisibleForTesting` annotation to
214ensure that the API is only called from test source sets.
215
216Libraries targeted at multi-platform usage in IntelliJ may use `@TestOnly` to
217ensure that the IDE enforces usage restrictions.
218
219Jetpack prefers that libraries expose test APIs as public API and maintain
220binary compatibility. This ensures that whatever a library needs in its own
221integration test app is available to app developers and may be safely called in
222third-party testing libraries.
223
224In cases where a test API needs restricted visibility or flexibility around
225binary compatibility, the `@VisibleForTesting` annotation may be combined with a
226`@RestrictTo` scope or `@RequiresOptIn` feature group.
227
228#### `@IntDef` `@StringDef` and `@LongDef` and visibility
229
230All `@IntDef`, `@StringDef`, and `@LongDef` will be stripped from resulting
231artifacts to avoid issues where compiler inlining constants removes information
232as to which `@IntDef` defined the value of `1`. The annotations are extracted
233and packaged separately to be read by Android Studio and lint which enforces the
234types in application code.
235
236*   Libraries *must* `@RestrictTo` all `@IntDef`, `@StringDef`, and `@LongDef`
237    declarations to create a warning when the type is used incorrectly.
238*   Libraries *must* expose constants used to define the `@IntDef` etc at the
239    same Java visibility as the hidden `@IntDef`
240
241Here is a complete example of an `@IntDef`
242
243```java
244// constants match Java visibility of ExifStreamType
245// code outside this module interacting with ExifStreamType uses these constants
246public static final int STREAM_TYPE_FULL_IMAGE_DATA = 1;
247public static final int STREAM_TYPE_EXIF_DATA_ONLY = 2;
248
249@RestrictTo(RestrictTo.Scope.LIBRARY) // Don't export ExifStreamType outside module
250@Retention(RetentionPolicy.SOURCE)
251@IntDef({
252  STREAM_TYPE_FULL_IMAGE_DATA,
253  STREAM_TYPE_EXIF_DATA_ONLY,
254})
255public @interface ExifStreamType {}
256```
257
258Java visibility should be set as appropriate for the code in question
259(`private`, `package`, or `public`) and is unrelated to hiding.
260
261For more, read the section in
262[Android API Council Guidelines](https://android.googlesource.com/platform/developers/docs/+/refs/heads/main/api-guidelines/framework.md#framework-hide-typedefs)
263
264#### `*current.txt` File Explanation {#currenttxt}
265
266In this example, `1.3.0-beta02.txt` is just used for an example. This will match
267the current library version.
268
269<table>
270    <tr>
271        <td><code>api/current.txt</code></td>
272        <td>All public APIs.</td>
273    </tr>
274    <tr>
275        <td><code>api/1.3.0-beta02.txt</code></td>
276        <td>All public APIs available in version <code>1.3.0-beta02</code>.
277        Used to enforce compatibility in later versions.  This file is only
278        generated during Beta.</td>
279    </tr>
280    <tr>
281        <td><code>api/public_plus_experimental_current.txt </code></td>
282        <td>Superset of all public APIs (<code>api/current.txt</code>) and all
283        experimental/<code>RequiresOptIn</code> APIs.
284        </td>
285    </tr>
286    <tr>
287        <td><code>api/public_plus_experimental_1.3.0-beta03.txt</code></td>
288        <td>Superset of all public APIs (<code>api/1.3.0-beta02.txt.txt</code>) and all
289        experimental/RequiresOptIn APIs, as available in version
290        <code>1.3.0-beta02.txt</code>.  Only generated during Beta.</td>
291    <tr>
292        <td><code>api/restricted_current.txt</code></td>
293        <td>Superset of all public APIs (<code>api/current.txt</code>) and
294        all <code>RestrictTo</code> APIs that require compatibility across
295        versions.
296        <p/>Specifically, includes <code>@RestrictTo(LIBRARY_GROUP)</code>
297        (for non-atomically versioned groups) and
298        <code>@RestrictTo(LIBRARY_GROUP_PREFIX)</code> (for all libraries).</td>
299    </tr>
300    <tr>
301        <td><code>api/restricted_1.3.0-beta02.txt.txt</code></td>
302        <td>Superset of all public APIs (<code>api/current.txt</code>) and
303        all <code>RestrictTo</code> APIs that require compatibility across
304        versions, as available in version <code>1.3.0-beta02.txt</code>.
305        <p/>
306        Specifically, includes <code>@RestrictTo(LIBRARY_GROUP)</code>
307        (for non-atomically versioned groups) and
308        <code>@RestrictTo(LIBRARY_GROUP_PREFIX)</code> (for all libraries).
309        This file is only generated during Beta.</td>
310    </tr>
311</table>
312