diff --git a/pom.xml b/pom.xml
index 9518a2a85..1f44875e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,6 +19,8 @@
0.8.3
3.0.1
+ 1.9
+
--add-opens=java.base/java.lang=ALL-UNNAMED
@@ -89,6 +91,16 @@
jackson-datatype-jdk8
2.14.0
+
+ com.hubspot.immutables
+ hubspot-style
+ ${dep.hubspot-immutables.version}
+
+
+ com.hubspot.immutables
+ immutables-exceptions
+ ${dep.hubspot-immutables.version}
+
@@ -187,6 +199,20 @@
mockito-core
test
+
+ org.immutables
+ value
+ provided
+
+
+ com.hubspot.immutables
+ hubspot-style
+ provided
+
+
+ com.hubspot.immutables
+ immutables-exceptions
+
diff --git a/src/main/java/com/hubspot/jinjava/interpret/Context.java b/src/main/java/com/hubspot/jinjava/interpret/Context.java
index b619a6238..1ea7aaf71 100644
--- a/src/main/java/com/hubspot/jinjava/interpret/Context.java
+++ b/src/main/java/com/hubspot/jinjava/interpret/Context.java
@@ -22,7 +22,6 @@
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.hubspot.jinjava.lib.Importable;
-import com.hubspot.jinjava.lib.expression.DefaultExpressionStrategy;
import com.hubspot.jinjava.lib.expression.ExpressionStrategy;
import com.hubspot.jinjava.lib.exptest.ExpTest;
import com.hubspot.jinjava.lib.exptest.ExpTestLibrary;
@@ -65,11 +64,11 @@ public class Context extends ScopeMap {
private Map> disabled;
public boolean isValidationMode() {
- return validationMode;
+ return contextConfiguration.isValidationMode();
}
public Context setValidationMode(boolean validationMode) {
- this.validationMode = validationMode;
+ contextConfiguration = contextConfiguration.withValidationMode(validationMode);
return this;
}
@@ -101,8 +100,6 @@ public enum Library {
private final FunctionLibrary functionLibrary;
private final TagLibrary tagLibrary;
- private ExpressionStrategy expressionStrategy = new DefaultExpressionStrategy();
-
private final Context parent;
private int renderDepth = -1;
@@ -110,14 +107,7 @@ public enum Library {
private List extends Node> superBlock;
private final Stack renderStack = new Stack<>();
-
- private boolean validationMode = false;
- private boolean deferredExecutionMode = false;
- private boolean deferLargeObjects = false;
- private boolean throwInterpreterErrors = false;
- private boolean partialMacroEvaluation = false;
- private boolean unwrapRawOverride = false;
- private DynamicVariableResolver dynamicVariableResolver = null;
+ private ContextConfiguration contextConfiguration = ContextConfiguration.of();
private final Set metaContextVariables; // These variable names aren't tracked in eager execution
private final Set overriddenNonMetaContextVariables;
private Node currentNode;
@@ -215,13 +205,7 @@ public Context(
this.overriddenNonMetaContextVariables =
parent == null ? new HashSet<>() : parent.overriddenNonMetaContextVariables;
if (parent != null) {
- this.expressionStrategy = parent.expressionStrategy;
- this.partialMacroEvaluation = parent.partialMacroEvaluation;
- this.unwrapRawOverride = parent.unwrapRawOverride;
- this.dynamicVariableResolver = parent.dynamicVariableResolver;
- this.deferredExecutionMode = parent.deferredExecutionMode;
- this.deferLargeObjects = parent.deferLargeObjects;
- this.throwInterpreterErrors = parent.throwInterpreterErrors;
+ this.contextConfiguration = parent.contextConfiguration;
}
}
@@ -654,21 +638,23 @@ public void registerTag(Tag t) {
}
public DynamicVariableResolver getDynamicVariableResolver() {
- return dynamicVariableResolver;
+ return contextConfiguration.getDynamicVariableResolver();
}
public void setDynamicVariableResolver(
final DynamicVariableResolver dynamicVariableResolver
) {
- this.dynamicVariableResolver = dynamicVariableResolver;
+ contextConfiguration =
+ contextConfiguration.withDynamicVariableResolver(dynamicVariableResolver);
}
public ExpressionStrategy getExpressionStrategy() {
- return expressionStrategy;
+ return contextConfiguration.getExpressionStrategy();
}
public void setExpressionStrategy(ExpressionStrategy expressionStrategy) {
- this.expressionStrategy = expressionStrategy;
+ contextConfiguration =
+ contextConfiguration.withExpressionStrategy(expressionStrategy);
}
public Optional getImportResourceAlias() {
@@ -754,20 +740,21 @@ public SetMultimap getDependencies() {
}
public boolean isDeferredExecutionMode() {
- return deferredExecutionMode;
+ return contextConfiguration.isDeferredExecutionMode();
}
public Context setDeferredExecutionMode(boolean deferredExecutionMode) {
- this.deferredExecutionMode = deferredExecutionMode;
+ contextConfiguration =
+ contextConfiguration.withDeferredExecutionMode(deferredExecutionMode);
return this;
}
public boolean isDeferLargeObjects() {
- return deferLargeObjects;
+ return contextConfiguration.isDeferLargeObjects();
}
public Context setDeferLargeObjects(boolean deferLargeObjects) {
- this.deferLargeObjects = deferLargeObjects;
+ contextConfiguration = contextConfiguration.withDeferLargeObjects(deferLargeObjects);
return this;
}
@@ -775,27 +762,29 @@ public TemporaryValueClosable withDeferLargeObjects(
boolean deferLargeObjects
) {
TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>(
- this.deferLargeObjects,
+ isDeferLargeObjects(),
this::setDeferLargeObjects
);
- this.deferLargeObjects = deferLargeObjects;
+ setDeferLargeObjects(deferLargeObjects);
return temporaryValueClosable;
}
public boolean getThrowInterpreterErrors() {
- return throwInterpreterErrors;
+ return contextConfiguration.isThrowInterpreterErrors();
}
public void setThrowInterpreterErrors(boolean throwInterpreterErrors) {
- this.throwInterpreterErrors = throwInterpreterErrors;
+ contextConfiguration =
+ contextConfiguration.withThrowInterpreterErrors(throwInterpreterErrors);
}
public boolean isPartialMacroEvaluation() {
- return partialMacroEvaluation;
+ return contextConfiguration.isPartialMacroEvaluation();
}
public void setPartialMacroEvaluation(boolean partialMacroEvaluation) {
- this.partialMacroEvaluation = partialMacroEvaluation;
+ contextConfiguration =
+ contextConfiguration.withPartialMacroEvaluation(partialMacroEvaluation);
}
public TemporaryValueClosable withPartialMacroEvaluation() {
@@ -806,27 +795,27 @@ public TemporaryValueClosable withPartialMacroEvaluation(
boolean partialMacroEvaluation
) {
TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>(
- this.partialMacroEvaluation,
+ isPartialMacroEvaluation(),
this::setPartialMacroEvaluation
);
- this.partialMacroEvaluation = partialMacroEvaluation;
+ setPartialMacroEvaluation(partialMacroEvaluation);
return temporaryValueClosable;
}
public boolean isUnwrapRawOverride() {
- return unwrapRawOverride;
+ return contextConfiguration.isUnwrapRawOverride();
}
public void setUnwrapRawOverride(boolean unwrapRawOverride) {
- this.unwrapRawOverride = unwrapRawOverride;
+ contextConfiguration = contextConfiguration.withUnwrapRawOverride(unwrapRawOverride);
}
public TemporaryValueClosable withUnwrapRawOverride() {
TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>(
- this.unwrapRawOverride,
+ isUnwrapRawOverride(),
this::setUnwrapRawOverride
);
- this.unwrapRawOverride = true;
+ setUnwrapRawOverride(true);
return temporaryValueClosable;
}
diff --git a/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java b/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java
new file mode 100644
index 000000000..5aac82fa8
--- /dev/null
+++ b/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java
@@ -0,0 +1,50 @@
+package com.hubspot.jinjava.interpret;
+
+import com.hubspot.immutables.style.HubSpotImmutableStyle;
+import com.hubspot.jinjava.lib.expression.DefaultExpressionStrategy;
+import com.hubspot.jinjava.lib.expression.ExpressionStrategy;
+import javax.annotation.Nullable;
+import org.immutables.value.Value.Default;
+import org.immutables.value.Value.Immutable;
+
+@Immutable(singleton = true)
+@HubSpotImmutableStyle
+public interface ContextConfigurationIF {
+ @Default
+ default ExpressionStrategy getExpressionStrategy() {
+ return new DefaultExpressionStrategy();
+ }
+
+ @Nullable
+ DynamicVariableResolver getDynamicVariableResolver();
+
+ @Default
+ default boolean isValidationMode() {
+ return false;
+ }
+
+ @Default
+ default boolean isDeferredExecutionMode() {
+ return false;
+ }
+
+ @Default
+ default boolean isDeferLargeObjects() {
+ return false;
+ }
+
+ @Default
+ default boolean isThrowInterpreterErrors() {
+ return false;
+ }
+
+ @Default
+ default boolean isPartialMacroEvaluation() {
+ return false;
+ }
+
+ @Default
+ default boolean isUnwrapRawOverride() {
+ return false;
+ }
+}