This is an automated email from the ASF dual-hosted git repository.

jadams pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git

commit e9d240727791964966c14a38dd7008ee8ed4ddd2
Author: Josh Adams <[email protected]>
AuthorDate: Fri Oct 23 15:33:58 2020 -0400

    Improve newVariableInstace defaultValue expressions
    
    This commit enables newVariableInstance's to have non-constant default
    value expressions.  These expressions are evaluated when the
    newVariableInstance is created.
    
    DAFFODIL-2352
---
 .../apache/daffodil/dsom/DFDLDefineVariable.scala  |  2 +-
 .../unparsers/ExpressionEvaluatingUnparsers.scala  |  3 +-
 .../apache/daffodil/processors/RuntimeData.scala   |  4 +-
 .../apache/daffodil/processors/VariableMap1.scala  | 11 +++-
 .../parsers/ExpressionEvaluatingParsers.scala      |  2 +-
 .../daffodil/processors/parsers/PState.scala       |  4 +-
 .../daffodil/processors/unparsers/UState.scala     |  4 +-
 .../daffodil/section07/variables/variables.tdml    | 67 ++++++++++++++++++++++
 .../section07/variables/TestVariables.scala        |  3 +
 9 files changed, 89 insertions(+), 11 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
index 41d7b97..a449592 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
@@ -62,7 +62,7 @@ class DFDLDefineVariable(node: Node, doc: SchemaDocument)
   final lazy val primType = PrimType.fromNameString(typeQName.local).getOrElse(
     this.SDE("Variables must have primitive type. Type was '%s'.", 
typeQName.toPrettyString))
 
-  final def createVariableInstance = variableRuntimeData.createVariableInstance
+  final def createVariableInstance = 
variableRuntimeData.createVariableInstance()
 
   final override lazy val runtimeData = variableRuntimeData
 
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
index 719cc34..855e54c 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
@@ -87,7 +87,8 @@ class NewVariableInstanceStartUnparser(override val context: 
RuntimeData)
   override lazy val childProcessors = Vector()
 
   override def unparse(state: UState) = {
-    state.newVariableInstance(context.asInstanceOf[VariableRuntimeData])
+    val vrd = context.asInstanceOf[VariableRuntimeData]
+    state.newVariableInstance(vrd, vrd, state)
   }
 }
 
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
index da76ce8..c80e2c7 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
@@ -987,6 +987,8 @@ final class VariableRuntimeData(
       }
     }
 
