Top Description Inners Fields Constructors Methods
com.google.auto.common

public abstract Class BasicAnnotationProcessor

extends AbstractProcessor
Class Inheritance
Static Imports
com.google.auto.common.MoreElements.asExecutable, .MoreElements.asPackage, .MoreElements.isAnnotationPresent, .MoreStreams.toImmutableMap, .MoreStreams.toImmutableSet, .SuperficialValidation.validateElement, com.google.common.base.Preconditions.checkNotNull, .Preconditions.checkState, com.google.common.collect.Iterables.transform, .Multimaps.filterKeys, java.util.Objects.requireNonNull, javax.lang.model.element.ElementKind.PACKAGE, javax.tools.Diagnostic.Kind.ERROR

An abstract Processor implementation that defers processing of Elements to later rounds if they cannot be processed.

Subclasses put their processing logic in Step implementations. The steps are passed to the processor by returning them in the steps() method, and can access the ProcessingEnvironment using 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 Step. 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 Step can defer elements

Each Step can defer elements by including them in the set returned by Step#process(ImmutableSetMultimap); 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.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
BasicAnnotationProcessor.ElementName

A package or type name.

public static interface
BasicAnnotationProcessor.ProcessingStep

Deprecated Implement Step instead.
The unit of processing logic that runs under the guarantee that all elements are complete and well-formed.
private static class
public static interface
BasicAnnotationProcessor.Step

The unit of processing logic that runs under the guarantee that all elements are complete and well-formed.

Field Summary

Modifier and TypeField and Description
private final Set<BasicAnnotationProcessor.ElementName>
private Elements
private final SetMultimap<BasicAnnotationProcessor.Step, BasicAnnotationProcessor.ElementName>
private Messager
private ImmutableList<? extends BasicAnnotationProcessor.Step>
Inherited from javax.annotation.processing.AbstractProcessor:
processingEnv

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
protected static BasicAnnotationProcessor.Step
asStep(BasicAnnotationProcessor.ProcessingStep processingStep)

Deprecated as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated.
Wraps the passed ProcessingStep in a Step.
private static void
findAnnotatedElements(Element element, ImmutableSet<TypeElement> annotationTypes, ImmutableSetMultimap.Builder<TypeElement, Element> annotatedElements)

Adds element and its enclosed elements to annotatedElements if they are annotated with any annotations in annotationTypes.

private static TypeElement
getEnclosingType(Element element)

Returns the nearest enclosing TypeElement to the current element, throwing an IllegalArgumentException if the provided Element is a PackageElement or is otherwise not enclosed by a type.

private ImmutableSet<TypeElement>
private ImmutableSet<TypeElement>
public final ImmutableSet<String>
private ImmutableSetMultimap<TypeElement, Element>
public final synchronized void
init(ProcessingEnvironment
environment to access facilities the tool framework provides to the processor
processingEnv
)

Overrides javax.annotation.processing.AbstractProcessor.init.

Implements javax.annotation.processing.Processor.init.

Initializes the processor with the processing environment by setting the processingEnv field to the value of the processingEnv argument.
protected Iterable<? extends BasicAnnotationProcessor.ProcessingStep>
initSteps()

Deprecated Implement steps() instead.
Creates processing steps for this processor.
protected void
postProcess()

Deprecated use postRound(RoundEnvironment) instead
An optional hook for logic to be executed at the end of each round.
protected void
postRound(RoundEnvironment roundEnv)

An optional hook for logic to be executed at the end of each round.

public final boolean
process(Set<? extends TypeElement>
the annotation interfaces requested to be processed
annotations
,
RoundEnvironment
environment for information about the current and prior round
roundEnv
)

Implements abstract javax.annotation.processing.AbstractProcessor.process.

Implements javax.annotation.processing.Processor.process.

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.
private void
process(ImmutableSetMultimap<TypeElement, Element> validElements)

Processes the valid elements, including those previously deferred by each step.

