22
33import com .google .common .annotations .Beta ;
44import com .google .common .base .Strings ;
5+ import com .google .common .collect .ImmutableSet ;
56import com .hubspot .jinjava .interpret .CallStack ;
67import com .hubspot .jinjava .interpret .Context ;
78import com .hubspot .jinjava .interpret .DeferredLazyReference ;
@@ -31,34 +32,18 @@ public class DeferredToken {
3132 public static class DeferredTokenBuilder {
3233
3334 private final Token token ;
34- private Stream <String > usedDeferredWords ;
35- private Stream <String > setDeferredWords ;
35+ private ImmutableSet . Builder <String > usedDeferredWords ;
36+ private ImmutableSet . Builder <String > setDeferredWords ;
3637
3738 private DeferredTokenBuilder (Token token ) {
3839 this .token = token ;
3940 }
4041
4142 public DeferredToken build () {
42- JinjavaInterpreter interpreter = JinjavaInterpreter .getCurrent ();
4343 return new DeferredToken (
4444 token ,
45- usedDeferredWords != null
46- ? usedDeferredWords
47- .map (DeferredToken ::splitToken )
48- .map (DeferredToken ::getFirstNonEmptyToken )
49- .distinct ()
50- .filter (word ->
51- interpreter == null ||
52- !(interpreter .getContext ().get (word ) instanceof DeferredMacroValueImpl )
53- )
54- .collect (Collectors .toSet ())
55- : Collections .emptySet (),
56- setDeferredWords != null
57- ? setDeferredWords
58- .map (DeferredToken ::splitToken )
59- .map (DeferredToken ::getFirstNonEmptyToken )
60- .collect (Collectors .toSet ())
61- : Collections .emptySet (),
45+ usedDeferredWords != null ? usedDeferredWords .build () : Collections .emptySet (),
46+ setDeferredWords != null ? setDeferredWords .build () : Collections .emptySet (),
6247 acquireImportResourcePath (),
6348 acquireMacroStack ()
6449 );
@@ -67,34 +52,40 @@ public DeferredToken build() {
6752 public DeferredTokenBuilder addUsedDeferredWords (
6853 Collection <String > usedDeferredWordsToAdd
6954 ) {
70- return addUsedDeferredWords (usedDeferredWordsToAdd .stream ());
55+ if (usedDeferredWords == null ) {
56+ usedDeferredWords = ImmutableSet .builder ();
57+ }
58+ usedDeferredWords .addAll (usedDeferredWordsToAdd );
59+ return this ;
7160 }
7261
7362 public DeferredTokenBuilder addUsedDeferredWords (
7463 Stream <String > usedDeferredWordsToAdd
7564 ) {
7665 if (usedDeferredWords == null ) {
77- usedDeferredWords = usedDeferredWordsToAdd ;
78- } else {
79- usedDeferredWords = Stream .concat (usedDeferredWords , usedDeferredWordsToAdd );
66+ usedDeferredWords = ImmutableSet .builder ();
8067 }
68+ usedDeferredWordsToAdd .forEach (usedDeferredWords ::add );
8169 return this ;
8270 }
8371
8472 public DeferredTokenBuilder addSetDeferredWords (
8573 Collection <String > setDeferredWordsToAdd
8674 ) {
87- return addSetDeferredWords (setDeferredWordsToAdd .stream ());
75+ if (setDeferredWords == null ) {
76+ setDeferredWords = ImmutableSet .builder ();
77+ }
78+ setDeferredWords .addAll (setDeferredWordsToAdd );
79+ return this ;
8880 }
8981
9082 public DeferredTokenBuilder addSetDeferredWords (
9183 Stream <String > setDeferredWordsToAdd
9284 ) {
9385 if (setDeferredWords == null ) {
94- setDeferredWords = setDeferredWordsToAdd ;
95- } else {
96- setDeferredWords = Stream .concat (setDeferredWords , setDeferredWordsToAdd );
86+ setDeferredWords = ImmutableSet .builder ();
9787 }
88+ setDeferredWordsToAdd .forEach (setDeferredWords ::add );
9889 return this ;
9990 }
10091 }
@@ -103,9 +94,10 @@ public DeferredTokenBuilder addSetDeferredWords(
10394 // These words aren't yet DeferredValues, but are unresolved
10495 // so they should be replaced with DeferredValueImpls if they exist in the context
10596 private final Set <String > usedDeferredWords ;
106-
97+ private final Set < String > usedDeferredBases ;
10798 // These words are those which will be set to a value which has been deferred.
10899 private final Set <String > setDeferredWords ;
100+ private final Set <String > setDeferredBases ;
109101
110102 // Used to determine the combine scope
111103 private final CallStack macroStack ;
@@ -211,23 +203,45 @@ public DeferredToken(
211203 ) {
212204 this (
213205 token ,
214- getBases ( usedDeferredWords ) ,
215- getBases ( setDeferredWords ) ,
206+ usedDeferredWords ,
207+ setDeferredWords ,
216208 acquireImportResourcePath (),
217209 acquireMacroStack ()
218210 );
219211 }
220212
221213 private DeferredToken (
222214 Token token ,
223- Set <String > usedDeferredWordBases ,
224- Set <String > setDeferredWordBases ,
215+ Set <String > usedDeferredWords ,
216+ Set <String > setDeferredWords ,
225217 String importResourcePath ,
226218 CallStack macroStack
227219 ) {
220+ JinjavaInterpreter interpreter = JinjavaInterpreter .getCurrent ();
228221 this .token = token ;
229- this .usedDeferredWords = usedDeferredWordBases ;
230- this .setDeferredWords = setDeferredWordBases ;
222+ this .usedDeferredBases =
223+ usedDeferredWords .isEmpty ()
224+ ? Collections .emptySet ()
225+ : usedDeferredWords
226+ .stream ()
227+ .map (DeferredToken ::splitToken )
228+ .map (DeferredToken ::getFirstNonEmptyToken )
229+ .distinct ()
230+ .filter (word ->
231+ interpreter == null ||
232+ !(interpreter .getContext ().get (word ) instanceof DeferredMacroValueImpl )
233+ )
234+ .collect (Collectors .toSet ());
235+ this .usedDeferredWords = usedDeferredWords ;
236+ this .setDeferredBases =
237+ setDeferredWords .isEmpty ()
238+ ? Collections .emptySet ()
239+ : setDeferredWords
240+ .stream ()
241+ .map (DeferredToken ::splitToken )
242+ .map (DeferredToken ::getFirstNonEmptyToken )
243+ .collect (Collectors .toSet ());
244+ this .setDeferredWords = setDeferredWords ;
231245 this .importResourcePath = importResourcePath ;
232246 this .macroStack = macroStack ;
233247 }
@@ -240,10 +254,18 @@ public Set<String> getUsedDeferredWords() {
240254 return usedDeferredWords ;
241255 }
242256
257+ public Set <String > getUsedDeferredBases () {
258+ return usedDeferredBases ;
259+ }
260+
243261 public Set <String > getSetDeferredWords () {
244262 return setDeferredWords ;
245263 }
246264
265+ public Set <String > getSetDeferredBases () {
266+ return setDeferredBases ;
267+ }
268+
247269 public String getImportResourcePath () {
248270 return importResourcePath ;
249271 }
@@ -255,7 +277,7 @@ public CallStack getMacroStack() {
255277 public void addTo (Context context ) {
256278 addTo (
257279 context ,
258- usedDeferredWords
280+ usedDeferredBases
259281 .stream ()
260282 .filter (word -> {
261283 Object value = context .get (word );
@@ -285,7 +307,7 @@ private void deferPropertiesOnContext(
285307 ) {
286308 if (isInSameScope (context )) {
287309 // set props are only deferred when within the scope which the variable is set in
288- markDeferredWordsAndFindSources (context , getSetDeferredWords (), true );
310+ markDeferredWordsAndFindSources (context , getSetDeferredBases (), true );
289311 }
290312 wordsWithoutDeferredSource .forEach (word -> deferDuplicatePointers (context , word ));
291313 wordsWithoutDeferredSource .removeAll (
@@ -424,12 +446,4 @@ private static String getFirstNonEmptyToken(List<String> strings) {
424446 public static List <String > splitToken (String token ) {
425447 return Arrays .asList (token .split ("\\ ." ));
426448 }
427-
428- public static Set <String > getBases (Set <String > original ) {
429- return original
430- .stream ()
431- .map (DeferredToken ::splitToken )
432- .map (prop -> prop .get (0 ))
433- .collect (Collectors .toSet ());
434- }
435449}
0 commit comments