@@ -128,16 +128,40 @@ public static Map<String, String> reconstructFromContextBeforeDeferringAsMap(
128128 Set <String > deferredWords ,
129129 JinjavaInterpreter interpreter
130130 ) {
131- Map <String , String > reconstructedValues = new LinkedHashMap <>();
132- reconstructedValues .putAll (
133- reconstructMacroFunctionsBeforeDeferring (deferredWords , interpreter )
131+ PrefixToPreserveState prefixToPreserveState = new PrefixToPreserveState ();
132+ reconstructFromContextBeforeDeferringAsMap (
133+ prefixToPreserveState ,
134+ deferredWords ,
135+ interpreter ,
136+ 0
134137 );
135- Set <String > deferredWordBases = filterToRelevantBases (deferredWords , interpreter );
138+ return prefixToPreserveState ;
139+ }
136140
137- reconstructedValues .putAll (
138- reconstructSetVariablesBeforeDeferring (deferredWordBases , interpreter )
139- );
140- return reconstructedValues ;
141+ private static void reconstructFromContextBeforeDeferringAsMap (
142+ PrefixToPreserveState prefixToPreserveState ,
143+ Set <String > deferredWords ,
144+ JinjavaInterpreter interpreter ,
145+ int depth
146+ ) {
147+ if (depth <= interpreter .getConfig ().getMaxRenderDepth ()) {
148+ reconstructMacroFunctionsBeforeDeferring (
149+ prefixToPreserveState ,
150+ deferredWords ,
151+ interpreter
152+ );
153+ Set <String > deferredWordBases = filterToRelevantBases (deferredWords , interpreter );
154+ if (deferredWordBases .isEmpty ()) {
155+ return ;
156+ }
157+
158+ reconstructSetVariablesBeforeDeferring (
159+ prefixToPreserveState ,
160+ deferredWordBases ,
161+ interpreter ,
162+ depth
163+ );
164+ }
141165 }
142166
143167 private static Set <String > filterToRelevantBases (
@@ -184,13 +208,15 @@ private static Set<String> filterToRelevantBases(
184208 * @return A jinjava-syntax string that is the images of any macro functions that must
185209 * be evaluated at a later time.
186210 */
187- private static Map <String , String > reconstructMacroFunctionsBeforeDeferring (
211+ private static void reconstructMacroFunctionsBeforeDeferring (
212+ PrefixToPreserveState prefixToPreserveState ,
188213 Set <String > deferredWords ,
189214 JinjavaInterpreter interpreter
190215 ) {
191216 Set <String > toRemove = new HashSet <>();
192217 Map <String , MacroFunction > macroFunctions = deferredWords
193218 .stream ()
219+ .filter (w -> !prefixToPreserveState .containsKey (w ))
194220 .filter (w -> !interpreter .getContext ().containsKey (w ))
195221 .map (w -> interpreter .getContext ().getGlobalMacro (w ))
196222 .filter (Objects ::nonNull )
@@ -230,37 +256,38 @@ private static Map<String, String> reconstructMacroFunctionsBeforeDeferring(
230256 .collect (
231257 Collectors .toMap (Entry ::getKey , entry -> entry .getValue ().asTemplateString ())
232258 );
259+ prefixToPreserveState .withAll (reconstructedMacros );
233260 // Remove macro functions from the set because they've been fully processed now.
234261 deferredWords .removeAll (toRemove );
235- return reconstructedMacros ;
236262 }
237263
238- private static Map <String , String > reconstructSetVariablesBeforeDeferring (
264+ private static void reconstructSetVariablesBeforeDeferring (
265+ PrefixToPreserveState prefixToPreserveState ,
239266 Set <String > deferredWords ,
240- JinjavaInterpreter interpreter
267+ JinjavaInterpreter interpreter ,
268+ int depth
241269 ) {
242- if (deferredWords .isEmpty ()) {
243- return Collections .emptyMap ();
244- }
245270 Set <String > metaContextVariables = interpreter .getContext ().getMetaContextVariables ();
246- return deferredWords
271+ deferredWords
247272 .stream ()
273+ .filter (w -> !metaContextVariables .contains (w ))
274+ .filter (w -> !prefixToPreserveState .containsKey (w ))
275+ .map (
276+ word ->
277+ new AbstractMap .SimpleImmutableEntry <>(word , interpreter .getContext ().get (word ))
278+ )
248279 .filter (
249- w ->
250- interpreter .getContext ().containsKey (w ) &&
251- !(interpreter .getContext ().get (w ) instanceof DeferredValue )
280+ entry -> entry .getValue () != null && !(entry .getValue () instanceof DeferredValue )
252281 )
253- .filter (w -> !metaContextVariables .contains (w ))
254- .collect (
255- Collectors .toMap (
256- Function .identity (),
257- word ->
258- buildBlockOrInlineSetTag (
259- word ,
260- interpreter .getContext ().get (word ),
261- interpreter
262- )
263- )
282+ .forEach (
283+ entry ->
284+ buildBlockOrInlineSetTagRecursively (
285+ prefixToPreserveState ,
286+ entry .getKey (),
287+ entry .getValue (),
288+ interpreter ,
289+ depth
290+ )
264291 );
265292 }
266293
@@ -280,7 +307,47 @@ public static String buildBlockOrInlineSetTagAndRegisterDeferredToken(
280307 return buildBlockOrInlineSetTag (name , value , interpreter , true );
281308 }
282309
283- public static String buildBlockOrInlineSetTag (
310+ private static void buildBlockOrInlineSetTagRecursively (
311+ PrefixToPreserveState prefixToPreserveState ,
312+ String name ,
313+ Object value ,
314+ JinjavaInterpreter interpreter ,
315+ int depth
316+ ) {
317+ if (value instanceof DeferredValue || value instanceof PyishBlockSetSerializable ) {
318+ prefixToPreserveState .put (
319+ name ,
320+ buildBlockOrInlineSetTag (name , value , interpreter , false )
321+ );
322+ return ;
323+ }
324+ String pyishStringRepresentation = PyishObjectMapper .getAsPyishString (value );
325+
326+ if (
327+ depth > 0 &&
328+ depth < interpreter .getConfig ().getMaxRenderDepth () &&
329+ interpreter .getConfig ().isNestedInterpretationEnabled ()
330+ ) {
331+ Set <String > dependentWords = EagerExpressionResolver .findDeferredWords (
332+ pyishStringRepresentation ,
333+ interpreter
334+ );
335+ if (!dependentWords .isEmpty ()) {
336+ reconstructFromContextBeforeDeferringAsMap (
337+ prefixToPreserveState ,
338+ dependentWords ,
339+ interpreter ,
340+ depth + 1
341+ );
342+ }
343+ }
344+ prefixToPreserveState .put (
345+ name ,
346+ buildSetTag (ImmutableMap .of (name , pyishStringRepresentation ), interpreter , false )
347+ );
348+ }
349+
350+ private static String buildBlockOrInlineSetTag (
284351 String name ,
285352 Object value ,
286353 JinjavaInterpreter interpreter ,
@@ -300,13 +367,8 @@ public static String buildBlockOrInlineSetTag(
300367 registerDeferredToken
301368 );
302369 }
303- String pyishStringRepresentation = PyishObjectMapper .getAsPyishString (value );
304- Set <String > dependentWords = EagerExpressionResolver .findDeferredWords (
305- pyishStringRepresentation ,
306- interpreter
307- );
308370 return buildSetTag (
309- ImmutableMap .of (name , pyishStringRepresentation ),
371+ ImmutableMap .of (name , PyishObjectMapper . getAsPyishString ( value ) ),
310372 interpreter ,
311373 registerDeferredToken
312374 );
0 commit comments