private String
private void
protected Iterable<? extends BasicAnnotationProcessor.Step>
steps()

Creates processing steps for this processor.

private static ImmutableSetMultimap<String, Element>
private ImmutableSetMultimap<TypeElement, Element>
validElements(RoundEnvironment roundEnv)

Returns the valid annotated elements contained in all of the deferred elements.

Inherited from javax.annotation.processing.AbstractProcessor:
getCompletionsgetSupportedOptionsgetSupportedSourceVersionisInitialized

Field Detail

deferredElementNamesback to summary
private final Set<BasicAnnotationProcessor.ElementName> deferredElementNames
elementsback to summary
private Elements elements
elementsDeferredByStepsback to summary
private final SetMultimap<BasicAnnotationProcessor.Step, BasicAnnotationProcessor.ElementName> elementsDeferredBySteps
messagerback to summary
private Messager messager
stepsback to summary
private ImmutableList<? extends BasicAnnotationProcessor.Step> steps

Constructor Detail

BasicAnnotationProcessorback to summary
public BasicAnnotationProcessor()

Method Detail

asStepback to summary
protected static BasicAnnotationProcessor.Step asStep(BasicAnnotationProcessor.ProcessingStep processingStep)

Deprecated

as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated. See corresponding docs for further information.

Wraps the passed ProcessingStep in a Step. This is a convenience method to allow incremental migration to a String-based API. This method can be used to return a not yet converted ProcessingStep from BasicAnnotationProcessor#steps().

findAnnotatedElementsback to summary
private static void findAnnotatedElements(Element element, ImmutableSet<TypeElement> annotationTypes, ImmutableSetMultimap.Builder<TypeElement, Element> annotatedElements)

Adds element and its enclosed elements to annotatedElements if they are annotated with any annotations in annotationTypes. Does not traverse to member types of element, so that if Outer is passed in the example below, looking for @X, then Outer, Outer.foo, and Outer.foo() will be added to the multimap, but neither Inner nor its members will.


  @X class Outer {
    @X Object foo;
    @X void foo() {}
    @X static class Inner {
      @X Object bar;
      @X void bar() {}
    }
  }
getEnclosingTypeback to summary
private static TypeElement getEnclosingType(Element element)

Returns the nearest enclosing TypeElement to the current element, throwing an IllegalArgumentException if the provided Element is a PackageElement or is otherwise not enclosed by a type.

getSupportedAnnotationTypeElementsback to summary
private ImmutableSet<TypeElement> getSupportedAnnotationTypeElements()
getSupportedAnnotationTypeElementsback to summary
private ImmutableSet<TypeElement> getSupportedAnnotationTypeElements(BasicAnnotationProcessor.Step step)
getSupportedAnnotationTypesback to summary
public final ImmutableSet<String> getSupportedAnnotationTypes()

Overrides javax.annotation.processing.AbstractProcessor.getSupportedAnnotationTypes.

Implements javax.annotation.processing.Processor.getSupportedAnnotationTypes.

Returns the set of supported annotation types as collected from registered processing steps.

Returns:ImmutableSet<String>

Doc from javax.annotation.processing.AbstractProcessor.getSupportedAnnotationTypes.

the names of the annotation interfaces supported by this processor, or an empty set if none

Annotations
@Override
indexByAnnotationback to summary
private ImmutableSetMultimap<TypeElement, Element> indexByAnnotation(Set<BasicAnnotationProcessor.ElementName> annotatedElements, ImmutableSet<TypeElement> annotationTypes)
initback to summary
public final synchronized void init(ProcessingEnvironment processingEnv)

Overrides javax.annotation.processing.AbstractProcessor.init.

Implements javax.annotation.processing.Processor.init.

Doc from javax.annotation.processing.AbstractProcessor.init.

Initializes the processor with the processing environment by setting the processingEnv field to the value of the processingEnv argument. An IllegalStateException will be thrown if this method is called more than once on the same object.

