@Override
    public Optional<Function<StatementContext, String>> parse(String template, ConfigRegistry config) {
        StringBuilder buf = new StringBuilder();
        List<BiConsumer<StatementContext, StringBuilder>> preparation = new ArrayList<>();
        Runnable pushBuf = () -> { // NOPMD
            if (buf.length() > 0) {
                String bit = buf.toString();
                buf.setLength(0);
                preparation.add((ctx, b) -> b.append(bit));
            }
        };
        DefineStatementLexer lexer = new DefineStatementLexer(CharStreams.fromString(template));
        lexer.addErrorListener(new ErrorListener());
        Token t = lexer.nextToken();
        while (t.getType() != EOF) {
            switch (t.getType()) {
                case COMMENT:
                case LITERAL:
                case QUOTED_TEXT:
                case DOUBLE_QUOTED_TEXT:
                    buf.append(t.getText());
                    break;
                case DEFINE:
                    pushBuf.run();
                    String text = t.getText();
                    String key = text.substring(1, text.length() - 1);
                    preparation.add((ctx, b) -> {
                        Object value = ctx.getAttribute(key);
                        if (value == null) {
                            throw new UnableToCreateStatementException("Undefined attribute for token '" + text + "'", ctx);
                        }
                        b.append(value);
                    });
                    break;
                case ESCAPED_TEXT:
                    buf.append(t.getText().substring(1));
                    break;
                default:
                    break;
            }
            t = lexer.nextToken();
        }
        pushBuf.run();
        return Optional.of(ctx -> {
            try {
                StringBuilder result = new StringBuilder();
                preparation.forEach(a -> a.accept(ctx, result));
                return result.toString();
            } catch (RuntimeException e) {
                throw new UnableToCreateStatementException("Error rendering SQL template: '" + template + "'", e, ctx);
            }
        });
    }
Template engine which replaces angle-bracketed tokens like
<code>&lt;name&gt;</code> with the string value of the named attribute.
Attribute names may contain letters (a-z, A-Z), digits (0-9), or underscores
(<code>_</code>).
core/src/main/java/org/jdbi/v3/core/statement/DefinedAttributeTemplateEngine.java