Architecture
1. Pipeline
A template string flows through four stages:
Template string -> Lexer -> Tokens -> Parser -> AST -> Executor -> Output
-
Lexer (
parse/Lexer.java) — scans the template into tokens, tracking action delimiters and trim markers. -
Parser (
parse/Parser.java) — builds an AST ofNodetypes (actions, pipelines,if/range/with, defined templates). -
Executor (
exec/Executor.java) — walks the AST against the data value, resolving fields, invoking functions, and writing output. A fresh executor is created perexecutecall, so a parsed template can be executed concurrently.
2. Modules and the function SPI
gotmpl4j-core knows only Go’s built-in functions (Functions.GO_BUILTINS). Everything else
is contributed by FunctionProvider implementations discovered through ServiceLoader:
| Provider | Priority | Source module |
|---|---|---|
Go built-ins |
— |
|
Sprig |
100 |
|
Helm |
200 |
(external — |
Higher priority wins on name collisions. To add your own functions, implement
FunctionProvider, register it in META-INF/services, and put it on the classpath — or pass
functions directly through GoTemplate.builder().withFunctions(…).
The core module must not depend on Sprig, Helm, or any host application; that boundary is what lets the engine be embedded standalone.