0
# Code Generation Framework
1
2
Advanced annotation processing framework for creating custom code generators and template-based processors. The Generator framework provides the foundation for building sophisticated annotation processors beyond the basic immutable value generation.
3
4
## Capabilities
5
6
### Template Definition
7
8
Mark classes as template definitions for code generation.
9
10
```java { .api }
11
/**
12
* Generates "generator" subclass of annotated template definition.
13
* It is recommended that annotated class also extend AbstractTemplate
14
* so default templating language capabilities will be accessible.
15
*/
16
@Documented
17
@Target(ElementType.TYPE)
18
@Retention(RetentionPolicy.SOURCE)
19
@interface Generator.Template {}
20
```
21
22
**Usage Example:**
23
24
```java
25
@Generator.Template
26
public abstract class PersonTemplate extends AbstractTemplate {
27
28
@Generator.Typedef
29
java.util.List<String> StringList;
30
31
public void generate() {
32
for (TypeElement type : annotations()) {
33
generateForType(type);
34
}
35
}
36
37
private void generateForType(TypeElement type) {
38
// Template generation logic here
39
out("// Generated code for: " + type.getSimpleName());
40
}
41
}
42
```
43
44
### Import Management
45
46
Import classes as simple name aliases for template language.
47
48
```java { .api }
49
/**
50
* Imports classes as simple name aliases to be available to template language.
51
* Special kind of annotation inheritance works. All imports combined together
52
* from @Generator.Import annotations of template classes and enclosing packages,
53
* as well as from superclasses and their respective packages.
54
*/
55
@Inherited
56
@Target({ ElementType.TYPE, ElementType.PACKAGE })
57
@Retention(RetentionPolicy.SOURCE)
58
@interface Generator.Import {
59
Class<?>[] value();
60
}
61
```
62
63
**Usage Example:**
64
65
```java
66
@Generator.Template
67
@Generator.Import({
68
java.util.List.class,
69
java.util.Map.class,
70
com.example.CustomType.class
71
})
72
public abstract class MyTemplate extends AbstractTemplate {
73
// Can now use List, Map, CustomType as simple names in templates
74
}
75
```
76
77
### Type Definitions
78
79
Define complex types as simple type names for template language.
80
81
```java { .api }
82
/**
83
* Used to introduce complex types as simple type names available to template language.
84
* Annotate fields with this annotation to introduce such typedef. Fields should be
85
* named starting with uppercase, so template will recognize it as type identifier.
86
*/
87
@Target(ElementType.FIELD)
88
@Retention(RetentionPolicy.SOURCE)
89
@interface Generator.Typedef {}
90
```
91
92
**Usage Example:**
93
94
```java
95
@Generator.Template
96
public abstract class CollectionTemplate extends AbstractTemplate {
97
98
@Generator.Typedef
99
java.util.Map.Entry<String, String> StringPair;
100
101
@Generator.Typedef
102
java.util.List<java.util.Map<String, Object>> DataList;
103
104
// Can now use StringPair and DataList as simple type names
105
}
106
```
107
108
### Method Memoization
109
110
Cache method results for improved performance during template processing.
111
112
```java { .api }
113
/**
114
* This annotation is used for memoization of methods or types (caching results).
115
* Applied to methods to avoid repeated computation of expensive operations.
116
*/
117
@Documented
118
@Target({ ElementType.METHOD, ElementType.TYPE })
119
@Retention(RetentionPolicy.SOURCE)
120
@interface Generator.Memoised {}
121
```
122
123
**Usage Example:**
124
125
```java
126
@Generator.Template
127
public abstract class OptimizedTemplate extends AbstractTemplate {
128
129
@Generator.Memoised
130
protected String computeExpensiveValue(TypeElement type) {
131
// Expensive computation that gets cached
132
return performComplexAnalysis(type);
133
}
134
}
135
```
136
137
### Supported Annotations Declaration
138
139
Declare which annotations the processor handles.
140
141
```java { .api }
142
/**
143
* Applies to the annotation processor extending AbstractGenerator to supply
144
* annotation names that processor will handle. Could be used instead of
145
* @SupportedAnnotationTypes, which is also supported.
146
*/
147
@Target({ ElementType.TYPE, ElementType.PACKAGE })
148
@Retention(RetentionPolicy.RUNTIME)
149
@interface Generator.SupportedAnnotations {
150
Class<? extends Annotation>[] value();
151
}
152
```
153
154
**Usage Example:**
155
156
```java
157
@Generator.SupportedAnnotations({
158
MyCustomAnnotation.class,
159
AnotherAnnotation.class
160
})
161
public class MyAnnotationProcessor extends AbstractGenerator {
162
@Override
163
protected void process() {
164
// Process the supported annotations
165
}
166
}
167
```
168
169
## Template Runtime Framework
170
171
### Template Invocation Context
172
173
Core class for template invocation, handling output generation and parameter management.
174
175
```java { .api }
176
/**
177
* Template invocation context providing output methods and parameter access.
178
* Used within template methods to generate code and handle parameters.
179
*/
180
public final static class Templates.Invokation {
181
182
/** Get the number of parameters passed to this invocation */
183
public int arity();
184
185
/** Get parameter at specified index */
186
public Object param(int ordinal);
187
188
/** Enable delimiter handling for cleaner output formatting */
189
public Invokation delimit();
190
191
/** Output a newline character */
192
public Invokation ln();
193
194
/** Output a string */
195
public Invokation out(String string);
196
197
/** Output an object (converted to string) */
198
public Invokation out(@Nullable Object content);
199
200
/** Output multiple objects */
201
public Invokation out(Object... objects);
202
203
/** Set current position for indentation management */
204
public Invokation pos(int pos);
205
}
206
```
207
208
### Template Fragment
209
210
Abstract base class for reusable template fragments.
211
212
```java { .api }
213
/**
214
* Abstract base class for template fragments that can be invoked with parameters.
215
* Provides captured indentation and parameter management for reusable code blocks.
216
*/
217
public static abstract class Templates.Fragment implements Invokable {
218
219
/** Create fragment with specified arity and captured invocation context */
220
protected Fragment(int arity, @Nullable Invokation capturedInvokation);
221
222
/** Create fragment with specified arity */
223
protected Fragment(int arity);
224
225
/** Get the number of parameters this fragment expects */
226
public int arity();
227
228
/** Run the fragment with given invocation context */
229
public abstract void run(Invokation invokation);
230
231
/** Invoke fragment with parameters, returning null or nested invokable */
232
@Nullable
233
public Invokable invoke(Invokation invokation, Object... params);
234
235
/** Convert fragment to character sequence */
236
CharSequence toCharSequence();
237
238
/** Convert fragment to string representation */
239
public String toString();
240
}
241
```
242
243
### Invokable Interface
244
245
Core interface for objects that can be invoked in template context.
246
247
```java { .api }
248
/**
249
* Interface for objects that can be invoked within template processing.
250
* Enables composition and chaining of template operations.
251
*/
252
public interface Templates.Invokable {
253
254
/**
255
* Invoke with parent invocation context and parameters
256
* @return null or nested invokable for chained operations
257
*/
258
@Nullable
259
Invokable invoke(Invokation parentInvokation, Object... parameters);
260
261
/** Get the number of parameters this invokable expects */
262
int arity();
263
}
264
```
265
266
## Base Classes
267
268
### Abstract Template
269
270
Base class for template definitions with built-in templating capabilities.
271
272
```java { .api }
273
/**
274
* Abstract base class for template definitions, extending built-in template
275
* language capabilities and providing access to processing environment.
276
*/
277
public abstract class AbstractTemplate extends Builtins {
278
279
/** Get the annotation processing environment */
280
protected final ProcessingEnvironment processing();
281
282
/** Get the current round environment */
283
protected final RoundEnvironment round();
284
285
/** Get the set of annotation types being processed */
286
protected final Set<TypeElement> annotations();
287
}
288
```
289
290
### Abstract Generator
291
292
Base class for annotation processors using the Generator framework.
293
294
```java { .api }
295
/**
296
* Abstract base class for annotation processors using the Generator framework.
297
* Extends AbstractProcessor with template invocation capabilities.
298
*/
299
public abstract class AbstractGenerator extends AbstractProcessor {
300
301
/** Main processing method to be implemented by subclasses */
302
protected abstract void process();
303
304
/** Get the annotation processing environment */
305
protected final ProcessingEnvironment processing();
306
307
/** Get the current round environment */
308
protected final RoundEnvironment round();
309
310
/** Get the set of annotation types being processed */
311
protected final Set<TypeElement> annotations();
312
313
/** Invoke a template or fragment */
314
protected final void invoke(Templates.Invokable invokable);
315
}
316
```
317
318
## Advanced Usage Patterns
319
320
### Custom Annotation Processor
321
322
```java
323
@Generator.SupportedAnnotations(MyAnnotation.class)
324
public class MyProcessor extends AbstractGenerator {
325
326
@Override
327
protected void process() {
328
for (TypeElement type : annotations()) {
329
processAnnotatedType(type);
330
}
331
}
332
333
private void processAnnotatedType(TypeElement type) {
334
MyTemplate template = new MyTemplateGenerator();
335
template.setProcessingEnvironment(processing());
336
template.setRoundEnvironment(round());
337
template.generateForType(type);
338
}
339
}
340
```
341
342
### Template with Fragments
343
344
```java
345
@Generator.Template
346
public abstract class ComponentTemplate extends AbstractTemplate {
347
348
protected final Fragment methodFragment = new Fragment(2) {
349
@Override
350
public void run(Invokation invokation) {
351
String methodName = (String) invokation.param(0);
352
String returnType = (String) invokation.param(1);
353
354
invokation
355
.out("public ").out(returnType).out(" ").out(methodName).out("() {").ln()
356
.out(" // Generated method implementation").ln()
357
.out("}").ln();
358
}
359
};
360
361
public void generateClass(String className) {
362
out("public class ").out(className).out(" {").ln();
363
methodFragment.invoke(null, "getName", "String");
364
methodFragment.invoke(null, "getId", "Long");
365
out("}").ln();
366
}
367
}
368
```