2424import org .springframework .ai .template .ValidationMode ;
2525import org .springframework .util .Assert ;
2626import org .stringtemplate .v4 .ST ;
27+ import org .stringtemplate .v4 .compiler .Compiler ;
2728import org .stringtemplate .v4 .compiler .STLexer ;
2829
2930import java .util .HashSet ;
@@ -48,17 +49,22 @@ public class StTemplateRenderer implements TemplateRenderer {
4849
4950 private static final ValidationMode DEFAULT_VALIDATION_MODE = ValidationMode .THROW ;
5051
52+ private static final boolean DEFAULT_SKIP_BUILT_IN_FUNCTIONS_VALIDATION = false ;
53+
5154 private final char startDelimiterToken ;
5255
5356 private final char endDelimiterToken ;
5457
5558 private final ValidationMode validationMode ;
5659
57- StTemplateRenderer (char startDelimiterToken , char endDelimiterToken , ValidationMode validationMode ) {
60+ private final boolean skipBuiltInFunctionsValidation ;
61+
62+ StTemplateRenderer (char startDelimiterToken , char endDelimiterToken , ValidationMode validationMode , boolean skipBuiltInFunctionsValidation ) {
5863 Assert .notNull (validationMode , "validationMode cannot be null" );
5964 this .startDelimiterToken = startDelimiterToken ;
6065 this .endDelimiterToken = endDelimiterToken ;
6166 this .validationMode = validationMode ;
67+ this .skipBuiltInFunctionsValidation = skipBuiltInFunctionsValidation ;
6268 }
6369
6470 @ Override
@@ -113,15 +119,20 @@ private Set<String> getInputVariables(ST st) {
113119 if (token .getType () == STLexer .LDELIM && i + 1 < tokens .size ()
114120 && tokens .get (i + 1 ).getType () == STLexer .ID ) {
115121 if (i + 2 < tokens .size () && tokens .get (i + 2 ).getType () == STLexer .COLON ) {
116- inputVariables .add (tokens .get (i + 1 ).getText ());
117- isInsideList = true ;
122+ String text = tokens .get (i + 1 ).getText ();
123+ if (!Compiler .funcs .containsKey (text ) || !skipBuiltInFunctionsValidation ) {
124+ inputVariables .add (text );
125+ isInsideList = true ;
126+ }
118127 }
119128 }
120129 else if (token .getType () == STLexer .RDELIM ) {
121130 isInsideList = false ;
122131 }
123132 else if (!isInsideList && token .getType () == STLexer .ID ) {
124- inputVariables .add (token .getText ());
133+ if (!Compiler .funcs .containsKey (token .getText ()) || !skipBuiltInFunctionsValidation ) {
134+ inputVariables .add (token .getText ());
135+ }
125136 }
126137 }
127138
@@ -140,6 +151,8 @@ public static class Builder {
140151
141152 private ValidationMode validationMode = DEFAULT_VALIDATION_MODE ;
142153
154+ private boolean skipBuiltInFunctionsValidation = DEFAULT_SKIP_BUILT_IN_FUNCTIONS_VALIDATION ;
155+
143156 private Builder () {
144157 }
145158
@@ -158,10 +171,15 @@ public Builder validationMode(ValidationMode validationMode) {
158171 return this ;
159172 }
160173
174+ public Builder skipBuiltInFunctionsValidation () {
175+ this .skipBuiltInFunctionsValidation = true ;
176+ return this ;
177+ }
178+
161179 public StTemplateRenderer build () {
162- return new StTemplateRenderer (startDelimiterToken , endDelimiterToken , validationMode );
180+ return new StTemplateRenderer (startDelimiterToken , endDelimiterToken , validationMode , skipBuiltInFunctionsValidation );
163181 }
164182
165183 }
166184
167- }
185+ }
0 commit comments