Class BasicAnnotationProcessor

java.lang.Object
javax.annotation.processing.AbstractProcessor
com.google.auto.common.BasicAnnotationProcessor
All Implemented Interfaces:
Processor

public abstract class BasicAnnotationProcessor extends AbstractProcessor
An abstract Processor implementation that defers processing of Elements to later rounds if they cannot be processed.

Subclasses put their processing logic in BasicAnnotationProcessor.ProcessingStep implementations. The steps are passed to the processor by returning them in the initSteps() method, and can access the ProcessingEnvironment using AbstractProcessor.processingEnv. Any logic that needs to happen once per round can be specified by overriding postRound(RoundEnvironment).

Ill-formed elements are deferred

Any annotated element whose nearest enclosing type is not well-formed is deferred, and not passed to any ProcessingStep. This helps processors to avoid many common pitfalls, such as ErrorType instances, ClassCastExceptions and badly coerced types.

A non-package element is considered well-formed if its type, type parameters, parameters, default values, supertypes, annotations, and enclosed elements are. Package elements are treated similarly, except that their enclosed elements are not validated. See SuperficialValidation.validateElement(Element) for details.

The primary disadvantage to this validation is that any element that forms a circular dependency with a type generated by another BasicAnnotationProcessor will never compile because the element will never be fully complete. All such compilations will fail with an error message on the offending type that describes the issue.

Each ProcessingStep can defer elements

Each ProcessingStep can defer elements by including them in the set returned by BasicAnnotationProcessor.ProcessingStep.process(SetMultimap); elements deferred by a step will be passed back to that step in a later round of processing.

This feature is useful when one processor may depend on code generated by another, independent processor, in a way that isn't caught by the well-formedness check described above. For example, if an element A cannot be processed because processing it depends on the existence of some class B, then A should be deferred until a later round of processing, when B will have been generated by another processor.

If A directly references B, then the well-formedness check will correctly defer processing of A until B has been generated.

However, if A references B only indirectly (for example, from within a method body), then the well-formedness check will not defer processing A, but a processing step can reject A.