Class BasicAnnotationProcessor
- java.lang.Object
-
- javax.annotation.processing.AbstractProcessor
-
- com.google.auto.common.BasicAnnotationProcessor
-
- All Implemented Interfaces:
javax.annotation.processing.Processor
public abstract class BasicAnnotationProcessor extends javax.annotation.processing.AbstractProcessorAn abstractProcessorimplementation that defers processing ofElements to later rounds if they cannot be processed.Subclasses put their processing logic in
BasicAnnotationProcessor.ProcessingStepimplementations. The steps are passed to the processor by returning them in theinitSteps()method, and can access theProcessingEnvironmentusingAbstractProcessor.processingEnv. Any logic that needs to happen once per round can be specified by overridingpostRound(RoundEnvironment).Ill-formed elements are deferred
Any annotated element whose nearest enclosing type is not well-formed is deferred, and not passed to anyProcessingStep. This helps processors to avoid many common pitfalls, such asErrorTypeinstances,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
BasicAnnotationProcessorwill 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
ProcessingStepcan defer elementsEach
ProcessingStepcan defer elements by including them in the set returned byBasicAnnotationProcessor.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
Acannot be processed because processing it depends on the existence of some classB, thenAshould be deferred until a later round of processing, whenBwill have been generated by another processor.If
Adirectly referencesB, then the well-formedness check will correctly defer processing ofAuntilBhas been generated.However, if
AreferencesBonly indirectly (for example, from within a method body), then the well-formedness check will not defer processingA, but a processing step can rejectA.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classBasicAnnotationProcessor.ElementNameA package or type name.static interfaceBasicAnnotationProcessor.ProcessingStepThe unit of processing logic that runs under the guarantee that all elements are complete and well-formed.
-
Field Summary
Fields Modifier and Type Field Description private java.util.Set<BasicAnnotationProcessor.ElementName>deferredElementNamesprivate javax.lang.model.util.Elementselementsprivate com.google.common.collect.SetMultimap<BasicAnnotationProcessor.ProcessingStep,BasicAnnotationProcessor.ElementName>elementsDeferredByStepsprivate javax.annotation.processing.Messagermessagerprivate com.google.common.collect.ImmutableList<? extends BasicAnnotationProcessor.ProcessingStep>steps
-
Constructor Summary
Constructors Constructor Description BasicAnnotationProcessor()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description private com.google.common.collect.ImmutableMap<java.lang.String,com.google.common.base.Optional<? extends javax.lang.model.element.Element>>deferredElements()Returns the previously deferred elements.private static voidfindAnnotatedElements(javax.lang.model.element.Element element, com.google.common.collect.ImmutableSet<? extends java.lang.Class<? extends java.lang.annotation.Annotation>> annotationClasses, com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> annotatedElements)Addselementand its enclosed elements toannotatedElementsif they are annotated with any annotations inannotationClasses.private static javax.lang.model.element.TypeElementgetEnclosingType(javax.lang.model.element.Element element)Returns the nearest enclosingTypeElementto the current element, throwing anIllegalArgumentExceptionif the providedElementis aPackageElementor is otherwise not enclosed by a type.private com.google.common.collect.ImmutableSet<? extends java.lang.Class<? extends java.lang.annotation.Annotation>>getSupportedAnnotationClasses()com.google.common.collect.ImmutableSet<java.lang.String>getSupportedAnnotationTypes()Returns the set of supported annotation types as a collected from registered processing steps.private com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element>indexByAnnotation(java.util.Set<BasicAnnotationProcessor.ElementName> annotatedElements)voidinit(javax.annotation.processing.ProcessingEnvironment processingEnv)protected abstract java.lang.Iterable<? extends BasicAnnotationProcessor.ProcessingStep>initSteps()Creates processing steps for this processor.protected voidpostProcess()Deprecated.usepostRound(RoundEnvironment)insteadprotected voidpostRound(javax.annotation.processing.RoundEnvironment roundEnv)An optional hook for logic to be executed at the end of each round.private voidprocess(com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> validElements)Processes the valid elements, including those previously deferred by each step.booleanprocess(java.util.Set<? extends javax.lang.model.element.TypeElement> annotations, javax.annotation.processing.RoundEnvironment roundEnv)private java.lang.StringprocessingErrorMessage(java.lang.String target)private voidreportMissingElements(java.util.Map<java.lang.String,? extends com.google.common.base.Optional<? extends javax.lang.model.element.Element>> missingElements, java.util.Collection<BasicAnnotationProcessor.ElementName> missingElementNames)private com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element>validElements(com.google.common.collect.ImmutableMap<java.lang.String,com.google.common.base.Optional<? extends javax.lang.model.element.Element>> deferredElements, javax.annotation.processing.RoundEnvironment roundEnv)Returns the valid annotated elements contained in all of the deferred elements.
-
-
-
Field Detail
-
deferredElementNames
private final java.util.Set<BasicAnnotationProcessor.ElementName> deferredElementNames
-
elementsDeferredBySteps
private final com.google.common.collect.SetMultimap<BasicAnnotationProcessor.ProcessingStep,BasicAnnotationProcessor.ElementName> elementsDeferredBySteps
-
elements
private javax.lang.model.util.Elements elements
-
messager
private javax.annotation.processing.Messager messager
-
steps
private com.google.common.collect.ImmutableList<? extends BasicAnnotationProcessor.ProcessingStep> steps
-
-
Method Detail
-
init
public final void init(javax.annotation.processing.ProcessingEnvironment processingEnv)
- Specified by:
initin interfacejavax.annotation.processing.Processor- Overrides:
initin classjavax.annotation.processing.AbstractProcessor
-
initSteps
protected abstract java.lang.Iterable<? extends BasicAnnotationProcessor.ProcessingStep> initSteps()
Creates processing steps for this processor.AbstractProcessor.processingEnvis guaranteed to be set when this method is invoked.
-
postProcess
@Deprecated protected void postProcess()
Deprecated.usepostRound(RoundEnvironment)insteadAn optional hook for logic to be executed at the end of each round.
-
postRound
protected void postRound(javax.annotation.processing.RoundEnvironment roundEnv)
An optional hook for logic to be executed at the end of each round.
-
getSupportedAnnotationClasses
private com.google.common.collect.ImmutableSet<? extends java.lang.Class<? extends java.lang.annotation.Annotation>> getSupportedAnnotationClasses()
-
getSupportedAnnotationTypes
public final com.google.common.collect.ImmutableSet<java.lang.String> getSupportedAnnotationTypes()
Returns the set of supported annotation types as a collected from registered processing steps.- Specified by:
getSupportedAnnotationTypesin interfacejavax.annotation.processing.Processor- Overrides:
getSupportedAnnotationTypesin classjavax.annotation.processing.AbstractProcessor
-
process
public final boolean process(java.util.Set<? extends javax.lang.model.element.TypeElement> annotations, javax.annotation.processing.RoundEnvironment roundEnv)- Specified by:
processin interfacejavax.annotation.processing.Processor- Specified by:
processin classjavax.annotation.processing.AbstractProcessor
-
deferredElements
private com.google.common.collect.ImmutableMap<java.lang.String,com.google.common.base.Optional<? extends javax.lang.model.element.Element>> deferredElements()
Returns the previously deferred elements.
-
reportMissingElements
private void reportMissingElements(java.util.Map<java.lang.String,? extends com.google.common.base.Optional<? extends javax.lang.model.element.Element>> missingElements, java.util.Collection<BasicAnnotationProcessor.ElementName> missingElementNames)
-
processingErrorMessage
private java.lang.String processingErrorMessage(java.lang.String target)
-
validElements
private com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> validElements(com.google.common.collect.ImmutableMap<java.lang.String,com.google.common.base.Optional<? extends javax.lang.model.element.Element>> deferredElements, javax.annotation.processing.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.
-
process
private void process(com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> validElements)
Processes the valid elements, including those previously deferred by each step.
-
indexByAnnotation
private com.google.common.collect.ImmutableSetMultimap<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> indexByAnnotation(java.util.Set<BasicAnnotationProcessor.ElementName> annotatedElements)
-
findAnnotatedElements
private static void findAnnotatedElements(javax.lang.model.element.Element element, com.google.common.collect.ImmutableSet<? extends java.lang.Class<? extends java.lang.annotation.Annotation>> annotationClasses, com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Class<? extends java.lang.annotation.Annotation>,javax.lang.model.element.Element> annotatedElements)Addselementand its enclosed elements toannotatedElementsif they are annotated with any annotations inannotationClasses. Does not traverse to member types ofelement, so that ifOuteris passed in the example below, looking for@X, thenOuter,Outer.foo, andOuter.foo()will be added to the multimap, but neitherInnernor its members will.@X class Outer { @X Object foo; @X void foo() {} @X static class Inner { @X Object bar; @X void bar() {} } }
-
getEnclosingType
private static javax.lang.model.element.TypeElement getEnclosingType(javax.lang.model.element.Element element)
Returns the nearest enclosingTypeElementto the current element, throwing anIllegalArgumentExceptionif the providedElementis aPackageElementor is otherwise not enclosed by a type.
-
-