-  def createVariableInstance: VariableInstance = VariableInstance(state, 
value, this, maybeDefaultValueExpr)
+  def createVariableInstance(defaultValue: DataValuePrimitiveNullable = 
value): VariableInstance = {
+    VariableInstance(state, defaultValue, this, maybeDefaultValueExpr)
+  }
 
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/VariableMap1.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/VariableMap1.scala
index 3346540..5c31336 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/VariableMap1.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/VariableMap1.scala
@@ -173,7 +173,7 @@ class VariableMap private(vTable: Map[GlobalQName, 
MStackOf[VariableInstance]])
   def this(topLevelVRDs: Seq[VariableRuntimeData] = Nil) =
     this(Map(topLevelVRDs.map {
       vrd =>
-        val variab = vrd.createVariableInstance
+        val variab = vrd.createVariableInstance()
         val stack = new MStackOf[VariableInstance]
         stack.push(variab)
         (vrd.globalQName, stack)
@@ -286,11 +286,16 @@ class VariableMap private(vTable: Map[GlobalQName, 
MStackOf[VariableInstance]])
   /**
    * Creates a new instance of a variable
    */
-  def newVariableInstance(vrd: VariableRuntimeData) = {
+  def newVariableInstance(vrd: VariableRuntimeData, referringContext: 
ThrowsSDE, state: ParseOrUnparseState) = {
     val varQName = vrd.globalQName
     val stack = vTable.get(varQName)
     Assert.invariant(stack.isDefined)
-    stack.get.push(vrd.createVariableInstance)
+
+    if (vrd.maybeDefaultValueExpr.isDefined) {
+      val defaultValue = 
DataValue.unsafeFromAnyRef(vrd.maybeDefaultValueExpr.get.evaluate(state))
+      
stack.get.push(vrd.createVariableInstance(VariableUtils.convert(defaultValue.getAnyRef.toString,
 vrd, referringContext)))
+    } else
+      stack.get.push(vrd.createVariableInstance())
   }
 
   def removeVariableInstance(vrd: VariableRuntimeData): Unit = {
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ExpressionEvaluatingParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ExpressionEvaluatingParsers.scala
index e7c24a1..2dc1c1c 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ExpressionEvaluatingParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ExpressionEvaluatingParsers.scala
@@ -165,7 +165,7 @@ class NewVariableInstanceStartParser(override val context: 
VariableRuntimeData)
   override lazy val runtimeDependencies = Vector()
 
   def parse(start: PState): Unit = {
-    start.newVariableInstance(context)
+    start.newVariableInstance(context, context, start)
   }
 }
 
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
index 99c7194..09018d0 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
@@ -343,8 +343,8 @@ final class PState private (
     changedVariablesStack.top += vrd.globalQName
   }
 
-  def newVariableInstance(vrd: VariableRuntimeData): Unit = {
-    variableMap.newVariableInstance(vrd)
+  def newVariableInstance(vrd: VariableRuntimeData, referringContext: 
VariableRuntimeData, pstate: PState): Unit = {
+    variableMap.newVariableInstance(vrd, referringContext, pstate)
     changedVariablesStack.top += vrd.globalQName
   }
 
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
index 888dd55..f033e1b 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
@@ -343,8 +343,8 @@ abstract class UState(
 
   def documentElement: DIDocument
 
-  def newVariableInstance(vrd: VariableRuntimeData): Unit = {
-    variableMap.newVariableInstance(vrd)
+  def newVariableInstance(vrd: VariableRuntimeData, referringContext: 
VariableRuntimeData, ustate: UState): Unit = {
+    variableMap.newVariableInstance(vrd, referringContext, ustate)
   }
 
   def removeVariableInstance(vrd: VariableRuntimeData): Unit = {
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
index 37cf970..453c2ec 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
@@ -33,6 +33,10 @@
       defaultValue="16" />
     <dfdl:defineVariable name="myVar3" type="xs:int"
       defaultValue="26" />
+    <!--<dfdl:defineVariable name="myVar4" type="xs:int"
+      defaultValue="36" />
+    <dfdl:defineVariable name="nonConstVar" type="xs:int"
+      defaultValue="{ $ex:myVar4 }" />-->
     <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" />
     <xs:element name="c">
@@ -408,6 +412,37 @@
       </xs:complexType>
     </xs:element>
 
+    <xs:element name="nvi12">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="oldVarValue" type="xsd:int" dfdl:inputValueCalc="{ 
$ex:myVar1 }" />
+          <xs:element name="newDefaultValue" type="xsd:int" 
dfdl:lengthKind="explicit" dfdl:length="1" />
+          <xs:element name="innerSeq">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:annotation>
+                  <xs:appinfo source="http://www.ogf.org/dfdl/";>
+                    <dfdl:newVariableInstance ref="ex:myVar1"
+                      defaultValue="{ ../ex:newDefaultValue }" />
+                  </xs:appinfo>
+                </xs:annotation>
+                <xs:element name="newVarValue" type="xs:int"
+                  dfdl:inputValueCalc="{ $ex:myVar1 }" />
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <!--<xs:element name="defNonConst">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="value" type="xsd:int" dfdl:inputValueCalc="{ 
$ex:nonConstVar }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>-->
+
     <xs:element name="e1">
       <xs:complexType>
         <xs:sequence dfdl:separator="{ $ex:v1_with_default }"
@@ -912,6 +947,38 @@
     </tdml:errors>
   </tdml:parserTestCase>
 
+  <tdml:parserTestCase name="varInstance_12" root="nvi12"
+    model="v"
+    description="newVariablesInstance with a non-constant expression as 
defaultValue">
+
+    <tdml:document><![CDATA[7]]></tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <nvi12 xmlns="http://example.com";>
+          <oldVarValue xsi:type="xsd:int">6</oldVarValue>
+          <newDefaultValue xsi:type="xsd:int">7</newDefaultValue>
+          <innerSeq>
+            <newVarValue xsi:type="xsd:int">7</newVarValue>
+          </innerSeq>
+        </nvi12>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <!--<tdml:parserTestCase name="defineVariable_nonConstantExpression" 
root="defNonConst"
+    model="v"
+    description="defineVariable with a non-constant expression as 
defaultValue">
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <defNonConst xmlns="http://example.com";>
+          <value>36</value>
+        </defNonConst>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>-->
+
   <tdml:parserTestCase name="varAsSeparator" root="e1"
     model="v"
     description="variable referenced as a separator; the defineVariable 
annotation occurs after the element declaration that references it - 
DFDL-7-107R">
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
index ff4d01f..9f81647 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
@@ -59,6 +59,9 @@ class TestVariables {
   @Test def test_varInstance_09(): Unit = { 
runner.runOneTest("varInstance_09") }
   @Test def test_varInstance_10(): Unit = { 
runner.runOneTest("varInstance_10") }
   @Test def test_varInstance_11(): Unit = { 
runner.runOneTest("varInstance_11") }
+  @Test def test_varInstance_12(): Unit = { 
runner.runOneTest("varInstance_12") }
+  // Causes OOLAG Circular Definition
+  // @Test def test_defineVariable_nonConstantExpression(): Unit = { 
runner.runOneTest("defineVariable_nonConstantExpression") }
   @Test def test_setVarChoice(): Unit = { runner.runOneTest("setVarChoice") }
   @Test def test_unparse_setVarChoice(): Unit = { 
runner.runOneTest("unparse_setVarChoice") }
   @Test def test_setVarOnSeqAndElemRef(): Unit = { 
runner.runOneTest("setVarOnSeqAndElemRef") }

Reply via email to