You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mb...@apache.org on 2018/08/15 12:59:55 UTC

[incubator-daffodil] 01/02: Eliminates backpointers from RuntimeData structures.

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

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

commit 06b3061a24521d9ad4cea0648900723c560c4d39
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Fri Mar 30 15:04:00 2018 -0400

    Eliminates backpointers from RuntimeData structures.
    
    This is a step toward eliminating the double-linked non-sharing behavior
    in the schema compiler, because maintaining these double-linked pointers
    for the runtime was forcing them to exist in the schema compiler also.
    
    DAFFODIL-1444
---
 .../org/apache/daffodil/dsom/ChoiceGroup.scala     |  5 ---
 .../org/apache/daffodil/dsom/ElementBase.scala     | 25 +-----------
 .../org/apache/daffodil/dsom/SchemaComponent.scala |  3 --
 .../org/apache/daffodil/dsom/SequenceGroup.scala   | 13 +------
 .../unparsers/SequenceChildUnparsers.scala         | 21 +++--------
 .../apache/daffodil/processors/RuntimeData.scala   | 44 ++--------------------
 6 files changed, 11 insertions(+), 100 deletions(-)

diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
index 9bf9fe2..d665355 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
@@ -253,11 +253,6 @@ abstract class ChoiceTermBase(
       namespaces,
       defaultBitOrder,
       groupMembersRuntimeData,
-      enclosingElement.map { _.elementRuntimeData }.getOrElse(
-        Assert.invariantFailed("model group with no surrounding element.")),
-      enclosingTerm.map { _.termRuntimeData }.getOrElse {
-        Assert.invariantFailed("model group with no surrounding term.")
-      },
       isRepresented,
       couldHaveText,
       alignmentValueInBits,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
index fcd7d7c..c968603 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
@@ -479,34 +479,11 @@ trait ElementBase
   }.value
 
   protected def computeElementRuntimeData(): ElementRuntimeData = {
-    val ee = enclosingElement
-    //
-    // Must be lazy below, because we are defining the elementRuntimeData in terms of
-    // the elementRuntimeData of its enclosing element. This backpointer must be
-    // constructed lazily so that we first connect up all the erds to their children,
-    // and only subsequently ask for these parents to be elaborated.
-    //
-    lazy val parent = ee.map { enc =>
-      Assert.invariant(this != enc)
-      enc.elementRuntimeData
-    }
-    lazy val parentTerm = this.enclosingTerm.map { enc =>
-      Assert.invariant(this != enc)
-      enc.termRuntimeData
-    }
-
-    //
-    // I got sick of initialization time problems, so this mutual recursion
-    // defines the tree of ERDs.
-    //
-    // This works because of deferred arguments and lazy evaluation
-    //
+    
     lazy val childrenERDs: Seq[ElementRuntimeData] =
       elementChildren.map { _.elementRuntimeData }
 
     val newERD: ElementRuntimeData = new ElementRuntimeData(
-      parent,
-      parentTerm,
       childrenERDs,
       schemaSet.variableMap,
       nextElementResolver,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
index 103ce0e..935ed0e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
@@ -24,7 +24,6 @@ import org.apache.daffodil.xml.NS
 import org.apache.daffodil.xml.XMLUtils
 import org.apache.daffodil.processors.NonTermRuntimeData
 import org.apache.daffodil.processors.RuntimeData
-import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.processors.VariableMap
 import org.apache.daffodil.processors.NonTermRuntimeData
 import org.apache.daffodil.xml.ResolvesQNames
@@ -91,8 +90,6 @@ trait SchemaComponent
       diagnosticDebugName,
       path,
       namespaces,
-      enclosingElement.map { _.erd },
-      Maybe.toMaybe(enclosingTerm.map { _.termRuntimeData }),
       tunable)
   }.value
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
index c85f8c3..795ebdb 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
@@ -27,7 +27,6 @@ import org.apache.daffodil.schema.annotation.props.gen.OccursCountKind
 import org.apache.daffodil.schema.annotation.props.gen.SequenceKind
 import org.apache.daffodil.Implicits.ns2String
 import org.apache.daffodil.grammar.SequenceGrammarMixin
-import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.processors.SequenceRuntimeData
 import org.apache.daffodil.schema.annotation.props.Found
 import org.apache.daffodil.schema.annotation.props.PropertyLookupResult