Parameters
processingEnv:ProcessingEnvironment

environment to access facilities the tool framework provides to the processor

Annotations
@Override
initStepsback to summary
protected Iterable<? extends BasicAnnotationProcessor.ProcessingStep> initSteps()

Deprecated

Implement steps() instead.

Creates processing steps for this processor. processingEnv is guaranteed to be set when this method is invoked.

Annotations
@Deprecated
postProcessback to summary
protected void postProcess()

Deprecated

use postRound(RoundEnvironment) instead

An optional hook for logic to be executed at the end of each round.

Annotations
@Deprecated
postRoundback to summary
protected void postRound(RoundEnvironment roundEnv)

An optional hook for logic to be executed at the end of each round.

processback to summary
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)

Implements abstract javax.annotation.processing.AbstractProcessor.process.

Implements javax.annotation.processing.Processor.process.

Doc from javax.annotation.processing.AbstractProcessor.process.

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 true is returned, the annotation interfaces are claimed and subsequent processors will not be asked to process them; if false is returned, the annotation interfaces are unclaimed and subsequent processors may be asked to process them. A processor may always return the same boolean value or may vary the result based on its own chosen criteria.

The input set will be empty if the processor supports "*" and the root elements have no annotations. A Processor must gracefully handle an empty set of annotations.

Parameters
annotations:Set<? extends TypeElement>

Doc from javax.annotation.processing.Processor.process.

the annotation interfaces requested to be processed

roundEnv:RoundEnvironment

Doc from javax.annotation.processing.Processor.process.

environment for information about the current and prior round

Returns:boolean

Doc from javax.annotation.processing.Processor.process.

whether or not the set of annotation interfaces are claimed by this processor

Annotations
@Override
processback to summary
private void process(ImmutableSetMultimap<TypeElement, Element> validElements)

Processes the valid elements, including those previously deferred by each step.

processingErrorMessageback to summary
private String processingErrorMessage(String target)
reportMissingElementsback to summary
private void reportMissingElements(Set<BasicAnnotationProcessor.ElementName> missingElementNames)
stepsback to summary
protected Iterable<? extends BasicAnnotationProcessor.Step> steps()

Creates processing steps for this processor. processingEnv is guaranteed to be set when this method is invoked.

Note

If you are migrating some steps from ProcessingStep to Step, then you can call asStep(ProcessingStep) on any unmigrated steps.

toClassNameKeyedMultimapback to summary
private static ImmutableSetMultimap<String, Element> toClassNameKeyedMultimap(SetMultimap<TypeElement, Element> elements)
validElementsback to summary
private ImmutableSetMultimap<TypeElement, Element> validElements(RoundEnvironment roundEnv)

Returns the valid annotated elements contained in all of the deferred elements. If none are found for a deferred element, defers it again.

com.google.auto.common back to summary

private final Class BasicAnnotationProcessor.ElementName

extends Object
Class Inheritance

A package or type name.

It's unfortunate that we have to track types and packages separately, but since there are two different methods to look them up in Elements, we end up with a lot of parallel logic. :(

Packages declared (and annotated) in package-info.java are tracked as deferred packages, type elements are tracked directly, and all other elements are tracked via their nearest enclosing type.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static enum

Field Summary

Modifier and TypeField and Description
private final BasicAnnotationProcessor.ElementName.Kind
private final String

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public boolean
equals(@Nullable Object
the reference object with which to compare.
object
)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.
pack-priv static BasicAnnotationProcessor.ElementName
forAnnotatedElement(Element element)

An ElementName for an annotated element.

pack-priv Optional<? extends Element>
getElement(Elements elements)

The Element whose fully-qualified name is name().

public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for the object.
pack-priv String
name()

The fully-qualified name of the element.

Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAlltoStringwaitwaitwait

Field Detail

kindback to summary
private final BasicAnnotationProcessor.ElementName.Kind kind
nameback to summary
private final String name

