001package io.jstach.jstache;
002
003import java.lang.annotation.Documented;
004import java.lang.annotation.ElementType;
005import java.lang.annotation.Retention;
006import java.lang.annotation.RetentionPolicy;
007import java.lang.annotation.Target;
008import java.util.Map;
009import java.util.Optional;
010
011/**
012 * Generates a JStachio Renderer from a template and a model (the annotated class).
013 * <p>
014 * Classes annotated are typically called "models" as they will be the root context for
015 * the template.
016 *
017 * <h2 class="toc-title">Contents</h2> <div class="js-toc"></div>
018 * <div class="js-toc-content">
019 * <h2 id="_example">Example Usage</h2>
020 *
021 * <pre class="code">
022 * <code class="language-java">
023 * &#64;JStache(template = &quot;&quot;&quot;
024 *     {{#people}}
025 *     {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old!
026 *     {{#-last}}
027 *     That is all for now!
028 *     {{/-last}}
029 *     {{/people}}
030 *     &quot;&quot;&quot;)
031 * public record HelloWorld(String message, List&lt;Person&gt; people) implements AgeLambdaSupport {}
032 *
033 * public record Person(String name, LocalDate birthday) {}
034 *
035 * public record AgeInfo(long age, String date) {}
036 *
037 * public interface AgeLambdaSupport {
038 *   &#64;JStacheLambda
039 *   default AgeInfo ageInfo(
040 *       Person person) {
041 *     long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now());
042 *     String date = person.birthday().format(DateTimeFormatter.ISO_DATE);
043 *     return new AgeInfo(age, date);
044 *   }
045 * }
046 * </code> </pre>
047 *
048 * <h2 id="_model_and_templates">Models and Templates</h2>
049 *
050 * Because JStachio checks types its best to think of the model and template as married.
051 * With the exception of partials JStachio cannot have a template without a model and vice
052 * versa. The way to create Renderer (what we call the model and template combined) is to
053 * annotate your model with {@link io.jstach.jstache.JStache}.
054 *
055 * <h3 id="_models">Models</h3> <strong>&#64;{@link io.jstach.jstache.JStache}</strong>
056 * <p>
057 * A JStachio model can be any class type including Records and Enums so long as you can
058 * you annotate the type with {@link io.jstach.jstache.JStache}.
059 * <p>
060 * When the compiler runs the annotation processor will create readable java classes that
061 * are suffixed with "Renderer" which will have methods to write the model to an
062 * {@link java.lang.Appendable}. The generated instance methods are named
063 * <code>execute</code> and the corresponding static methods are named
064 * <code>render</code>.
065 * <p>
066 * <em>TIP: If you like to see the generated classes from the annotation processor they
067 * usually get put in <code>target/generated-sources/annotations</code> for Maven
068 * projects.</em>
069 *
070 * <h4 id="_decorating_models">Adding interfaces to models and renderers</h4>
071 * <strong>&#64;{@link io.jstach.jstache.JStacheInterfaces}</strong>
072 * <p>
073 * Java has a huge advantage over JSON and Javascript. <em>You can use interfaces to add
074 * additional variables as well as lambda methods
075 * ({@link io.jstach.jstache.JStacheLambda})!</em> To enforce that certain interfaces are
076 * added to models (the ones annotated) and renderers (the generated classes) you can use
077 * {@link io.jstach.jstache.JStacheInterfaces} on packages or the classes themselves.
078 * <p>
079 * You can also make generated classes have {@link ElementType#TYPE} annotations (see
080 * {@link JStacheInterfaces#templateAnnotations()}) and extend a class
081 * {@link JStacheInterfaces#templateExtends()}) as well which maybe useful for integration
082 * with other frameworks particularly DI frameworks.
083 *
084 * <h3 id="_templates">Templates</h3>
085 *
086 * The format of the templates should by default be Mustache. The syntax is informally
087 * explained by the
088 * <a href="https://jgonggrijp.gitlab.io/wontache/mustache.5.html">mustache manual</a> and
089 * formally explained by the <a href="https://github.com/mustache/spec">spec</a>. There
090 * are some subtle differences in JStachio version of Mustache due to the static nature
091 * that are discussed in <a href="#_context_lookup">context lookup</a>. <strong>Template
092 * finding is as follows:</strong>
093 * <ol>
094 * <li><code>path</code> which is a classpath with slashes following the same format as
095 * the ClassLoader resources. The path maybe augmented with {@link JStachePath}.
096 * <li><code>template</code> which if not empty is used as the template contents
097 * <li>if the above is not set then the name of the class suffixed with ".mustache" is
098 * used as the resource.
099 * </ol>
100 *
101 * <h4 id="_inline_templates">Inline Templates</h4>
102 * <strong>{@link io.jstach.jstache.JStache#template()}</strong>
103 * <p>
104 * Inline templates are pretty straight forward. Just set
105 * {@link io.jstach.jstache.JStache#template()} to a literal string. If you go this route
106 * it is <em>highly recommend you use the new triple quote string literal for inline
107 * templates</em>
108 *
109 * <h4 id="_resource_templates">Resource Templates</h4>
110 * <strong>{@link io.jstach.jstache.JStache#path()} and
111 * &#64;{@link io.jstach.jstache.JStachePath} </strong>
112 * <p>
113 * Resource templates are files that are in the classpath and are more complicated because
114 * of lookup resolution.
115 * <p>
116 * When the annotation processor runs these files usually are in:
117 * <code>javax.tools.StandardLocation#CLASS_OUTPUT</code> and in a Maven or Gradle project
118 * they normally would reside in <code>src/main/resources</code> or
119 * <code>src/test/resources</code> which get copied on build to
120 * <code>target/classes</code> or similar. <em>N.B. becareful not to have resource
121 * filtering turned on for mustache templates.</em>
122 * <p>
123 * Ideally JStachio would use <code>javax.tools.StandardLocation#SOURCE_PATH</code> to
124 * find resource templates but that is currently <a href=
125 * "https://stackoverflow.com/questions/22494596/eclipse-annotation-processor-get-project-path">
126 * problematic with incremental compilers such as Eclipse</a>.
127 * <p>
128 * Another issue with incremental compiling is that template files are not always copied
129 * after being edited to <code>target/classes</code> and thus are not found by the
130 * annotation processor. To deal with this issue JStachio during compilation fallsback to
131 * direct filesystem access and assumes that your templates are located:
132 * <code>CWD/src/main/resources</code>. That location is configurable via the annotation
133 * processor option {@link #RESOURCES_PATH_OPTION}
134 * (<strong>{@value #RESOURCES_PATH_OPTION}</strong>).
135 *
136 * <p>
137 * Normally you need to specify the full path in {@link #path()} which is a resource path
138 * (and not a file path) as specified by {@link ClassLoader#getResource(String)} however
139 * you can make path expansion happen with {@link io.jstach.jstache.JStachePath} which
140 * allows you to prefix and suffix the path.
141 *
142 * <h4 id="_partials">Partials</h4>
143 * <strong><code>{{&gt; partial }} and {{&lt; parent }}{{/parent}} </code></strong>
144 * <p>
145 * JStachio supports Mustache partials (and parents) and by default works just like
146 * template resources such that {@link io.jstach.jstache.JStachePath} is used for
147 * resolution if specified.
148 * <p>
149 * You may also remap partial names via {@link io.jstach.jstache.JStachePartial} to a
150 * different location as well as to an inline template (string literal).
151 *
152 * <h4 id="_fragments">Fragments</h4>
153 *
154 * JStachio allows referencing a <a href="https://htmx.org/essays/template-fragments/">
155 * subset of a template called "fragments"</a>. The subset of a template can be any type
156 * of section block and the <em>first one found from top to bottom reading with the
157 * matching name</em> is picked. The subset of a resource template is referenced with the
158 * URI fragment notation.
159 *
160 * <p>
161 * For example let us say we have a template like <code>/contacts/details.mustache</code>:
162 * <pre><code class="language-hbs">
163 * &lt;html&gt;
164 *     &lt;body&gt;
165 *         &lt;div hx-target="this"&gt;
166 *           {{#archive-ui}}
167 *             {{#contact.archived}}
168 *             &lt;button hx-patch="/contacts/${contact.id}/unarchive"&gt;Unarchive&lt;/button&gt;
169 *             {{/contact.archived}}
170 *             {{^contact.archived}}
171 *             &lt;button hx-delete="/contacts/${contact.id}"&gt;Archive&lt;/button&gt;
172 *             {{/contact.archived}}
173 *           {{/archive-ui}}
174 *         &lt;/div&gt;
175 *         &lt;h3&gt;Contact&lt;/h3&gt;
176 *         &lt;p&gt;${contact.email}&lt;/p&gt;
177 *     &lt;/body&gt;
178 * &lt;/html&gt;
179 * </code> </pre>
180 *
181 * <pre><code class="language-java">
182 * &#64;JStache("/contacts/details.mustache#archive-ui")
183 * public record ContactDetails(Contact contact){}
184 * </code> </pre>
185 *
186 * The effective template for <code>ContactDetails</code> would be:
187 *
188 * <pre><code class="language-hbs">
189 *   {{#contact.archived}}
190 *   &lt;button hx-patch="/contacts/${contact.id}/unarchive"&gt;Unarchive&lt;/button&gt;
191 *   {{/contact.archived}}
192 *   {{^contact.archived}}
193 *   &lt;button hx-delete="/contacts/${contact.id}"&gt;Archive&lt;/button&gt;
194 *   {{/contact.archived}}
195 * </code> </pre>
196 *
197 * <strong> If the fragment start tag is "standalone" and all the content inside the
198 * fragment start tag starts with the same whitespace (or more) as the fragment start tag
199 * starting whitespace will be stripped from each line of the content. </strong> This is
200 * to allow a partial references to dictate the indentation based on spec whitespace
201 * handling.
202 * <p>
203 * Fragment section blocks can be of these type:
204 * <ul>
205 * <li><code>{{#fragment}}</code></li>
206 * <li><code>{{$fragment}}</code></li>
207 * <li><code>{{&lt;fragment}}</code></li>
208 * <li><code>{{^fragment}}</code></li>
209 * </ul>
210 *
211 * The semantics of the section block are ignored as well as the rest of the template.
212 *
213 * <h4 id="_optional_spec">Optional Spec Support</h4> JStachio implements some optional
214 * parts of the specification. Below shows what is and is not supported.
215 * <table border="1">
216 * <caption><strong>Optional Spec Features Table</strong></caption>
217 * <tr>
218 * <th>Name</th>
219 * <th>Supported</th>
220 * <th>Manual Description</th>
221 * </tr>
222 * <tr>
223 * <td>Lambda variables (arity 0)</td>
224 * <td style="color:red;">NO</td>
225 * <td>An optional part of the specification states that if the final key in the name is a
226 * lambda that returns a string, then that string should be rendered as a Mustache
227 * template before interpolation. It will be rendered using the default delimiters (see
228 * Set Delimiter below) against the current context.</td>
229 * </tr>
230 * <tr>
231 * <td>Lambda sections (arity 1)</td>
232 * <td style="color:blue;">YES</td>
233 * <td>An optional part of the specification states that if the final key in the name is a
234 * lambda that returns a string, then that string replaces the content of the section. It
235 * will be rendered using the same delimiters (see Set Delimiter below) as the original
236 * section content. In this way you can implement filters or caching.</td>
237 * </tr>
238 * <tr>
239 * <td>Delimiters</td>
240 * <td style="color:blue;">YES</td>
241 * <td>Set Delimiter tags are used to change the tag delimiters for all content following
242 * the tag in the current compilation unit. The tag's content MUST be any two
243 * non-whitespace sequences (separated by whitespace) EXCEPT an equals sign ('=') followed
244 * by the current closing delimiter. Set Delimiter tags SHOULD be treated as standalone
245 * when appropriate. <em>(this feature is non-optional in current mustache but some
246 * mustaches implemenations treat it as optional)</em></td>
247 * </tr>
248 * <tr>
249 * <td>Dynamic Names</td>
250 * <td style="color:red;">NO</td>
251 * <td>Partials can be loaded dynamically at runtime using Dynamic Names; an optional part
252 * of the Mustache specification which allows to dynamically determine a tag's content at
253 * runtime.</td>
254 * </tr>
255 * <tr>
256 * <td>Blocks</td>
257 * <td style="color:blue;">YES</td>
258 * <td>A block begins with a dollar and ends with a slash. That is, {{$title}} begins a
259 * "title" block and {{/title}} ends it.</td>
260 * </tr>
261 * <tr>
262 * <td>Parents</td>
263 * <td style="color:blue;">YES</td>
264 * <td>A parent begins with a less than sign and ends with a slash. That is,
265 * {{&lt;article}} begins an "article" parent and {{/article}} ends it.</td>
266 * </tr>
267 * </table>
268 *
269 * <h3 id="_context_lookup">Context Lookup</h3>
270 *
271 * JStachio unlike almost all other Mustache implementations does its context lookup
272 * statically during compile time. Consequently JStachio pedantically is early bound where
273 * as Mustache is traditionally late bound. Most of the time this difference will not
274 * manifest itself so long as you avoid using {@link Map} in your models.
275 * <p>
276 * The other notable difference is JStachio does not like missing variables (a compiler
277 * error will happen) where as many Mustache implementations sometimes allow this and will
278 * just not output anything.
279 *
280 * <em> n.b. This doc and various other docs often appears to use the term "variable" and
281 * "binding" interchangeable. "variable" however is generally a subset of "binding" and is
282 * the leaf nodes of the model tree that are to be outputted like String
283 * interpolation.</em> In mustache spec parlance it is the last key (all the way to the
284 * right) of a dotted name. Also in some cases this doc calls dotted names "path".
285 *
286 *
287 * <h4 id="_context_java_types">Interpretation of Java-types and values</h4> When some
288 * value is null nothing is rendered if it is used as a section. If some value is null and
289 * it is used as a variable a null pointer exception will be thrown by default. This is
290 * configurable via {@link JStacheFormatterTypes} and custom {@link JStacheFormatter}.
291 * <p>
292 * Boxed and unboxed <code>boolean</code> can be used for mustache-sections. Section is
293 * only rendered if value is true.
294 * <p>
295 * {@link Optional} empty is treated like an empty list or a boolean false. Optional
296 * values are always assumed to be non null.
297 * <p>
298 * {@code Map<String,?>} follow different nesting rules than other types. If you are in a
299 * {@link Map} nested section the rest of the context is checked before the
300 * <code>Map</code>. Once that is done the Map is then checked using
301 * {@link Map#get(Object)}' where the key is the <em>last part of the dotted name</em>.
302 * <p>
303 * Data-binding contexts are nested. Names are looked up in innermost context first. If
304 * name is not found in current context, parent context is inspected. This process
305 * continues up to root context.
306 *
307 * In each rendering context name lookup is performed as follows:
308 *
309 * <ol>
310 * <li>Method with requested name is looked up. Method should have no arguments and should
311 * throw no checked exceptions. If there is such method it is used to fetch actual data to
312 * render. Compile-time error is raised if there is method with given name, but it is not
313 * accessible, has parameters or throws checked exceptions.</li>
314 * <li>Method with requested name and annotated correctly with {@link JStacheLambda} and
315 * the lookup is for a section than the method lambda method will be used.</li>
316 * <li>Method with getter-name for requested name is looked up. (For example, if 'age' is
317 * requested, 'getAge' method is looked up.) Method should have no arguments and should
318 * throw no checked exceptions. If there is such method it is used to fetch actual data to
319 * render. Compile-time error is raised if there is method with such name, but it is not
320 * accessible, has parameters or throws checked exceptions</li>
321 *
322 * <li>Field with requested name is looked up. Compile-time error is raised if there is
323 * field with such name but it's not accessible.</li>
324 * </ol>
325 *
326 * <h4 id="_inheritance">Inheritance and enclosed access of fields and methods</h4>
327 *
328 * Currently JStachio will only allow access to <code>public</code> methods and fields
329 * that are <strong>inherited</strong>. However enclosed fields and methods
330 * <strong>directly</strong> on the type annotated can be package protected (the default
331 * no modifier). <code>private</code> fields and methods regardless of inheritance are not
332 * allowed as the only way to access them would be through MethodHandles and would greatly
333 * complicate code generation.
334 * <p>
335 * <em> The above behavior is to simplify portability and usage of reflective engines such
336 * as JMustache and Handlebars.java in modular applications and libraries. However the use
337 * of these engines unlike JStachio may still require <code>open</code>ing up the module
338 * containing the annotated models. If you would like different rules for access please
339 * file an issue. </em>
340 *
341 * <h4 id="_enums">Enum Matching Extension</h4> Basically enums have boolean keys that are
342 * the enums name ({@code Enum.name()}) that can be used as conditional sections. Assume
343 * {@code light} is an enum like:
344 *
345 * <pre>
346 * <code class="language-java">
347 * public enum Light {
348 *   RED,
349 *   GREEN,
350 *   YELLOW
351 * }
352 * </code> </pre>
353 *
354 * You can conditinally select on the enum like a pattern match:
355 *
356 * <pre>
357 * <code class="language-hbs">
358 * {{#light.RED}}
359 * STOP
360 * {{/light.RED}}
361 * {{#light.GREEN}}
362 * GO
363 * {{/light.GREEN}}
364 * {{#light.YELLOW}}
365 * Proceeed with caution
366 * {{/light.YELLOW}}
367 * </code> </pre>
368 *
369 * <h4 id="_index_support">Index Extension</h4>
370 *
371 * JStachio is compatible with both handlebars.js (handlebars.java as well) and JMustache
372 * index keys for iterable sections.
373 * <ol>
374 * <li><code>{@value #FIRST_JMUSTACHE_BINDING_NAME}</code> and
375 * <code>{@value #FIRST_BINDING_NAME}</code> is boolean that is true when you are on the
376 * first item.</li>
377 * <li><code>{@value #LAST_JMUSTACHE_BINDING_NAME}</code> and
378 * <code>{@value #LAST_JMUSTACHE_BINDING_NAME}</code> is a boolean that is true when you
379 * are on the last item in the iterable</li>
380 * <li><code>{@value #INDEX_JMUSTACHE_BINDING_NAME}</code> is a one based index. The first
381 * item would be {@code 1} and not {@code 0}</li>
382 * <li><code>{@value #INDEX_BINDING_NAME}</code> is zero based index (handlebars). The
383 * first item would be {@code 0}.
384 * </ol>
385 *
386 * <h3 id="_lambdas">Lambda Support</h3>
387 *
388 * <strong>&#64;{@link JStacheLambda}</strong>
389 * <p>
390 * JStachio supports lambda section calls in a similar manner to
391 * <a href="https://github.com/samskivert/jmustache">JMustache</a>. Just tag your methods
392 * with {@link JStacheLambda} and the returned models will be used to render the contents
393 * of the lambda section. The top of the context stack can be passed to the lambda.
394 *
395 *
396 * <h2 id="_code_generation">Code Generation</h2>
397 *
398 * <strong>&#64;{@link io.jstach.jstache.JStacheConfig#type()}</strong>
399 * <p>
400 * JStachio by default reads mustache syntax and generates code that needs the jstachio
401 * runtime (io.jstache.jstachio). However it is possible to generate code that does not
402 * need the runtime and possibly in the future other syntaxs like Handlebars might be
403 * supported.
404 *
405 * <h3 id="_methods_generated">Generated Renderer Classes</h3> JStachio generates a single
406 * class from a mustache template and model (class annotated with JStache) pair. The
407 * generated classes are generally called "Renderers" or sometimes "Templates". Depending
408 * on which JStache type is picked different methods are generated. The guaranteed
409 * generated methods <em>not to change on minor version or less</em> on the renderer
410 * classes are discussed in <strong>{@link JStacheType}</strong>.
411 *
412 * <h3 id="_zero_dep">Zero dependency code generation</h3>
413 *
414 * <strong>&#64;{@link io.jstach.jstache.JStacheConfig#type()} ==
415 * {@link JStacheType#STACHE}</strong>
416 * <p>
417 * Zero dependency code generation is useful if you want to avoid coupling your runtime
418 * and downstream dependencies with JStachio (including the annotations themselves) as
419 * well as minimize the overall footprint and or classes loaded. A common use case would
420 * be using jstachio for code generation in an annotation processing library where you
421 * want as minimal class path issues as possible.
422 * <p>
423 * If this configuration is selected generated code will <strong>ONLY have references to
424 * stock base JDK module ({@link java.base/}) classes</strong>. However one major caveat
425 * is that generated classes will not be reflectively accessible to the JStachio runtime
426 * and thus fallback and filtering will not work. Thus in a web framework environment this
427 * configuration choice is less desirable.
428 * <p>
429 * <em>n.b. as long as the jstachio annotations are not accessed reflectively you do not
430 * need the annotation jar in the classpath during runtime thus the annotations jar is
431 * effectively an optional compile time dependency.</em>
432 *
433 *
434 * <h2 id="_formatting">Formatting variables</h2>
435 *
436 * JStachio has strict control on what happens when you output a variable (a binding that
437 * is not an iterable) like <code>{{variable}}</code> or <code>{{{variable}}}</code>.
438 *
439 * <h3 id="_allowed_types">Allowed formatting types</h3> <strong>
440 * &#64;{@link io.jstach.jstache.JStacheFormatterTypes}</strong>
441 * <p>
442 * Only a certain set of types are allowed to be formatted and if they are not a compiler
443 * error will happen (as in the annotation processor will fail). To understand more about
444 * that see {@link io.jstach.jstache.JStacheFormatterTypes}.
445 *
446 * <h3 id="_runtime_formatting">Runtime formatting</h3>
447 * <strong>&#64;{@link io.jstach.jstache.JStacheFormatter} and
448 * &#64;{@link JStacheConfig#formatter()}</strong>
449 * <p>
450 * Assuming the compiler allowed the variable to be formatted you can control the output
451 * via {@link io.jstach.jstache.JStacheFormatter} and setting
452 * {@link io.jstach.jstache.JStacheConfig#formatter()}.
453 * <p>
454 * If you are using the JStachio runtime (io.jstach.jstachio) and have
455 * {@link JStacheConfig#type()} set to {@link JStacheType#JSTACHIO} (or UNSPECIFIED aka
456 * default) the default formatter will be used (see <code class=
457 * "externalLink">io.jstach.jstachio.formatters.DefaultFormatter</code>). The default
458 * formatter is slightly different than the mustache spec in that it does not allow
459 * formatting nulls. If you would like to follow the spec rules where <code>null</code>
460 * should be an empty string use <code class=
461 * "externalLink">io.jstach.jstachio.formatters.SpecFormatter</code>.
462 *
463 * <h2 id="_escaping">Escaping and Content Type</h2>
464 * <strong>&#64;{@link io.jstach.jstache.JStacheContentType}, and
465 * &#64;{@link JStacheConfig#contentType()} </strong>
466 * <p>
467 * If you are using the JStachio runtime (io.jstach.jstachio) and have
468 * {@link JStacheConfig#type()} set to {@link JStacheType#JSTACHIO} (or UNSPECIFIED aka
469 * default) you will get out of the box escaping for HTML (see
470 * <code class="externalLink">io.jstach.jstachio.escapers.Html</code>) per the mustache
471 * spec.
472 * <p>
473 * <strong>To disable escaping</strong> set {@link JStacheConfig#contentType()} to
474 * <code class="externalLink">io.jstach.jstachio.escapers.PlainText</code>.
475 *
476 * <h2 id="_config">Configuration</h2> <strong>&#64;{@link JStacheConfig}</strong>
477 * <p>
478 * You can set global configuration on class, packages and module elements. See
479 * {@link JStacheConfig} for more details on config resolution. Some configuration is set
480 * through compiler flags and annotation processor options. However {@link JStacheConfig}
481 * unlike compiler flags and annotation processor options are available during runtime
482 * through reflective access.
483 *
484 * <h3 id="_config_flags">Compiler flags</h3>
485 *
486 * The compiler has some boolean flags that can be set statically via {@link JStacheFlags}
487 * as well as through annotation processor options.
488 *
489 * <h3 id="_config_compiler">Annotation processor options</h3>
490 *
491 * Some configuration is available as an annotation processor option. Current available
492 * options are:
493 *
494 * <ul>
495 * <li>{@link #RESOURCES_PATH_OPTION}</li>
496 * <li>{@link #INCREMENTAL_OPTION}</li>
497 * </ul>
498 *
499 * The previously mentioned {@linkplain JStacheFlags compiler flags} are also available as
500 * annotation options. The flags are prefixed with "<code>jstache.</code>". For example
501 * {@link JStacheFlags.Flag#DEBUG} would be:
502 * <p>
503 * <code>jstache.debug=true/false</code>.
504 *
505 * <h4 id="_config_compiler_maven">Configuring options with Maven</h4>
506 *
507 * Example configuration with Maven:
508 *
509 * <pre class="language-xml">{@code
510 * <plugin>
511 *     <groupId>org.apache.maven.plugins</groupId>
512 *     <artifactId>maven-compiler-plugin</artifactId>
513 *     <version>3.8.1</version>
514 *     <configuration>
515 *         <source>17</source>
516 *         <target>17</target>
517 *         <annotationProcessorPaths>
518 *             <path>
519 *                 <groupId>io.jstach</groupId>
520 *                 <artifactId>jstachio-apt</artifactId>
521 *                 <version>${io.jstache.version}</version>
522 *             </path>
523 *         </annotationProcessorPaths>
524 *         <compilerArgs>
525 *             <arg>
526 *                 -Ajstache.resourcesPath=src/main/resources
527 *             </arg>
528  *             <arg>
529 *                 -Ajstache.debug=false
530 *             </arg>
531 *         </compilerArgs>
532 *     </configuration>
533 * </plugin>
534 * }</pre>
535 *
536 * <h4 id="_config_compiler_gradle">Configuring options with Gradle</h4>
537 *
538 * Example configuration with Gradle:
539 *
540 * <pre>
541 * <code class="language-kotlin">
542 * compileJava {
543 *     options.compilerArgs += [
544 *     '-Ajstache.resourcesPath=src/main/resources'
545 *     ]
546 * }
547 * </code> </pre>
548 *
549 *
550 * </div>
551 *
552 * @author agentgt
553 * @see JStachePath
554 * @see JStacheFormatterTypes
555 * @see JStacheConfig
556 * @see JStacheFormatter
557 * @see JStacheContentType
558 * @see JStacheConfig
559 *
560 * @jstachioVersion
561 */
562@Retention(RetentionPolicy.RUNTIME)
563@Target(ElementType.TYPE)
564@Documented
565public @interface JStache {
566
567        /**
568         * Resource path to template
569         * @return Path to mustache template
570         * @see JStachePath
571         */
572        String path() default "";
573
574        /**
575         * Inline the template as a Java string instead of a file. Use the new triple quote
576         * string literal for complex templates.
577         * @return An inline template
578         */
579        String template() default "";
580
581        /**
582         * Name of generated class.
583         * <p>
584         * name can be omitted. <code>model.getClass().getName()</code> +
585         * {@link JStacheName#DEFAULT_SUFFIX} name is used by default.
586         * @return Name of generated class
587         */
588        String name() default "";
589
590        /**
591         * An annotation processor compiler flag
592         * (<strong>{@value #RESOURCES_PATH_OPTION}</strong>) that says where the templates
593         * files are located.
594         * <p>
595         * When the annotation processor runs these files usually are in:
596         * <code>javax.tools.StandardLocation#CLASS_OUTPUT</code> and in a Maven or Gradle
597         * project they normally would reside in <code>src/main/resources</code> or
598         * <code>src/test/resources</code> which get copied on build to
599         * <code>target/classes</code> or similar. However due to incremental compiling
600         * template files are not always copied to <code>target/classes</code> and thus are
601         * not found by the annotation processor. To deal with this issue JStachio during
602         * compilation fallsback to direct filesystem access of the <em>source</em> directory
603         * instead of the output (<code>javax.tools.StandardLocation#CLASS_OUTPUT</code>) if
604         * the files cannot be found.
605         * <p>
606         * JStachio tries to resolve your project layout and current working directory
607         * automatically based on variety of heuristics so that you do not need to use this
608         * flag. JStachio may not find the correct source folder for your templates but it
609         * usually can find the correct "<em>current working directory</em>" (which will be
610         * called "<em>CWD</em>" for the rest of this passage).
611         * </p>
612         * <strong>Multiple paths can be passed by comma separating them.</strong> The paths
613         * are tried in order. If a path does not start with a path separator then it will be
614         * appended to the <strong>resolved</strong> CWD otherwise it is assumed to be a fully
615         * qualified path. <strong> NOTE the CWD may not be correct! </strong>
616         * <p>
617         * The default location is <code>CWD/src/main/resources</code>. Again the CWD may not
618         * be resolved correctly so the only guarantee is to give the absolute path if nothing
619         * else is working. Please file an issue with info on your build system and IDE if you
620         * project is mostly canonical in layout if you are experiencing issues.
621         * </p>
622         *
623         * <strong>If the option is blank or empty then NO fallback will happen and
624         * effectively disables the above behavior. </strong>
625         *
626         * You can change it by passing to the annotation processor a setting for
627         * <strong>{@value #RESOURCES_PATH_OPTION}</strong> like:
628         * <pre><code>jstache.resourcesPath=some/path</code></pre>
629         *
630         * For build annotation processor configuration examples see:
631         * <ol>
632         * <li><a href="#_config_compiler_maven">Configuring options with Maven</a></li>
633         * <li><a href="#_config_compiler_gradle">Configuring options with Gradle</a></li>
634         * </ol>
635         *
636         */
637        public static final String RESOURCES_PATH_OPTION = "jstache.resourcesPath";
638
639        /**
640         * <strong>EXPERIMENTAL:</strong> annotation processor compiler flag
641         * (<strong>{@value #INCREMENTAL_OPTION}</strong>) that turns on incremental compiling
642         * of supported platforms (currently only Gradle). <em>This option may turn off other
643         * settings and if it does it will warn you!</em>
644         * <p>
645         * Incremental compiling does not support generating {@linkplain JStacheCatalog
646         * catalogs} or Service Provider files (<code>META-INF/services</code>).
647         */
648        public static final String INCREMENTAL_OPTION = "jstache.incremental";
649
650        /**
651         * A virtual variable that is direct analog to
652         * <a href="https://handlebarsjs.com/api-reference/data-variables.html#root">
653         * handlebars <code>&#64;root</code></a>. The root model instance is accessible to
654         * mustache templates with this global binding name. This allows easier access to the
655         * model if deeply nested in a context stack.
656         */
657        public static final String ROOT_BINDING_NAME = "@root";
658
659        /**
660         * A handlebars inspired virtual variable that is bound while in list contexts. If on
661         * the first element then it is <code>true</code>.
662         */
663        public static final String FIRST_BINDING_NAME = "@first";
664
665        /**
666         * A JMustache inspired virtual variable that is bound while in list contexts. If on
667         * the first element then it is <code>true</code>.
668         */
669        public static final String FIRST_JMUSTACHE_BINDING_NAME = "-first";
670
671        /**
672         * A handlebars inspired virtual variable that is bound while in list contexts. If on
673         * the last element then it is <code>true</code>.
674         */
675        public static final String LAST_BINDING_NAME = "@last";
676
677        /**
678         * A JMustache inspired virtual variable that is bound while in list contexts. If on
679         * the last element then it is <code>true</code>.
680         */
681        public static final String LAST_JMUSTACHE_BINDING_NAME = "-last";
682
683        /**
684         * A handlebars inspired virtual variable that is bound while in list contexts. A zero
685         * based index that is an integer.
686         */
687        public static final String INDEX_BINDING_NAME = "@index";
688
689        /**
690         * A JMustache inspired virtual variable that is bound while in list contexts. A one
691         * based index that is an integer.
692         */
693        public static final String INDEX_JMUSTACHE_BINDING_NAME = "-index";
694
695}