summaryrefslogtreecommitdiff
path: root/javax/annotation/processing/Processor.java
blob: af790546c20e7b5c24173e01477155a33a4cfa56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/* Processor.java -- An annotation processor.
   Copyright (C) 2012  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.annotation.processing;

import java.util.Set;

import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;

/**
 * <p>Provides the interface for an annotation processor.</p>
 * <p>Annotation processing is divided into a series of rounds,
 * with the input for each round being a subset of the output
 * from the previous round.  The input for the initial round
 * are those provided to the tool by the user, but, for the
 * purposes of operation, can be thought of as coming from a
 * virtual preceding round, as the behaviour is the same.
 * Once a processor is asked to process inputs in a particular
 * round, it is asked to do so in all subsequent rounds, even
 * if there are no annotations left for it to process.  These
 * inputs can include files generated by the tool's operation.</p>
 * <p>Annotation processors are found using a tool-specific
 * discovery method which may involve them being named directly
 * or discovered via a service-based lookup.  The processors which
 * are actually used are determined by which of the annotations present
 * on the root elements are supported by the processor and whether or
 * not it claims them.  Claimed annotation types are removed from
 * the set of unmatched annotations and are not passed to other
 * processors.  A round is complete once the set is empty or no
 * more processors are available.  If there are no annotation types
 * on the root elements (i.e. the set is empty to begin with), then
 * only <emph>universal processors</emph> (those which accept {@code "*"})
 * are run.</p>
 * <h2>Implementing an Annotation Processor</h2>
 * <p>The tool infrastructure expects the following from an annotation
 * processor:</p>
 * <ol>
 * <li>It should be able to create an instance of the processor using
 * a no-argument constructor and use this same instance for the whole run.</li>
 * <li>Once it has created the instance, it calls {@code init} with
 * an appropriate {@link ProcessingEnvironment}.</li>
 * <li>The tool calls {@link #getSupportedAnnotationTypes},
 * {@link #getSupportedOptions} and {@link #getSupportedSourceVersion} once
 * at the start of each run.</li>
 * <li>The tool calls {@link #process} on the processor for each round.</li>
 * </ol>
 * <p>Use outside the above protocol is undefined.  A processor supporting
 * {@code "*"} and returning {@code true} from the {@code process} method
 * will claim all annotations and prevent other processors from running.
 * If this is not the intention, then {@code false} should be returned.</p>
 * <p>To work well with different tool implementations, the processor
 * should make sure the following properties hold:</p>
 * <ol>
 * <li><strong>Orthogonality</strong>: The result of processing an input
 * is not dependent on the presence or not of other inputs.</li>
 * <li><strong>Consistency</strong>: Processing the same input should
 * always produce the same output.</li>
 * <li><strong>Commutativity</strong>: Processing input A then input B
 * should be the same as processing input B then input A.</li>
 * <li><strong>Independence</strong>: The result of processing an input
 * is not dependent on the presence of output from other processors.</li>
 * </ol>
 * <p>If a processor raises an error, this will be noted and the round
 * completed.  The subsequent round can then query as to whether an
 * error was raised using {@link RoundEnvironment#errorRaised()}.  If
 * an uncaught exception is raised, the tool may cease the use of other
 * annotation processors, so this should be used only in situations where
 * the usual error recovery process is infeasible.</p>
 * <p>The tool environment need not support annotation processors accessing
 * environmental resources, either per round or cross-round, in a multi-threaded
 * environment.  If a method returns {@code null} or other invalid input, or throws
 * an exception, in response to a configuration query, the tool may treat this
 * as an error condition.</p>
 * <p>The {@link Filer} interface documentation provides more information on how
 * files are handled and the restrictions in place.  Implementators may find it
 * easier to base their implementation on the {@link AbstractProcessor} class
 * rather than implementing this interface directly.</p>
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.6
 */
public interface Processor
{

  /**
   * <p>Returns the names of the annotation types supported by this
   * processor.  These can take one of the following forms:</p>
   * <ol>
   * <li>A canonical fully-qualified type name.</li>
   * <li>A partial type name with the suffix {@code .*}</li>
   * <li>{@code .*}</li>
   * </ol>
   * <p>For example, {@code "gnu.classpath.annotations.ProcessMe"} matches
   * the specific annotation class, {@code ProcessMe}.  Alternatively,
   * {@code "gnu.classpath.annotations.*"} matches all annotations under
   * the package {@code gnu.classpath.annotations}.  Finally, {@code .*}
   * matches all annotations.</p>
   * <p>Processors should avoid claiming annotations they don't support,
   * as this may cause performance issues, and, if they also return
   * {@code true} when asked to {@link #process()} them, then they may
   * prevent other processors from handling those annotations.</p>
   *
   * @return the names of the supported annotation types.
   * @see SupportedAnnotationTypes
   */
  Set<String> getSupportedAnnotationTypes();

  /**
   * Returns the options supported by this tool.  Each string
   * returned by this method must be a period-separated sequence
   * of identifiers, as defined by
   * {@link SourceVersion#isIdentifier(CharSequence)}.
   * The tool may use this list to work out which options a user
   * provides are unsupported and print a warning.
   *
   * @return the names of the supported options or an empty set if none.
   * @see SupportedOptions
   */
  Set<String> getSupportedOptions();

  /**
   * Returns the latest source code version supported by this processor.
   *
   * @return the latest version supported.
   * @see SupportedSourceVersion
   * @see ProcessingEnvironment#getSourceVersion
   */
  SourceVersion getSupportedSourceVersion();

  /**
   * Initialises the processor with the specified environment.
   *
   * @param env the environment for the annotation processor, which gives
   *            it with access to facilities provided by the tool.
   */
  void init(ProcessingEnvironment env);

  /**
   * Processes a set of annotation types originating from the previous
   * round (including the virtual zeroth round formed from the user's input).
   * The processor may opt to claim these types by returning {@code true}.
   * If it does so, the types are claimed and they are not passed to
   * subsequent processors.  Whether a processor claims types or not may
   * vary, dependent on its own criteria.  A processor that supports
   * all types ({@code "*"}) is expected to gracefully handle the possibility
   * of receiving an empty set of annotations.
   *
   * @param types the annotations to process.
   * @param roundEnv information about this and the previous round.
   * @return true if the annotations are claimed by this processor, false otherwise.
   */
  boolean process(Set<? extends TypeElement> types, RoundEnvironment roundEnv);

}