Constructor Detail

ElementNameback to summary
private ElementName(BasicAnnotationProcessor.ElementName.Kind kind, Name name)

Method Detail

equalsback to summary
public boolean equals(@Nullable Object object)

Overrides java.lang.Object.equals.

Doc from java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Parameters
object:@Nullable Object

the reference object with which to compare.

Returns:boolean

true if this object is the same as the obj argument; false otherwise.

Annotations
@Override
forAnnotatedElementback to summary
pack-priv static BasicAnnotationProcessor.ElementName forAnnotatedElement(Element element)

An ElementName for an annotated element. If element is a package, uses the fully qualified name of the package. If it's a type, uses its fully qualified name. Otherwise, uses the fully-qualified name of the nearest enclosing type.

A package can be annotated if it has a package-info.java with annotations on the package declaration.

getElementback to summary
pack-priv Optional<? extends Element> getElement(Elements elements)

The Element whose fully-qualified name is name(). Empty if the relevant method on Elements returns null.

hashCodeback to summary
public int hashCode()

Overrides java.lang.Object.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Returns:int

a hash code value for this object.

Annotations
@Override
nameback to summary
pack-priv String name()

The fully-qualified name of the element.

com.google.auto.common back to summary

private final Enum BasicAnnotationProcessor.ElementName.Kind

extends Enum<BasicAnnotationProcessor.ElementName.Kind>
Class Inheritance

Field Summary

Modifier and TypeField and Description
public static final BasicAnnotationProcessor.ElementName.Kind
public static final BasicAnnotationProcessor.ElementName.Kind

Constructor Summary

AccessConstructor and Description
private
Kind()

Field Detail

PACKAGE_NAMEback to summary
public static final BasicAnnotationProcessor.ElementName.Kind PACKAGE_NAME
TYPE_NAMEback to summary
public static final BasicAnnotationProcessor.ElementName.Kind TYPE_NAME

Constructor Detail

Kindback to summary
private Kind()

Method Detail

valueOfback to summary
public static BasicAnnotationProcessor.ElementName.Kind valueOf(String name)
valuesback to summary
public static BasicAnnotationProcessor.ElementName.Kind[] values()
com.google.auto.common back to summary

public Interface BasicAnnotationProcessor.ProcessingStep

Annotations
@Deprecated

Deprecated

Implement Step instead. See BasicAnnotationProcessor#steps().

The unit of processing logic that runs under the guarantee that all elements are complete and well-formed. A step may reject elements that are not ready for processing but may be at a later round.

Method Summary

Modifier and TypeMethod and Description
public Set<? extends Class<? extends Annotation>>
annotations()

The set of annotation types processed by this step.

public Set<? extends Element>

Returns:

the elements (a subset of the values of elementsByAnnotation) that this step is unable to process, possibly until a later processing round. These elements will be passed back to this step at the next round of processing.
process
(SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation)

The implementation of processing logic for the step.

Method Detail

annotationsback to summary
public Set<? extends Class<? extends Annotation>> annotations()

The set of annotation types processed by this step.

processback to summary
public Set<? extends Element> process(SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation)

The implementation of processing logic for the step. It is guaranteed that the keys in elementsByAnnotation will be a subset of the set returned by annotations().

Returns:Set<? extends Element>

the elements (a subset of the values of elementsByAnnotation) that this step is unable to process, possibly until a later processing round. These elements will be passed back to this step at the next round of processing.

com.google.auto.common back to summary

private Class BasicAnnotationProcessor.ProcessingStepAsStep

extends Object
implements Step
Class Inheritance
  • java.lang.Object
  • com.google.auto.common.BasicAnnotationProcessor.ProcessingStepAsStep
All Implemented Interfaces
com.google.auto.common.BasicAnnotationProcessor.Step

Field Summary

Modifier and TypeField and Description
private final ImmutableMap<String, Class<? extends Annotation>>
private final BasicAnnotationProcessor.ProcessingStep
processingStep

