Annotation processing happens in a sequence of rounds. On each round, a processor may be asked to process a subset of the annotations found on the source and class files produced by a prior round. The inputs to the first round of processing are the initial inputs to a run of the tool; these initial inputs can be regarded as the output of a virtual zeroth round of processing. If a processor was asked to process on a given round, it will be asked to process on subsequent rounds, including the last round, even if there are no annotations for it to process. The tool infrastructure may also ask a processor to process files generated implicitly by the tool's operation.
Each implementation of a Processor must provide a
public no-argument constructor to be used by tools to instantiate
the processor. The tool infrastructure will interact with classes
implementing this interface as follows:
Processor object is not being used, to
create an instance of a processor the tool calls the no-arg
constructor of the processor class.
init method with
an appropriate ProcessingEnvironment.
getSupportedAnnotationTypes, getSupportedOptions, and getSupportedSourceVersion. These methods are only called once per
run, not on each round.
process
method on the Processor object; a new Processor
object is not created for each round.
The tool uses a discovery process to find annotation
processors and decide whether or not they should be run. By
configuring the tool, the set of potential processors can be
controlled. For example, for a JavaCompiler the list of candidate processors to run can be
set directly or controlled by a search path
used for a service-style
lookup. Other tool implementations may have different
configuration mechanisms, such as command line options; for
details, refer to the particular tool's documentation. Which
processors the tool asks to run is a function
of the interfaces of the annotations present on the root elements, what annotation interfaces a processor
supports, and whether or not a processor claims the annotation interfaces it processes. A processor will
be asked to process a subset of the annotation interfaces it
supports, possibly an empty set.
For a given round, the tool computes the set of annotation
interfaces that are present on the elements included
within the root elements. If there is at least one annotation
interface present, then as processors claim annotation interfaces,
they are removed from the set of unmatched annotation interfaces.
When the set is empty or no more processors are available, the
round has run to completion. If there are no annotation interfaces
present, annotation processing still occurs but only universal
processors which support processing all annotation interfaces,
"*", can claim the (empty) set of annotation interfaces.
An annotation interface is considered present if there is at least
one annotation of that interface present on an element included within
the root elements of a round. For this purpose, a type parameter is
considered to be included by its generic
element.
For this purpose, a package element is not considered to
include the top-level classes and interfaces within that
package. (A root element representing a package is created when a
package-info file is processed.) Likewise, for this
purpose, a module element is not considered to include the
packages within that module. (A root element representing a module
is created when a module-info file is processed.)
Annotations on type uses, as opposed to
annotations on elements, are ignored when computing whether or not
an annotation interface is present.
An annotation is present if it meets the definition of being
present given in AnnotatedConstruct. In brief, an
annotation is considered present for the purposes of discovery if
it is directly present or present via inheritance. An annotation is
not considered present by virtue of being wrapped by a
container annotation. Operationally, this is equivalent to an
annotation being present on an element if and only if it would be
included in the results of Elements#getAllAnnotationMirrors(Element) called on that element. Since
annotations inside container annotations are not considered
present, to properly process repeatable annotation interfaces,
processors are advised to include both the repeatable annotation
interface and its containing annotation interface in the set of supported annotation interfaces of a
processor.
Note that if a processor supports "*" and returns true, all annotations are claimed. Therefore, a universal
processor being used to, for example, implement additional validity
checks should return false so as to not prevent other such
checkers from being able to run.
If a processor throws an uncaught exception, the tool may cease other active annotation processors. If a processor raises an error, the current round will run to completion and the subsequent round will indicate an error was raised. Since annotation processors are run in a cooperative environment, a processor should throw an uncaught exception only in situations where no error recovery or reporting is feasible.
The tool environment is not required to support annotation processors that access environmental resources, either per round or cross-round, in a multi-threaded fashion.
If the methods that return configuration information about the
annotation processor return null, return other invalid
input, or throw an exception, the tool infrastructure must treat
this as an error condition.
To be robust when running in different tool implementations, an annotation processor should have the following properties:
The Filer interface discusses restrictions on how
processors can operate on files.
API Note
Implementors of this interface may find it convenient
to extend AbstractProcessor rather than implementing this
interface directly.
| Modifier and Type | Method and Description |
|---|---|
| public Iterable | Returns: suggested completions to the annotationthe element being annotated element, AnnotationMirror the (perhaps partial) annotation being
applied to the element annotation, ExecutableElement the annotation member to return possible completions for member, String source code text to be completed userText)Returns to the tool infrastructure an iterable of suggested completions to an annotation. |
| public Set | Returns: the names of the annotation interfaces supported by this processor or an empty set if noneReturns the names of the annotation interfaces supported by this processor. |
| public Set | Returns: the options recognized by this processor or an empty set if noneReturns the options recognized by this processor. |
| public SourceVersion | Returns: the latest source version supported by this annotation processorReturns the latest source version supported by this annotation processor. |
| public void | init(ProcessingEnvironment
environment for facilities the tool framework
provides to the processor processingEnv)Initializes the processor with the processing environment. |
| public boolean | Returns: whether or not the set of annotation interfaces are claimed by this processorthe annotation interfaces requested to be processed annotations, RoundEnvironment environment for information about the current and prior round roundEnv)Processes a set of annotation interfaces on root elements originating from the prior round and returns whether or not these annotation interfaces are claimed by this processor. |
| getCompletions | back to summary |
|---|---|
| public Iterable Returns to the tool infrastructure an iterable of suggested
completions to an annotation. Since completions are being asked
for, the information provided about the annotation may be
incomplete, as if for a source code fragment. A processor may
return an empty iterable. Annotation processors should focus
their efforts on providing completions for annotation members
with additional validity constraints known to the processor, for
example an Since incomplete programs are being modeled, some of the
parameters may only have partial information or may be Completions are informative and may reflect additional validity checks performed by annotation processors. For example, consider the simple annotation:
(A Mersenne prime is prime number of the form
2n - 1.) Given an AnnotationMirror
for this annotation interface, a list of all such primes in the
int range could be returned without examining any other
arguments to getCompletions:
A more informative set of completions would include the number of each prime:import static javax.annotation.processing.Completions.*; ... return List.of( However, if thereturn List.of( userText is available, it can be checked
to see if only a subset of the Mersenne primes are valid. For
example, if the user has typed
the value of userText will be "1"; and only
two of the primes are possible completions:
Sometimes no valid completion is possible. For example, there
is no in-range Mersenne prime starting with 9:
An appropriate response in this case is to either return an
empty list of completions,
or a single empty completion with a helpful messagereturn Collections.emptyList();
| |
| getSupportedAnnotationTypes | back to summary |
|---|---|
| public Set Returns the names of the annotation interfaces supported by this
processor. An element of the result may be the canonical
(fully qualified) name of a supported annotation interface.
Alternately it may be of the form " Each string returned in the set must be accepted by the following grammar: where TypeName and ModuleName are as defined in The Java Language Specification (6.5 Determining the Meaning of a Name). API Note When running in an environment which supports modules,
processors are encouraged to include the module prefix when
describing their supported annotation interfaces. The method
| |
| getSupportedOptions | back to summary |
|---|---|
| public Set Returns the options recognized by this processor. An
implementation of the processing tool must provide a way to
pass processor-specific options distinctly from options passed
to the tool itself, see Each string returned in the set must be a period separated sequence of identifiers:
A tool might use this information to determine if any options provided by a user are unrecognized by any processor, in which case it may wish to report a warning.
| |
| getSupportedSourceVersion | back to summary |
|---|---|
| public SourceVersion getSupportedSourceVersion() Returns the latest source version supported by this annotation processor.
| |
| init | back to summary |
|---|---|
| public void init(ProcessingEnvironment processingEnv) Initializes the processor with the processing environment.
| |
| process | back to summary |
|---|---|
| public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) Processes a set of annotation interfaces on root elements originating
from the prior round and returns whether or not these
annotation interfaces are claimed by this processor. If The input set will be empty if the processor supports
| |