@@ -39,6 +38,7 @@ import org.apache.daffodil.processors.SeparatorParseEv
 import org.apache.daffodil.processors.ModelGroupRuntimeData
 import org.apache.daffodil.schema.annotation.props.gen.LayerLengthUnits
 import org.apache.daffodil.processors.SeparatorUnparseEv
+import org.apache.daffodil.exceptions.Assert
 
 /**
  * Base for anything sequence-like.
@@ -228,11 +228,6 @@ abstract class SequenceGroupTermBase(
       namespaces,
       defaultBitOrder,
       groupMembersRuntimeData,
-      enclosingElement.map { _.elementRuntimeData }.getOrElse(
-        Assert.invariantFailed("model group with no surrounding element.")),
-      enclosingTerm.map { _.termRuntimeData }.getOrElse {
-        Assert.invariantFailed("model group with no surrounding term.")
-      },
       isRepresented,
       couldHaveText,
       alignmentValueInBits,
@@ -377,7 +372,6 @@ final class ChoiceBranchImpliedSequence(rawGM: Term)
     new SequenceRuntimeData(
       schemaSet.variableMap,
       encodingInfo,
-      // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
       schemaFileLocation,
       dpathCompileInfo,
       diagnosticDebugName,
@@ -385,11 +379,6 @@ final class ChoiceBranchImpliedSequence(rawGM: Term)
       namespaces,
       defaultBitOrder,
       groupMembersRuntimeData,
-      enclosingElement.map { _.elementRuntimeData }.getOrElse(
-        Assert.invariantFailed("model group with no surrounding element.")),
-      enclosingTerm.map { _.termRuntimeData }.getOrElse {
-        Assert.invariantFailed("model group with no surrounding term.")
-      },
       isRepresented,
       couldHaveText,
       alignmentValueInBits,
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SequenceChildUnparsers.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SequenceChildUnparsers.scala
index 0583a96..3690ad3 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SequenceChildUnparsers.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SequenceChildUnparsers.scala
@@ -170,23 +170,12 @@ abstract class RepeatingChildUnparser(
                 false // event not a start for this element
               }
             } else if (ev.isEnd && ev.isComplex) {
-              val c = ev.asComplex
-              //ok. We've peeked ahead and found the end of the complex element
+              //ok. We've peeked ahead and found the end of a complex element.
+              // It has to be the complex element that ultimately encloses this sequence.
+              // Though that's not a unique element given that this sequence could be inside
+              // a global group definition that is reused in muliple places.
               //that this sequence is the model group of.
-              val optParentRD = srd.immediateEnclosingElementRuntimeData
-              // FIXME: there's no reason to walk backpointer to immediateEnclosingElementRuntimeData
-              // as we just want that element's name, and we could precompute that and
-              // include it on the SequenceChildUnparser for this
-              optParentRD match {
-                case Some(e: ElementRuntimeData) => {
-                  Assert.invariant(c.runtimeData.namedQName =:= e.namedQName)
-                  // System.err.println("Stopping occurrences(2) of %s due to event %s".format(erd.namedQName, ev))
-                  false
-                }
-                case _ =>
-                  Assert.invariantFailed("Not end element for this sequence's containing element. Event %s, optParentRD %s.".format(
-                    ev, optParentRD))
-              }
+              false
             } else {
               // end of simple element. We shouldUnparse on the start event.
               // System.err.println("Stopping occurrences(3) of %s due to event %s".format(erd.namedQName, ev))
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 9291150..93f7bf1 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
@@ -77,8 +77,6 @@ sealed trait RuntimeData
   val path: String
   val namespaces: NamespaceBinding
 
-  def immediateEnclosingElementRuntimeData: Option[ElementRuntimeData]
-  def immediateEnclosingTermRuntimeData: Maybe[TermRuntimeData]
   def variableMap: VariableMap
   override def toString = diagnosticDebugName
 
@@ -104,8 +102,6 @@ sealed abstract class TermRuntimeData(
    * hook these objects into a parent-child tree without
    * having to use an assignment to a var.
    */