Deprecated as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated.

Constructor Summary

AccessConstructor and Description
pack-priv
ProcessingStepAsStep(BasicAnnotationProcessor.ProcessingStep processingStep)

Deprecated as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated.

Method Summary

Modifier and TypeMethod and Description
public Set<String>
annotations()

Implements com.google.auto.common.BasicAnnotationProcessor.Step.annotations.

The set of fully-qualified annotation type names processed by this step.
public Set<? extends Element>
process(ImmutableSetMultimap<String, Element> elementsByAnnotation)

Implements com.google.auto.common.BasicAnnotationProcessor.Step.process.

The implementation of processing logic for the step.
private ImmutableSetMultimap<Class<? extends Annotation>, Element>
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

annotationsByNameback to summary
private final ImmutableMap<String, Class<? extends Annotation>> annotationsByName
processingStepback to summary
private final BasicAnnotationProcessor.ProcessingStep processingStep

Deprecated

as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated. See corresponding docs for further information.

Constructor Detail

ProcessingStepAsStepback to summary
pack-priv ProcessingStepAsStep(BasicAnnotationProcessor.ProcessingStep processingStep)

Deprecated

as a consequence of BasicAnnotationProcessor.ProcessingStep being deprecated. See corresponding docs for further information.

Method Detail

annotationsback to summary
public Set<String> annotations()

Implements com.google.auto.common.BasicAnnotationProcessor.Step.annotations.

Doc from com.google.auto.common.BasicAnnotationProcessor.Step.annotations.

The set of fully-qualified annotation type names processed by this step.

Warning

If the returned names are not names of annotations, they'll be ignored.

Annotations
@Override
processback to summary
public Set<? extends Element> process(ImmutableSetMultimap<String, Element> elementsByAnnotation)

Implements com.google.auto.common.BasicAnnotationProcessor.Step.process.

Doc from com.google.auto.common.BasicAnnotationProcessor.Step.process.

The implementation of processing logic for the step. It is guaranteed that the keys in elementsByAnnotation will be a subset of the set returned by annotations().

Returns:Set<? extends Element>

the elements (a subset of the values of elementsByAnnotation) that this step is unable to process, possibly until a later processing round. These elements will be passed back to this step at the next round of processing.

Annotations
@Override
toClassKeyedMultimapback to summary
private ImmutableSetMultimap<Class<? extends Annotation>, Element> toClassKeyedMultimap(SetMultimap<String, Element> elements)
com.google.auto.common back to summary

public Interface BasicAnnotationProcessor.Step

Known Direct Implementers
com.google.auto.common.BasicAnnotationProcessor.ProcessingStepAsStep

The unit of processing logic that runs under the guarantee that all elements are complete and well-formed. A step may reject elements that are not ready for processing but may be at a later round.

Method Summary

Modifier and TypeMethod and Description
public Set<String>
annotations()

The set of fully-qualified annotation type names processed by this step.

public Set<? extends Element>

Returns:

the elements (a subset of the values of elementsByAnnotation) that this step is unable to process, possibly until a later processing round. These elements will be passed back to this step at the next round of processing.
process
(ImmutableSetMultimap<String, Element> elementsByAnnotation)

The implementation of processing logic for the step.

Method Detail

annotationsback to summary
public Set<String> annotations()

The set of fully-qualified annotation type names processed by this step.

Warning

If the returned names are not names of annotations, they'll be ignored.

processback to summary
public Set<? extends Element> process(ImmutableSetMultimap<String, Element> elementsByAnnotation)

The implementation of processing logic for the step. It is guaranteed that the keys in elementsByAnnotation will be a subset of the set returned by annotations().

Returns:Set<? extends Element>

the elements (a subset of the values of elementsByAnnotation) that this step is unable to process, possibly until a later processing round. These elements will be passed back to this step at the next round of processing.