-  @TransientParam immediateEnclosingElementRuntimeDataArg: => Option[ElementRuntimeData],
-  @TransientParam immedEnclosingTermRuntimeDataArg: => Maybe[TermRuntimeData],
   @TransientParam encodingInfoArg: => EncodingRuntimeData,
   @TransientParam dpathCompileInfoArg: => DPathCompileInfo,
   @TransientParam isRepresentedArg: => Boolean,
@@ -148,8 +144,6 @@ sealed abstract class TermRuntimeData(
    */
   def tunable = dpathCompileInfo.tunable
 
-  lazy val immediateEnclosingElementRuntimeData = immediateEnclosingElementRuntimeDataArg
-  lazy val immediateEnclosingTermRuntimeData = immedEnclosingTermRuntimeDataArg
   lazy val encodingInfo = encodingInfoArg
   lazy val dpathCompileInfo = dpathCompileInfoArg
   lazy val isRepresented = isRepresentedArg
@@ -164,8 +158,6 @@ sealed abstract class TermRuntimeData(
 
   override def preSerialization: Unit = {
     super.preSerialization
-    immediateEnclosingElementRuntimeData
-    immediateEnclosingTermRuntimeData
     encodingInfo
     dpathCompileInfo
     isRepresented
@@ -195,8 +187,6 @@ sealed class NonTermRuntimeData(
   @TransientParam diagnosticDebugNameArg: => String,
   @TransientParam pathArg: => String,
   @TransientParam namespacesArg: => NamespaceBinding,
-  @TransientParam immediateEnclosingElementRuntimeDataArg: => Option[ElementRuntimeData],
-  @TransientParam immedEnclosingTermRuntimeDataArg: => Maybe[TermRuntimeData],
   @TransientParam tunableArg: => DaffodilTunables)
   extends RuntimeData
   with PreSerialization {
@@ -206,8 +196,6 @@ sealed class NonTermRuntimeData(
   lazy val diagnosticDebugName = diagnosticDebugNameArg
   lazy val path = pathArg
   lazy val namespaces = namespacesArg
-  lazy val immediateEnclosingElementRuntimeData = immediateEnclosingElementRuntimeDataArg
-  lazy val immediateEnclosingTermRuntimeData = immedEnclosingTermRuntimeDataArg
   lazy val tunable = tunableArg
 
   override def preSerialization: Unit = {
@@ -217,8 +205,6 @@ sealed class NonTermRuntimeData(
     diagnosticDebugName
     path
     namespaces
-    immediateEnclosingElementRuntimeData
-    immediateEnclosingTermRuntimeData
     tunable
   }
   @throws(classOf[java.io.IOException])
@@ -252,7 +238,7 @@ final class SimpleTypeRuntimeData(
   @TransientParam fractionDigitsArg: => Option[java.math.BigDecimal],
   @TransientParam unionMemberTypesArg: => Seq[SimpleTypeRuntimeData],
   @TransientParam tunableArg: => DaffodilTunables) extends NonTermRuntimeData(variableMapArg, schemaFileLocationArg, diagnosticDebugNameArg,
-  pathArg, namespacesArg, None, None, tunableArg) {
+  pathArg, namespacesArg, tunableArg) {
 
   import OKOrError._
 
@@ -604,8 +590,6 @@ final class ElementRuntimeData(
    * all transient elements must be added to the preSerialization method below
    * to allow parser serialization/deserialization to work.
    */
-  @TransientParam parentArg: => Option[ElementRuntimeData],
-  @TransientParam parentTermArg: => Maybe[TermRuntimeData],
   @TransientParam childrenArg: => Seq[ElementRuntimeData],
   @TransientParam variableMapArg: => VariableMap,
   @TransientParam nextElementResolverArg: => NextElementResolver,
@@ -659,15 +643,13 @@ final class ElementRuntimeData(
   @TransientParam maybeFillByteEvArg: => Maybe[FillByteEv],
   @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
   @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
-  extends TermRuntimeData(parentArg, parentTermArg, encInfoArg, dpathElementCompileInfoArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
+  extends TermRuntimeData(encInfoArg, dpathElementCompileInfoArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
     defaultBitOrderArg, optIgnoreCaseArg, maybeFillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg) {
 
   override def isRequiredScalar = !isArray && isRequiredOrOptional
 
-  lazy val parent = parentArg
-  lazy val parentTerm = parentTermArg
   lazy val children = childrenArg
   lazy val variableMap = variableMapArg
   lazy val nextElementResolver = nextElementResolverArg
@@ -704,8 +686,6 @@ final class ElementRuntimeData(
 
   override def preSerialization: Unit = {
     super.preSerialization
-    parent
-    parentTerm
     children
     variableMap
     nextElementResolver
@@ -744,8 +724,6 @@ final class ElementRuntimeData(
   @throws(classOf[java.io.IOException])
   final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
 
-  lazy val rootERD: ElementRuntimeData = parent.map { _.rootERD }.getOrElse(this)
-
   final def childERDs = children
 
   def isSimpleType = optPrimType.isDefined
@@ -781,8 +759,6 @@ sealed abstract class ModelGroupRuntimeData(
   @TransientParam namespacesArg: => NamespaceBinding,
   @TransientParam defaultBitOrderArg: => BitOrder,
   @TransientParam groupMembersArg: => Seq[TermRuntimeData],
-  @TransientParam erdArg: ElementRuntimeData,
-  @TransientParam trdArg: => TermRuntimeData,
   @TransientParam isRepresentedArg: => Boolean,
   @TransientParam couldHaveTextArg: => Boolean,
   @TransientParam alignmentValueInBitsArg: => Int,
@@ -792,8 +768,6 @@ sealed abstract class ModelGroupRuntimeData(
   @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
   @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
   extends TermRuntimeData(
-    Some(erdArg),
-    Maybe(trdArg),
     encInfoArg, ciArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
     defaultBitOrderArg, optIgnoreCaseArg, maybeFillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
@@ -810,8 +784,6 @@ sealed abstract class ModelGroupRuntimeData(
   lazy val path = pathArg
   lazy val namespaces = namespacesArg
   lazy val groupMembers = groupMembersArg
-  lazy val erd = erdArg
-  lazy val trd = trdArg
 
   override def preSerialization: Unit = {
     super.preSerialization
@@ -823,8 +795,6 @@ sealed abstract class ModelGroupRuntimeData(
     path
     namespaces
     groupMembers
-    erd
-    trd
   }
   @throws(classOf[java.io.IOException])
   final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
@@ -845,8 +815,6 @@ final class SequenceRuntimeData(
   @TransientParam namespacesArg: => NamespaceBinding,
   @TransientParam defaultBitOrderArg: => BitOrder,
   @TransientParam groupMembersArg: => Seq[TermRuntimeData],
-  @TransientParam erdArg: ElementRuntimeData,
-  @TransientParam trdArg: => TermRuntimeData,
   @TransientParam isRepresentedArg: => Boolean,
   @TransientParam couldHaveTextArg: => Boolean,
   @TransientParam alignmentValueInBitsArg: => Int,
@@ -856,7 +824,7 @@ final class SequenceRuntimeData(
   @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
   @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
   extends ModelGroupRuntimeData(variableMapArg, encInfoArg, schemaFileLocationArg, ciArg, diagnosticDebugNameArg, pathArg, namespacesArg, defaultBitOrderArg, groupMembersArg,
-    erdArg, trdArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg,
+    isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg,
     maybeFillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg)
@@ -876,8 +844,6 @@ final class ChoiceRuntimeData(
   @TransientParam namespacesArg: => NamespaceBinding,
   @TransientParam defaultBitOrderArg: => BitOrder,
   @TransientParam groupMembersArg: => Seq[TermRuntimeData],
-  @TransientParam erdArg: ElementRuntimeData,
-  @TransientParam trdArg: => TermRuntimeData,
   @TransientParam isRepresentedArg: => Boolean,
   @TransientParam couldHaveTextArg: => Boolean,
   @TransientParam alignmentValueInBitsArg: => Int,
@@ -887,7 +853,7 @@ final class ChoiceRuntimeData(
   @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
   @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
   extends ModelGroupRuntimeData(variableMapArg, encInfoArg, schemaFileLocationArg, ciArg, diagnosticDebugNameArg, pathArg, namespacesArg, defaultBitOrderArg, groupMembersArg,
-    erdArg, trdArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg, maybeFillByteEvArg,
+    isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg, maybeFillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg)
 
@@ -908,8 +874,6 @@ final class VariableRuntimeData(
     diagnosticDebugNameArg,
     pathArg,
     namespacesArg,
-    None,
-    None,
     tunableArg)
   with Serializable {