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 2019/11/18 19:09:01 UTC

[incubator-daffodil] branch master updated: Cleanup: create runtime1 package and mixins for Term classes and Gram.

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


The following commit(s) were added to refs/heads/master by this push:
     new 5ec9ba9  Cleanup: create runtime1 package and mixins for Term classes and Gram.
5ec9ba9 is described below

commit 5ec9ba9af71c6d89368d132d31ad0958bac0e6b4
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Wed Nov 13 19:46:04 2019 -0500

    Cleanup: create runtime1 package and mixins for Term classes and Gram.
    
    The purpose here is separation of concerns.
    Things specific to daffodil-runtime1 should be segregated in the schema
    compiler to a package with that specific runtime/backend in mind.
    
    This makes it clear that the dsom and grammar packages are supposed to contain
    backend-independent code.
    
    However, this is a very partial first step in this direction. The
    grammar primitives are still very runtime1-specific with their parser and
    unparser methods. Also the dpath package needs separating as well.
    
    Nevertheless, this change is worth it to help better categorize the
    various schema compiler optimizers and various computed LV "attributes" into
    those that are runtime1 specific, and those that are fully general.
    
    DAFFODIL-2233
---
 .../org/apache/daffodil/dsom/ChoiceGroup.scala     |  93 -------
 .../org/apache/daffodil/dsom/ElementBase.scala     | 229 +-----------------
 .../org/apache/daffodil/dsom/ModelGroup.scala      |  24 +-
 .../org/apache/daffodil/dsom/SequenceGroup.scala   |  52 +---
 .../main/scala/org/apache/daffodil/dsom/Term.scala |  66 +----
 .../daffodil/grammar/ChoiceGrammarMixin.scala      |   5 +-
 .../daffodil/grammar/ElementBaseGrammarMixin.scala | 127 +---------
 .../org/apache/daffodil/grammar/GrammarTerm.scala  |  39 +--
 .../daffodil/grammar/ModelGroupGrammarMixin.scala  |   6 +-
 .../daffodil/grammar/SequenceGrammarMixin.scala    |   5 +-
 .../apache/daffodil/grammar/TermGrammarMixin.scala |   5 +-
 .../runtime1/ChoiceTermRuntime1Mixin.scala         | 129 ++++++++++
 .../runtime1/ElementBaseRuntime1Mixin.scala        | 267 +++++++++++++++++++++
 .../daffodil/runtime1/GramRuntime1Mixin.scala      |  62 +++++
 .../runtime1/ModelGroupRuntime1Mixin.scala         |  48 ++++
 .../runtime1/SequenceTermRuntime1Mixin.scala       |  78 ++++++
 .../daffodil/runtime1/TermRuntime1Mixin.scala      | 114 +++++++++
 .../org/apache/daffodil/runtime1/package.scala     |  31 +++
 18 files changed, 765 insertions(+), 615 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 678bcce..ecd187f 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
@@ -148,18 +148,6 @@ abstract class ChoiceTermBase(
     isDD
   }
 
-  final protected lazy val choiceDispatchKeyExpr = {
-    val qn = this.qNameForProperty("choiceDispatchKey")
-    ExpressionCompilers.String.compileProperty(qn, NodeInfo.NonEmptyString, choiceDispatchKeyRaw, this, dpathCompileInfo)
-  }
-
-  final lazy val choiceDispatchKeyEv = {
-    Assert.invariant(isDirectDispatch)
-    val ev = new ChoiceDispatchKeyEv(choiceDispatchKeyExpr, modelGroupRuntimeData)
-    ev.compile()
-    ev
-  }
-
   // If choiceDispatchKeyKind is byType, verify that all our children share a repType,
   // and use that. Otherwise, there is no need to associate a repType with this choice
   override final lazy val optRepType: Option[SimpleTypeDefBase] = defaultableChoiceDispatchKeyKind match {
@@ -263,87 +251,6 @@ abstract class ChoiceTermBase(
     }
     assuming(branchesOk.forall { x => x })
   }.value
-
-  final def choiceBranchMap: Map[ChoiceBranchEvent, RuntimeData] = LV('choiceBranchMap) {
-    val eventTuples = groupMembers.flatMap {
-      case e: ElementBase => Seq((ChoiceBranchStartEvent(e.namedQName), e))
-      case mg: ModelGroup => {
-        val idEvents = mg.identifyingEventsForChoiceBranch
-        Assert.invariant(!idEvents.isEmpty)
-        idEvents.map { (_, mg) }
-      }
-    }
-
-    // converts a sequence of tuples into a multi-map
-    val eventMap = eventTuples.groupBy { _._1 }.mapValues { _.map(_._2) }
-
-    val noDupes = eventMap.map {
-      case (event, trds) =>
-        if (trds.length > 1) {
-          if (event.isInstanceOf[ChoiceBranchStartEvent] && trds.exists {
-            // any element children in any of the trds?
-            // because if so, we have a true ambiguity here.
-            case sg: SequenceTermBase => {
-              val nonOVCEltChildren = sg.elementChildren.filterNot { _.isOutputValueCalc }
-              nonOVCEltChildren.length > 0
-            }
-            case _ => false
-          }) {
-            // Possibly due to presence of a element with dfdl:outputValueCalc, XML Schema's
-            // UPA check may not catch this ambiguity. However, we need a real element
-            // with unique name, to unambiguously identify a branch.
-            // So if there is ambiguity at this point, we have to fail.
-            SDE(
-              "UPA violation. Multiple choice branches begin with %s.\n" +
-                "Note that elements with dfdl:outputValueCalc cannot be used to distinguish choice branches.\n" +
-                "Note that choice branches with entirely optional content are not allowed.\n" +
-                "The offending choice branches are:\n%s",
-              event.qname, trds.map { trd => "%s at %s".format(trd.diagnosticDebugName, trd.locationDescription) }.mkString("\n"))
-          } else {
-            val eventType = event match {
-              case _: ChoiceBranchEndEvent => "end"
-              case _: ChoiceBranchStartEvent => "start"
-            }
-            // there are no element children in any of the branches.
-            SDW(
-              WarnID.MultipleChoiceBranches,
-              "Multiple choice branches are associated with the %s of element %s.\n" +
-                "Note that elements with dfdl:outputValueCalc cannot be used to distinguish choice branches.\n" +
-                "Note that choice branches with entirely optional content are not allowed.\n" +
-                "The offending choice branches are:\n%s\n" +
-                "The first branch will be used during unparsing when an infoset ambiguity exists.",
-              eventType, event.qname, trds.map { trd => "%s at %s".format(trd.diagnosticDebugName, trd.locationDescription) }.mkString("\n"))
-          }
-        }
-        (event, trds(0).runtimeData)
-    }
-
-    noDupes
-  }.value
-
-  final lazy val modelGroupRuntimeData = choiceRuntimeData
-
-  final lazy val choiceRuntimeData = {
-    new ChoiceRuntimeData(
-      schemaSet.variableMap,
-      encodingInfo,
-      // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
-      schemaFileLocation,
-      dpathCompileInfo,
-      diagnosticDebugName,
-      path,
-      namespaces,
-      defaultBitOrder,
-      groupMembersRuntimeData,
-      isRepresented,
-      couldHaveText,
-      alignmentValueInBits,
-      hasNoSkipRegions,
-      optIgnoreCase,
-      maybeFillByteEv,
-      maybeCheckByteAndBitOrderEv,
-      maybeCheckBitOrderAndCharset)
-  }
 }
 
 final class Choice(xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
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 e2c635a..c6e0568 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
@@ -189,85 +189,6 @@ trait ElementBase
   }
 
   /**
-   * Tells us if, for this element, we need to capture its content length
-   *  at unparse runtime, or we can ignore that.
-   */
-  final lazy val shouldCaptureUnparseContentLength: Boolean = {
-    val isReferenced =
-      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
-      else {
-        val setElems = schemaSet.root.contentLengthUnparserReferencedElementInfos
-        setElems.contains(this.dpathElementCompileInfo)
-      }
-
-    // We need to capture content length when maybeFixedLengthInBits is
-    // defined because it allows us to set absolute start bit positions of
-    // the DOS, even when there are things like padding and OVC that can
-    // cause suspensions that result in relative bit positions. However, we
-    // really only need this if there are going to be suspensions, not on all
-    // fixed length elements. Otherwise, we're capturing content length for
-    // no reason (unless it is referenced in a contentLength expression).
-    val mightHaveSuspensions = (maybeFixedLengthInBits.isDefined && couldHaveSuspensions)
-
-    isReferenced || mightHaveSuspensions
-  }
-
-  /**
-   * Tells us if, for this element, we need to capture its value length
-   *  at parse runtime, or we can ignore that.
-   */
-  final lazy val shouldCaptureParseValueLength: Boolean = {
-    val isReferenced =
-      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
-      else {
-        val setElems = schemaSet.root.valueLengthParserReferencedElementInfos
-        setElems.contains(this.dpathElementCompileInfo)
-      }
-
-    // For simple elements with text representation, valueLength is captured in
-    // individual parsers since they handle removing delimiters and padding.
-    //
-    // For complex elements with specified length, valueLength is captured in
-    // the specified length parsers, since they handle skipping unused
-    // element regions. For complex elements, this means lengthKind is not
-    // implicit or delimited.
-    //
-    // So for these cases we do not want to capture value length, since
-    // they are handled by the parsers as necessary
-    val capturedByParsers =
-      (isSimpleType && impliedRepresentation == Representation.Text) ||
-        (isComplexType && (lengthKind != LengthKind.Implicit && lengthKind != LengthKind.Delimited))
-
-    !capturedByParsers && isReferenced
-  }
-
-  /**
-   * Tells us if, for this element, we need to capture its value length
-   *  at unparse runtime, or we can ignore that.
-   */
-  final lazy val shouldCaptureUnparseValueLength: Boolean = {
-    val isReferenced =
-      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
-      else {
-        val setElems = schemaSet.root.valueLengthUnparserReferencedElementInfos
-        setElems.contains(this.dpathElementCompileInfo)
-      }
-
-    // Besides being referenced by the dfdl:valueLength function,
-    // We need the valueLength to be computed for unparser pad/fill, to check
-    // excess length, and for alignmentFills.
-    //
-    // TBD: why for alignment fills? Don't see using it in the code. Try without this?
-    val pad = this.shouldAddPadding
-    val fill = this.shouldAddFill
-    val len = this.shouldCheckExcessLength
-    val alg = !this.isKnownToBeAligned // alignment fill uses the value length.
-    val mightHaveSuspensions = pad || fill || len || alg
-
-    isReferenced || mightHaveSuspensions
-  }
-
-  /**
    * None for complex types, Some(primType) for simple types.
    */
   final lazy val optPrimType: Option[PrimType] = Misc.boolToOpt(isSimpleType, primType) // .typeRuntimeData)
@@ -278,35 +199,8 @@ trait ElementBase
    */
   def isArraywithAtLeastOneRequiredArrayElement: Boolean
 
-  final override lazy val dpathCompileInfo = dpathElementCompileInfo
-
-  /**
-   * This is the compile info for this element term.
-   */
-  lazy val dpathElementCompileInfo: DPathElementCompileInfo = {
-    val ee = enclosingElements
-    val eci = new DPathElementCompileInfo(
-      ee.map {
-        _.dpathElementCompileInfo
-      },
-      variableMap,
-      elementChildrenCompileInfo,
-      namespaces,
-      slashPath,
-      name,
-      isArray,
-      namedQName,
-      optPrimType,
-      schemaFileLocation,
-      tunable,
-      schemaSet.typeCalcMap,
-      runtimeData,
-      shortSchemaComponentDesignator)
-    eci
-  }
-
-  private lazy val thisElementsNamespace: NS = this.namedQName.namespace
-  private lazy val thisElementsNamespacePrefix: String = this.namespaces.getPrefix(thisElementsNamespace.toString)
+  final protected lazy val thisElementsNamespace: NS = this.namedQName.namespace
+  final protected lazy val thisElementsNamespacePrefix: String = this.namespaces.getPrefix(thisElementsNamespace.toString)
 
   private def nsBindingsToSet(nsb: NamespaceBinding): Set[(String, NS)] = {
     if (nsb == scala.xml.TopScope) Set()
@@ -409,7 +303,7 @@ trait ElementBase
    * To be properly constructed, scala's xml Elems must share the scope (namespace bindings) of the enclosing
    * parent element, except when it adds more of its own bindings, in which case the tail is supposed to be shared.
    */
-  private lazy val minimizedScope: NamespaceBinding = LV('minimizedScope) {
+  final protected lazy val minimizedScope: NamespaceBinding = LV('minimizedScope) {
     val uniquePairs =
       if (this.isInstanceOf[Root]) {
         // If this is the root element and it contains xmlns="", then remove
@@ -431,9 +325,6 @@ trait ElementBase
     pairsToNSBinding(uniquePairs, parentMinimizedScope)
   }.value
 
-  override lazy val runtimeData: RuntimeData = elementRuntimeData
-  override lazy val termRuntimeData: TermRuntimeData = elementRuntimeData
-
   /**
    * Is either None, Some(primTypeValue) or Some(UseNilForDefault), which is a
    * singleton object indicating that the item is nillable, and useNilForDefault was true.
@@ -465,41 +356,6 @@ trait ElementBase
     } else None
   }
 
-  /**
-   * The NextElementResolver is used to determine what infoset event comes next, and "resolves" which is to say
-   * determines the ElementRuntimeData for that infoset event. This can be used to construct the initial
-   * infoset from a stream of XML events.
-   */
-  final def computeNextElementResolver(possibles: Seq[ElementBase], resolverType: ResolverType): NextElementResolver = {
-    //
-    // Annoying, but scala's immutable Map is not covariant in its first argument
-    // the way one would normally expect a collection to be.
-    // So Map[NamedQName, ElementRuntimeData] is not a subtype of Map[QNameBase, ElementRuntimeData]
-    // So we need a cast upward to Map[QNameBase,ElementRuntimeData]
-    //
-    val eltMap = possibles.map {
-      e => (e.namedQName, e.elementRuntimeData)
-    }.toMap.asInstanceOf[Map[QNameBase, ElementRuntimeData]]
-    val resolver = eltMap.size match {
-      case 0 => new NoNextElement(schemaFileLocation, resolverType)
-      case 1 => new OnlyOnePossibilityForNextElement(schemaFileLocation, eltMap.values.head, resolverType)
-      case _ => {
-        val groupedByName = possibles.groupBy(_.namedQName.local)
-        var hasNamesDifferingOnlyByNS = false
-        groupedByName.foreach {
-          case (_, sameNamesEB) =>
-            if (sameNamesEB.length > 1) {
-              SDW(WarnID.NamespaceDifferencesOnly, "Neighboring QNames differ only by namespaces. Infoset representations that do not support namespacess cannot differentiate between these elements and may fail to unparse. QNames are: %s",
-                sameNamesEB.map(_.namedQName.toExtendedSyntax).mkString(", "))
-              hasNamesDifferingOnlyByNS = true
-            }
-        }
-        new SeveralPossibilitiesForNextElement(schemaFileLocation, eltMap, resolverType, hasNamesDifferingOnlyByNS)
-      }
-    }
-    resolver
-  }
-
   lazy val unparserInfosetElementDefaultingBehavior: UnparserInfo.InfosetEventBehavior = {
     import UnparserInfo._
     //if (isScalar && isDefaultable) ScalarDefaultable
@@ -522,76 +378,7 @@ trait ElementBase
   //    isOutputValueCalc
   //  }
 
-  final lazy val nextElementResolver: NextElementResolver = {
-    computeNextElementResolver(possibleNextChildElementsInInfoset, SiblingResolver)
-  }
-
-  final lazy val childElementResolver: NextElementResolver =
-    computeNextElementResolver(possibleFirstChildElementsInInfoset, ChildResolver)
-
-  final def erd = elementRuntimeData // just an abbreviation
-
-  final lazy val elementRuntimeData: ElementRuntimeData = LV('elementRuntimeData) {
-    computeElementRuntimeData
-  }.value
-
-  protected def computeElementRuntimeData(): ElementRuntimeData = {
-
-    lazy val childrenERDs: Seq[ElementRuntimeData] =
-      elementChildren.map { _.elementRuntimeData }
-
-    val newERD: ElementRuntimeData = new ElementRuntimeData(
-      position,
-      childrenERDs,
-      schemaSet.variableMap,
-      nextElementResolver,
-      childElementResolver,
-      encodingInfo,
-      dpathElementCompileInfo,
-      schemaFileLocation,
-      diagnosticDebugName,
-      path,
-      namespaces,
-      minimizedScope,
-      defaultBitOrder,
-      optPrimType,
-      targetNamespace,
-      thisElementsNamespace,
-      optSimpleTypeRuntimeData,
-      minOccurs,
-      maxOccurs,
-      Maybe.toMaybe(optionOccursCountKind),
-      name,
-      targetNamespacePrefix,
-      thisElementsNamespacePrefix,
-      isHidden,
-      isNillable,
-      isArray, // can have more than 1 occurrence
-      isOptional, // can have exactly 0 or 1 occurrence
-      isRequiredInInfoset, // must have at least 1 occurrence
-      namedQName,
-      isRepresented,
-      couldHaveText,
-      alignmentValueInBits,
-      hasNoSkipRegions,
-      impliedRepresentation,
-      optIgnoreCase,
-      defaultValue,
-      //
-      // unparser specific items
-      //
-      optTruncateSpecifiedLengthString,
-      if (isOutputValueCalc) Some(ovcCompiledExpression) else None,
-      maybeBinaryFloatRepEv,
-      maybeByteOrderEv,
-      maybeFillByteEv,
-      maybeCheckByteAndBitOrderEv,
-      maybeCheckBitOrderAndCharset,
-      isQuasiElement)
-    newERD
-  }
-
-  private lazy val optTruncateSpecifiedLengthString =
+  final protected lazy val optTruncateSpecifiedLengthString =
     Option(truncateSpecifiedLengthString =:= YesNo.Yes)
   // because of the way text numbers are unparsed, we don't know that
   // the string is for a text number. So we need this property for numbers and other text
@@ -1186,14 +973,6 @@ trait ElementBase
     }.get
   }
 
-  private lazy val optSimpleTypeRuntimeData: Option[SimpleTypeRuntimeData] =
-    typeDef match {
-      case _: PrimitiveType => None
-      case _: ComplexTypeBase => None
-      case s: SimpleTypeDefBase =>
-        Some(s.simpleTypeRuntimeData)
-    }
-
   /**
    * Does the element have a default value?
    */
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
index 76df420..53acd92 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
@@ -198,25 +198,6 @@ abstract class ModelGroup(index: Int)
     echls
   }.value
 
-  final override lazy val runtimeData: RuntimeData = modelGroupRuntimeData
-
-  final override lazy val termRuntimeData: TermRuntimeData = modelGroupRuntimeData
-
-  protected lazy val groupMembersRuntimeData = {
-    val res = this match {
-      case mg: ModelGroup => mg.groupMembers.map {
-        _ match {
-          case eb: ElementBase => eb.erd
-          case t: Term => t.termRuntimeData
-        }
-      }
-      case _ => Nil
-    }
-    res
-  }
-
-  def modelGroupRuntimeData: ModelGroupRuntimeData
-
   protected final lazy val prettyBaseName = xml.label
 
   final lazy val sequenceChildren = groupMembers.collect { case s: SequenceTermBase => s }
@@ -267,7 +248,10 @@ abstract class ModelGroup(index: Int)
     }
   }
 
-  final def allSelfContainedTermsTerminatedByRequiredElement: Seq[Term] =
+  /**
+   * Package private as this is for testing only
+   */
+  private[dsom] final def allSelfContainedTermsTerminatedByRequiredElement: Seq[Term] =
     LV('allSelfContainedTermsTerminatedByRequiredElement) {
       val listOfTerms = groupMembers.map(m => {
         m match {
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 ca0867b..a251e7d 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
@@ -65,8 +65,6 @@ abstract class SequenceTermBase(
 
   def separatorUnparseEv: SeparatorUnparseEv
 
-  def sequenceRuntimeData: SequenceRuntimeData
-
   def layerLengthUnits: LayerLengthUnits
 
   def isOrdered: Boolean
@@ -93,7 +91,6 @@ abstract class SequenceGroupTermBase(
   with LayeringRuntimeValuedPropertiesMixin {
 
   requiredEvaluations(checkIfValidUnorderedSequence)
-  requiredEvaluations(modelGroupRuntimeData.preSerialization)
 
   protected def apparentXMLChildren: Seq[Node]
 
@@ -226,30 +223,6 @@ abstract class SequenceGroupTermBase(
     case SequenceKind.Unordered => false
   }
 
-  final lazy val modelGroupRuntimeData = sequenceRuntimeData
-
-  final lazy val sequenceRuntimeData = {
-    new SequenceRuntimeData(
-      schemaSet.variableMap,
-      encodingInfo,
-      // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
-      schemaFileLocation,
-      dpathCompileInfo,
-      diagnosticDebugName,
-      path,
-      namespaces,
-      defaultBitOrder,
-      groupMembersRuntimeData,
-      isRepresented,
-      couldHaveText,
-      alignmentValueInBits,
-      hasNoSkipRegions,
-      optIgnoreCase,
-      maybeFillByteEv,
-      maybeCheckByteAndBitOrderEv,
-      maybeCheckBitOrderAndCharset)
-  }
-
   private val layeredSequenceAllowedProps = Set("ref", "layerTransform", "layerEncoding", "layerLengthKind", "layerLength", "layerLengthUnits", "layerBoundaryMark")
 
   final lazy val maybeLayerTransformerEv: Maybe[LayerTransformerEv] = {
@@ -321,7 +294,7 @@ trait SequenceDefMixin
 /**
  * Represents a local sequence definition.
  */
-class Sequence(xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
+final class Sequence(xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
   extends SequenceGroupTermBase(xmlArg, lexicalParent, position)
   with SequenceDefMixin {
 
@@ -390,27 +363,6 @@ final class ChoiceBranchImpliedSequence(rawGM: Term)
 
   override def findPropertyOption(pname: String): PropertyLookupResult = rawGM.findPropertyOption(pname)
 
-  override lazy val sequenceRuntimeData: SequenceRuntimeData = {
-    new SequenceRuntimeData(
-      schemaSet.variableMap,
-      encodingInfo,
-      schemaFileLocation,
-      dpathCompileInfo,
-      diagnosticDebugName,
-      path,
-      namespaces,
-      defaultBitOrder,
-      groupMembersRuntimeData,
-      isRepresented,
-      couldHaveText,
-      alignmentValueInBits,
-      true,
-      None,
-      Maybe.Nope,
-      Maybe.Nope,
-      Maybe.Nope)
-  }
-
   /**
    * Implied sequence doesn't exist textually, so can't have properties on it.
    */
@@ -419,8 +371,6 @@ final class ChoiceBranchImpliedSequence(rawGM: Term)
   // Members declared in AnnotatedSchemaComponent
   protected def optReferredToComponent: Option[AnnotatedSchemaComponent] = None
 
-  def modelGroupRuntimeData: ModelGroupRuntimeData = sequenceRuntimeData
-
   final override def xmlChildren: Seq[scala.xml.Node] = Seq(xml)
 
   // Members declared in Term
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
index cf2cd41..42ee03a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
@@ -197,8 +197,6 @@ trait Term
    */
   def isArray: Boolean
 
-  def termRuntimeData: TermRuntimeData
-
   def elementChildren: Seq[ElementBase]
 
   /**
@@ -825,69 +823,7 @@ trait Term
     }
   }.value
 
-  /**
-   * Set of elements referenced from an expression in the scope of this term.
-   *
-   * Specific to certain function call contexts e.g., only elements referenced
-   * by dfdl:valueLength or dfdl:contentLength.
-   *
-   * Separated by parser/unparser since parsers have to derive from
-   * dfdl:inputValueCalc, and must include discriminators and assert test
-   * expressions. Unparsers must derive from dfdl:outputValueCalc and exclude
-   * discriminators and asserts. Both must include setVariable/newVariableInstance,
-   * and property expressions are nearly the same. There are some unparser-specfic
-   * properties that take runtime-valued expressions - dfdl:outputNewLine is
-   * one example.
-   */
-  final lazy val contentLengthParserReferencedElementInfos: Set[DPathElementCompileInfo] = {
-    val propRefs = propertyContentReferencedElementInfos
-    val stmtRefs = statementContentParserReferencedElementInfos
-    val calcRefs = calcContentParserReferencedElementInfos
-    val locRefs = propRefs ++ stmtRefs ++ calcRefs
-    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.contentLengthParserReferencedElementInfos) }
-    res
-  }
-
-  /**
-   * Any element referenced from an expression in the scope of this term
-   * is in this set.
-   */
-  final lazy val contentLengthUnparserReferencedElementInfos: Set[DPathElementCompileInfo] = {
-    val propRefs = propertyContentReferencedElementInfos
-    val stmtRefs = statementContentUnparserReferencedElementInfos
-    val calcRefs = calcContentUnparserReferencedElementInfos
-    val locRefs = propRefs ++ stmtRefs ++ calcRefs
-    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.contentLengthUnparserReferencedElementInfos) }
-    res
-  }
-
-  /**
-   * Any element referenced from an expression in the scope of this term
-   * is in this set.
-   */
-  final lazy val valueLengthParserReferencedElementInfos: Set[DPathElementCompileInfo] = {
-    val propRefs = propertyValueReferencedElementInfos
-    val stmtRefs = statementValueParserReferencedElementInfos
-    val calcRefs = calcValueParserReferencedElementInfos
-    val locRefs = propRefs ++ stmtRefs ++ calcRefs
-    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.valueLengthParserReferencedElementInfos) }
-    res
-  }
-
-  /**
-   * Any element referenced from an expression in the scope of this term
-   * is in this set.
-   */
-  final lazy val valueLengthUnparserReferencedElementInfos: Set[DPathElementCompileInfo] = {
-    val propRefs = propertyValueReferencedElementInfos
-    val stmtRefs = statementValueUnparserReferencedElementInfos
-    val calcRefs = calcValueUnparserReferencedElementInfos
-    val locRefs = propRefs ++ stmtRefs ++ calcRefs
-    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.valueLengthUnparserReferencedElementInfos) }
-    res
-  }
-
-  private lazy val realChildren: Seq[Term] = {
+  final protected lazy val realChildren: Seq[Term] = {
     this match {
       case mg: ModelGroup => mg.groupMembers.asInstanceOf[Seq[Term]]
       case eb: ElementBase if (eb.isComplexType) => Seq(eb.complexType.group)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
index 9b7b5a3..1744ad0 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
@@ -24,8 +24,11 @@ import org.apache.daffodil.processors.parsers.NadaParser
 import org.apache.daffodil.processors.unparsers.ChoiceUnusedUnparser
 import org.apache.daffodil.processors.unparsers.Unparser
 import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.runtime1.ChoiceTermRuntime1Mixin
 
-trait ChoiceGrammarMixin extends GrammarMixin { self: ChoiceTermBase =>
+trait ChoiceGrammarMixin
+  extends GrammarMixin
+  with ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
 
   override lazy val groupContent = prod("choiceContent") {
     ChoiceCombinator(this, alternatives)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
index 2a4882c..a75d585 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
@@ -18,10 +18,8 @@
 package org.apache.daffodil.grammar
 
 import java.lang.{ Long => JLong }
-
 import scala.Boolean
 import scala.Long
-
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.dpath.NodeInfo
 import org.apache.daffodil.dpath.NodeInfo.PrimType
@@ -31,131 +29,17 @@ import org.apache.daffodil.dsom.ExpressionCompilers
 import org.apache.daffodil.dsom.InitiatedTerminatedMixin
 import org.apache.daffodil.dsom.TunableLimitExceededError
 import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.grammar.primitives.AlignmentFill
-import org.apache.daffodil.grammar.primitives.BCDDecimalDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.BCDDecimalKnownLength
-import org.apache.daffodil.grammar.primitives.BCDDecimalPrefixedLength
-import org.apache.daffodil.grammar.primitives.BCDDecimalRuntimeLength
-import org.apache.daffodil.grammar.primitives.BCDIntegerDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.BCDIntegerKnownLength
-import org.apache.daffodil.grammar.primitives.BCDIntegerPrefixedLength
-import org.apache.daffodil.grammar.primitives.BCDIntegerRuntimeLength
-import org.apache.daffodil.grammar.primitives.BinaryBoolean
-import org.apache.daffodil.grammar.primitives.BinaryBooleanPrefixedLength
-import org.apache.daffodil.grammar.primitives.BinaryDecimalKnownLength
-import org.apache.daffodil.grammar.primitives.BinaryDecimalPrefixedLength
-import org.apache.daffodil.grammar.primitives.BinaryDecimalRuntimeLength
-import org.apache.daffodil.grammar.primitives.BinaryDouble
-import org.apache.daffodil.grammar.primitives.BinaryFloat
-import org.apache.daffodil.grammar.primitives.BinaryIntegerKnownLength
-import org.apache.daffodil.grammar.primitives.BinaryIntegerPrefixedLength
-import org.apache.daffodil.grammar.primitives.BinaryIntegerRuntimeLength
-import org.apache.daffodil.grammar.primitives.BlobSpecifiedLength
-import org.apache.daffodil.grammar.primitives.CaptureContentLengthEnd
-import org.apache.daffodil.grammar.primitives.CaptureContentLengthStart
-import org.apache.daffodil.grammar.primitives.CaptureValueLengthEnd
-import org.apache.daffodil.grammar.primitives.CaptureValueLengthStart
-import org.apache.daffodil.grammar.primitives.ComplexNilOrContent
-import org.apache.daffodil.grammar.primitives.ConvertBinaryDateTimeSecMilliPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextBooleanPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextBytePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextCombinator
-import org.apache.daffodil.grammar.primitives.ConvertTextDatePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextDateTimePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextDecimalPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextDoublePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextFloatPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextIntPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextIntegerPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextLongPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextNonNegativeIntegerPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextShortPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextTimePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextUnsignedBytePrim
-import org.apache.daffodil.grammar.primitives.ConvertTextUnsignedIntPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextUnsignedLongPrim
-import org.apache.daffodil.grammar.primitives.ConvertTextUnsignedShortPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedBytePrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedCombinator
-import org.apache.daffodil.grammar.primitives.ConvertZonedDecimalPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedIntPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedIntegerPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedLongPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedNonNegativeIntegerPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedShortPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedUnsignedBytePrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedUnsignedIntPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedUnsignedLongPrim
-import org.apache.daffodil.grammar.primitives.ConvertZonedUnsignedShortPrim
-import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorElement
-import org.apache.daffodil.grammar.primitives.DynamicEscapeSchemeCombinatorElement
-import org.apache.daffodil.grammar.primitives.ElementCombinator
-import org.apache.daffodil.grammar.primitives.ElementParseAndUnspecifiedLength
-import org.apache.daffodil.grammar.primitives.ElementUnused
-import org.apache.daffodil.grammar.primitives.HexBinaryDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.HexBinaryEndOfBitLimit
-import org.apache.daffodil.grammar.primitives.HexBinaryLengthPrefixed
-import org.apache.daffodil.grammar.primitives.HexBinarySpecifiedLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedDecimalDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.IBM4690PackedDecimalKnownLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedDecimalPrefixedLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedDecimalRuntimeLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedIntegerDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.IBM4690PackedIntegerKnownLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedIntegerPrefixedLength
-import org.apache.daffodil.grammar.primitives.IBM4690PackedIntegerRuntimeLength
-import org.apache.daffodil.grammar.primitives.Initiator
-import org.apache.daffodil.grammar.primitives.InputValueCalc
-import org.apache.daffodil.grammar.primitives.LeadingSkipRegion
-import org.apache.daffodil.grammar.primitives.LeftCenteredPadding
-import org.apache.daffodil.grammar.primitives.LiteralCharacterNilOfSpecifiedLength
-import org.apache.daffodil.grammar.primitives.LiteralNilDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.LiteralValueNilOfSpecifiedLength
-import org.apache.daffodil.grammar.primitives.LogicalNilValue
-import org.apache.daffodil.grammar.primitives.OnlyPadding
-import org.apache.daffodil.grammar.primitives.PackedDecimalDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.PackedDecimalKnownLength
-import org.apache.daffodil.grammar.primitives.PackedDecimalPrefixedLength
-import org.apache.daffodil.grammar.primitives.PackedDecimalRuntimeLength
-import org.apache.daffodil.grammar.primitives.PackedIntegerDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.PackedIntegerKnownLength
-import org.apache.daffodil.grammar.primitives.PackedIntegerPrefixedLength
-import org.apache.daffodil.grammar.primitives.PackedIntegerRuntimeLength
-import org.apache.daffodil.grammar.primitives.PaddingInfoMixin
-import org.apache.daffodil.grammar.primitives.RightCenteredPadding
-import org.apache.daffodil.grammar.primitives.RightFill
-import org.apache.daffodil.grammar.primitives.SimpleNilOrValue
-import org.apache.daffodil.grammar.primitives.SimpleTypeRetry
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthExplicit
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthExplicitCharacters
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthImplicit
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthImplicitCharacters
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthPattern
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthPrefixed
-import org.apache.daffodil.grammar.primitives.SpecifiedLengthPrefixedCharacters
-import org.apache.daffodil.grammar.primitives.StringDelimitedEndOfData
-import org.apache.daffodil.grammar.primitives.StringOfSpecifiedLength
-import org.apache.daffodil.grammar.primitives.Terminator
-import org.apache.daffodil.grammar.primitives.TrailingSkipRegion
+import org.apache.daffodil.grammar.primitives._ // there are too many to show individually
 import org.apache.daffodil.processors.TextJustificationType
 import org.apache.daffodil.schema.annotation.props.Found
 import org.apache.daffodil.schema.annotation.props.NotFound
-import org.apache.daffodil.schema.annotation.props.gen.BinaryCalendarRep
-import org.apache.daffodil.schema.annotation.props.gen.BinaryFloatRep
-import org.apache.daffodil.schema.annotation.props.gen.BinaryNumberRep
-import org.apache.daffodil.schema.annotation.props.gen.CalendarPatternKind
-import org.apache.daffodil.schema.annotation.props.gen.LengthKind
-import org.apache.daffodil.schema.annotation.props.gen.LengthUnits
-import org.apache.daffodil.schema.annotation.props.gen.NilKind
-import org.apache.daffodil.schema.annotation.props.gen.Representation
-import org.apache.daffodil.schema.annotation.props.gen.TextNumberRep
-import org.apache.daffodil.schema.annotation.props.gen.YesNo
+import org.apache.daffodil.schema.annotation.props.gen._ // there are too many to show individually
 import org.apache.daffodil.util.PackedSignCodes
 import org.apache.daffodil.xml.GlobalQName
 import org.apache.daffodil.xml.QName
 import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.grammar.primitives.ElementCombinator
-import org.apache.daffodil.grammar.primitives.TypeValueCalc
+import org.apache.daffodil.dsom.ExpressionCompilers
+import org.apache.daffodil.runtime1.ElementBaseRuntime1Mixin
 
 /////////////////////////////////////////////////////////////////
 // Elements System
@@ -165,7 +49,8 @@ trait ElementBaseGrammarMixin
   extends InitiatedTerminatedMixin
   with AlignedMixin
   with HasStatementsGrammarMixin
-  with PaddingInfoMixin { self: ElementBase =>
+  with PaddingInfoMixin
+  with ElementBaseRuntime1Mixin { self: ElementBase =>
 
   private val context = this
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
index bcf053a..f28178a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
@@ -26,6 +26,7 @@ import org.apache.daffodil.compiler.ParserOrUnparser
 import org.apache.daffodil.compiler.BothParserAndUnparser
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.runtime1.GramRuntime1Mixin
 
 /**
  * Gram - short for "Grammar Term"
@@ -49,7 +50,8 @@ import org.apache.daffodil.util.Maybe
  * then it becomes the EmptyGram which other Gram combinators recognize and optimize out.
  */
 abstract class Gram(contextArg: SchemaComponent)
-  extends OOLAGHostImpl(contextArg) {
+  extends OOLAGHostImpl(contextArg)
+  with GramRuntime1Mixin {
 
   final def SDE(str: String, args: Any*): Nothing = context.SDE(str, args: _*)
 
@@ -114,39 +116,4 @@ abstract class Gram(contextArg: SchemaComponent)
       Assert.invariantFailed("More than one alternative for || survived in the grammar")
   }
 
-  /**
-   * Provides parser.
-   *
-   * Required to examine child parsers, and optimize itself out by propagating NadaParser if there is no parser.
-   */
-  def parser: Parser
-
-  final def maybeParser: Maybe[Parser] = {
-    if (this.isEmpty) Maybe.Nope
-    else {
-      val p = this.parser
-      if (p.isEmpty) Maybe.Nope
-      else Maybe(p)
-    }
-  }
-
-  protected final def hasNoParser: Parser = Assert.invariantFailed("Has no parser.")
-  protected final def hasNoUnparser: Unparser = Assert.invariantFailed("Has no unparser.")
-
-  /**
-   * Provides unparser.
-   *
-   * Required to examine child unparsers, and optimize itself out by propagating NadaUnparser if there is no unparser.
-   */
-  def unparser: Unparser
-
-  final def maybeUnparser: Maybe[Unparser] = {
-    if (this.isEmpty) Maybe.Nope
-    else {
-      val u = this.unparser
-      if (u.isEmpty) Maybe.Nope
-      else Maybe(u)
-    }
-  }
-
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
index 351ac86..739b8c7 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
@@ -27,12 +27,16 @@ import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorSequence
 import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorChoice
 import org.apache.daffodil.dsom.SequenceTermBase
 import org.apache.daffodil.dsom.ChoiceTermBase
+import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorChoice
+import org.apache.daffodil.runtime1.ModelGroupRuntime1Mixin
+import org.apache.daffodil.grammar.primitives.LeadingSkipRegion
 
 trait ModelGroupGrammarMixin
   extends InitiatedTerminatedMixin
   with AlignedMixin
   with HasStatementsGrammarMixin
-  with GroupCommonAGMixin { self: ModelGroup =>
+  with GroupCommonAGMixin
+  with ModelGroupRuntime1Mixin { self: ModelGroup =>
 
   private lazy val groupLeftFraming = prod("groupLeftFraming") {
     LeadingSkipRegion(this) ~ AlignmentFill(this)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
index 134242a..74227e5 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
@@ -23,8 +23,11 @@ import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.primitives._
 import org.apache.daffodil.grammar.primitives.OrderedSequence
 import org.apache.daffodil.grammar.primitives.UnorderedSequence
+import org.apache.daffodil.runtime1.SequenceTermRuntime1Mixin
 
-trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
+trait SequenceGrammarMixin
+  extends GrammarMixin
+  with SequenceTermRuntime1Mixin { self: SequenceTermBase =>
 
   final override lazy val groupContent = prod("groupContent") {
     if (isLayered) layerContent
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/TermGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/TermGrammarMixin.scala
index 2348d5f..59cb1b1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/TermGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/TermGrammarMixin.scala
@@ -19,6 +19,8 @@ package org.apache.daffodil.grammar
 import org.apache.daffodil.dsom.DFDLNewVariableInstance
 import org.apache.daffodil.dsom.Term
 import org.apache.daffodil.grammar.primitives._
+import org.apache.daffodil.grammar.primitives.MandatoryTextAlignment
+import org.apache.daffodil.runtime1.TermRuntime1Mixin
 
 /////////////////////////////////////////////////////////////////
 // Common to all Terms (Elements and ModelGroups)
@@ -26,7 +28,8 @@ import org.apache.daffodil.grammar.primitives._
 
 trait TermGrammarMixin
   extends AlignedMixin
-  with BitOrderMixin { self: Term =>
+  with BitOrderMixin
+  with TermRuntime1Mixin { self: Term =>
 
   override protected final def grammarContext = this
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
new file mode 100644
index 0000000..499fda8
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.dsom.ChoiceTermBase
+import org.apache.daffodil.dsom.ModelGroup
+import org.apache.daffodil.infoset.ChoiceBranchStartEvent
+import org.apache.daffodil.processors.RuntimeData
+import org.apache.daffodil.processors.ChoiceRuntimeData
+import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.infoset.ChoiceBranchEvent
+import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.infoset.ChoiceBranchEndEvent
+import org.apache.daffodil.dsom.SequenceTermBase
+import org.apache.daffodil.api.WarnID
+import org.apache.daffodil.processors.ChoiceDispatchKeyEv
+import org.apache.daffodil.dsom.ExpressionCompilers
+import org.apache.daffodil.dpath.NodeInfo
+
+trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
+
+  final protected lazy val choiceDispatchKeyExpr = {
+    val qn = this.qNameForProperty("choiceDispatchKey")
+    ExpressionCompilers.String.compileProperty(qn, NodeInfo.NonEmptyString, choiceDispatchKeyRaw, this, dpathCompileInfo)
+  }
+
+  final lazy val choiceDispatchKeyEv = {
+    Assert.invariant(isDirectDispatch)
+    val ev = new ChoiceDispatchKeyEv(choiceDispatchKeyExpr, modelGroupRuntimeData)
+    ev.compile()
+    ev
+  }
+
+  final def choiceBranchMap: Map[ChoiceBranchEvent, RuntimeData] = LV('choiceBranchMap) {
+    val eventTuples = groupMembers.flatMap {
+      case e: ElementBase => Seq((ChoiceBranchStartEvent(e.namedQName), e))
+      case mg: ModelGroup => {
+        val idEvents = mg.identifyingEventsForChoiceBranch
+        Assert.invariant(!idEvents.isEmpty)
+        idEvents.map { (_, mg) }
+      }
+    }
+
+    // converts a sequence of tuples into a multi-map
+    val eventMap = eventTuples.groupBy { _._1 }.mapValues { _.map(_._2) }
+
+    val noDupes = eventMap.map {
+      case (event, trds) =>
+        if (trds.length > 1) {
+          if (event.isInstanceOf[ChoiceBranchStartEvent] && trds.exists {
+            // any element children in any of the trds?
+            // because if so, we have a true ambiguity here.
+            case sg: SequenceTermBase => {
+              val nonOVCEltChildren = sg.elementChildren.filterNot { _.isOutputValueCalc }
+              nonOVCEltChildren.length > 0
+            }
+            case _ => false
+          }) {
+            // Possibly due to presence of a element with dfdl:outputValueCalc, XML Schema's
+            // UPA check may not catch this ambiguity. However, we need a real element
+            // with unique name, to unambiguously identify a branch.
+            // So if there is ambiguity at this point, we have to fail.
+            SDE(
+              "UPA violation. Multiple choice branches begin with %s.\n" +
+                "Note that elements with dfdl:outputValueCalc cannot be used to distinguish choice branches.\n" +
+                "Note that choice branches with entirely optional content are not allowed.\n" +
+                "The offending choice branches are:\n%s",
+              event.qname, trds.map { trd => "%s at %s".format(trd.diagnosticDebugName, trd.locationDescription) }.mkString("\n"))
+          } else {
+            val eventType = event match {
+              case _: ChoiceBranchEndEvent => "end"
+              case _: ChoiceBranchStartEvent => "start"
+            }
+            // there are no element children in any of the branches.
+            SDW(
+              WarnID.MultipleChoiceBranches,
+              "Multiple choice branches are associated with the %s of element %s.\n" +
+                "Note that elements with dfdl:outputValueCalc cannot be used to distinguish choice branches.\n" +
+                "Note that choice branches with entirely optional content are not allowed.\n" +
+                "The offending choice branches are:\n%s\n" +
+                "The first branch will be used during unparsing when an infoset ambiguity exists.",
+              eventType, event.qname, trds.map { trd => "%s at %s".format(trd.diagnosticDebugName, trd.locationDescription) }.mkString("\n"))
+          }
+        }
+        (event, trds(0).runtimeData)
+    }
+
+    noDupes
+  }.value
+
+  final lazy val modelGroupRuntimeData = choiceRuntimeData
+
+  final lazy val choiceRuntimeData = {
+    new ChoiceRuntimeData(
+      schemaSet.variableMap,
+      encodingInfo,
+      // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
+      schemaFileLocation,
+      dpathCompileInfo,
+      diagnosticDebugName,
+      path,
+      namespaces,
+      defaultBitOrder,
+      groupMembersRuntimeData,
+      isRepresented,
+      couldHaveText,
+      alignmentValueInBits,
+      hasNoSkipRegions,
+      optIgnoreCase,
+      maybeFillByteEv,
+      maybeCheckByteAndBitOrderEv,
+      maybeCheckBitOrderAndCharset)
+  }
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
new file mode 100644
index 0000000..7e1c616
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.dsom.PrefixLengthQuasiElementDecl
+import org.apache.daffodil.schema.annotation.props.gen.LengthKind
+import org.apache.daffodil.schema.annotation.props.gen.Representation
+import org.apache.daffodil.dsom.DPathElementCompileInfo
+import org.apache.daffodil.processors.RuntimeData
+import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.processors.SimpleTypeRuntimeData
+import org.apache.daffodil.dsom.SimpleTypeDefBase
+import org.apache.daffodil.dsom.ComplexTypeBase
+import org.apache.daffodil.dsom.PrimitiveType
+import org.apache.daffodil.infoset.ResolverType
+import org.apache.daffodil.infoset.SeveralPossibilitiesForNextElement
+import org.apache.daffodil.xml.QNameBase
+import org.apache.daffodil.infoset.NoNextElement
+import org.apache.daffodil.infoset.OnlyOnePossibilityForNextElement
+import org.apache.daffodil.infoset.NextElementResolver
+import org.apache.daffodil.api.WarnID
+import org.apache.daffodil.infoset.ChildResolver
+import org.apache.daffodil.infoset.SiblingResolver
+
+trait ElementBaseRuntime1Mixin { self: ElementBase =>
+
+  requiredEvaluations(erd.preSerialization)
+
+  /**
+   * Tells us if, for this element, we need to capture its content length
+   *  at unparse runtime, or we can ignore that.
+   */
+  final lazy val shouldCaptureUnparseContentLength: Boolean = {
+    val isReferenced =
+      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
+      else {
+        val setElems = schemaSet.root.contentLengthUnparserReferencedElementInfos
+        setElems.contains(this.dpathElementCompileInfo)
+      }
+
+    // We need to capture content length when maybeFixedLengthInBits is
+    // defined because it allows us to set absolute start bit positions of
+    // the DOS, even when there are things like padding and OVC that can
+    // cause suspensions that result in relative bit positions. However, we
+    // really only need this if there are going to be suspensions, not on all
+    // fixed length elements. Otherwise, we're capturing content length for
+    // no reason (unless it is referenced in a contentLength expression).
+    val mightHaveSuspensions = (maybeFixedLengthInBits.isDefined && couldHaveSuspensions)
+
+    isReferenced || mightHaveSuspensions
+  }
+
+  /**
+   * Tells us if, for this element, we need to capture its value length
+   *  at parse runtime, or we can ignore that.
+   */
+  final lazy val shouldCaptureParseValueLength: Boolean = {
+    val isReferenced =
+      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
+      else {
+        val setElems = schemaSet.root.valueLengthParserReferencedElementInfos
+        setElems.contains(this.dpathElementCompileInfo)
+      }
+
+    // For simple elements with text representation, valueLength is captured in
+    // individual parsers since they handle removing delimiters and padding.
+    //
+    // For complex elements with specified length, valueLength is captured in
+    // the specified length parsers, since they handle skipping unused
+    // element regions. For complex elements, this means lengthKind is not
+    // implicit or delimited.
+    //
+    // So for these cases we do not want to capture value length, since
+    // they are handled by the parsers as necessary
+    val capturedByParsers =
+      (isSimpleType && impliedRepresentation == Representation.Text) ||
+        (isComplexType && (lengthKind != LengthKind.Implicit && lengthKind != LengthKind.Delimited))
+
+    !capturedByParsers && isReferenced
+  }
+
+  /**
+   * Tells us if, for this element, we need to capture its value length
+   *  at unparse runtime, or we can ignore that.
+   */
+  final lazy val shouldCaptureUnparseValueLength: Boolean = {
+    val isReferenced =
+      if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) false
+      else {
+        val setElems = schemaSet.root.valueLengthUnparserReferencedElementInfos
+        setElems.contains(this.dpathElementCompileInfo)
+      }
+
+    // Besides being referenced by the dfdl:valueLength function,
+    // We need the valueLength to be computed for unparser pad/fill, to check
+    // excess length, and for alignmentFills.
+    //
+    // TBD: why for alignment fills? Don't see using it in the code. Try without this?
+    val pad = this.shouldAddPadding
+    val fill = this.shouldAddFill
+    val len = this.shouldCheckExcessLength
+    val alg = !this.isKnownToBeAligned // alignment fill uses the value length.
+    val mightHaveSuspensions = pad || fill || len || alg
+
+    isReferenced || mightHaveSuspensions
+  }
+
+  final override lazy val dpathCompileInfo = dpathElementCompileInfo
+
+  /**
+   * This is the compile info for this element term.
+   */
+  lazy val dpathElementCompileInfo: DPathElementCompileInfo = {
+    val ee = enclosingElements
+    val eci = new DPathElementCompileInfo(
+      ee.map {
+        _.dpathElementCompileInfo
+      },
+      variableMap,
+      elementChildrenCompileInfo,
+      namespaces,
+      slashPath,
+      name,
+      isArray,
+      namedQName,
+      optPrimType,
+      schemaFileLocation,
+      tunable,
+      schemaSet.typeCalcMap,
+      runtimeData,
+      shortSchemaComponentDesignator)
+    eci
+  }
+
+  override lazy val runtimeData: RuntimeData = elementRuntimeData
+  override lazy val termRuntimeData: TermRuntimeData = elementRuntimeData
+
+  final def erd = elementRuntimeData // just an abbreviation
+
+  final lazy val elementRuntimeData: ElementRuntimeData = LV('elementRuntimeData) {
+    computeElementRuntimeData
+  }.value
+
+  protected def computeElementRuntimeData(): ElementRuntimeData = {
+
+    lazy val childrenERDs: Seq[ElementRuntimeData] =
+      elementChildren.map { _.elementRuntimeData }
+
+    val newERD: ElementRuntimeData = new ElementRuntimeData(
+      position,
+      childrenERDs,
+      schemaSet.variableMap,
+      nextElementResolver,
+      childElementResolver,
+      encodingInfo,
+      dpathElementCompileInfo,
+      schemaFileLocation,
+      diagnosticDebugName,
+      path,
+      namespaces,
+      minimizedScope,
+      defaultBitOrder,
+      optPrimType,
+      targetNamespace,
+      thisElementsNamespace,
+      optSimpleTypeRuntimeData,
+      minOccurs,
+      maxOccurs,
+      Maybe.toMaybe(optionOccursCountKind),
+      name,
+      targetNamespacePrefix,
+      thisElementsNamespacePrefix,
+      isHidden,
+      isNillable,
+      isArray, // can have more than 1 occurrence
+      isOptional, // can have exactly 0 or 1 occurrence
+      isRequiredInInfoset, // must have at least 1 occurrence
+      namedQName,
+      isRepresented,
+      couldHaveText,
+      alignmentValueInBits,
+      hasNoSkipRegions,
+      impliedRepresentation,
+      optIgnoreCase,
+      defaultValue,
+      //
+      // unparser specific items
+      //
+      optTruncateSpecifiedLengthString,
+      if (isOutputValueCalc) Some(ovcCompiledExpression) else None,
+      maybeBinaryFloatRepEv,
+      maybeByteOrderEv,
+      maybeFillByteEv,
+      maybeCheckByteAndBitOrderEv,
+      maybeCheckBitOrderAndCharset,
+      isQuasiElement)
+    newERD
+  }
+
+  private lazy val optSimpleTypeRuntimeData: Option[SimpleTypeRuntimeData] =
+    typeDef match {
+      case _: PrimitiveType => None
+      case _: ComplexTypeBase => None
+      case s: SimpleTypeDefBase =>
+        Some(s.simpleTypeRuntimeData)
+    }
+
+  /**
+   * The NextElementResolver is used to determine what infoset event comes next, and "resolves" which is to say
+   * determines the ElementRuntimeData for that infoset event. This can be used to construct the initial
+   * infoset from a stream of XML events.
+   */
+  final def computeNextElementResolver(possibles: Seq[ElementBase], resolverType: ResolverType): NextElementResolver = {
+    //
+    // Annoying, but scala's immutable Map is not covariant in its first argument
+    // the way one would normally expect a collection to be.
+    // So Map[NamedQName, ElementRuntimeData] is not a subtype of Map[QNameBase, ElementRuntimeData]
+    // So we need a cast upward to Map[QNameBase,ElementRuntimeData]
+    //
+    val eltMap = possibles.map {
+      e => (e.namedQName, e.elementRuntimeData)
+    }.toMap.asInstanceOf[Map[QNameBase, ElementRuntimeData]]
+    val resolver = eltMap.size match {
+      case 0 => new NoNextElement(schemaFileLocation, resolverType)
+      case 1 => new OnlyOnePossibilityForNextElement(schemaFileLocation, eltMap.values.head, resolverType)
+      case _ => {
+        val groupedByName = possibles.groupBy(_.namedQName.local)
+        var hasNamesDifferingOnlyByNS = false
+        groupedByName.foreach {
+          case (_, sameNamesEB) =>
+            if (sameNamesEB.length > 1) {
+              SDW(WarnID.NamespaceDifferencesOnly, "Neighboring QNames differ only by namespaces. Infoset representations that do not support namespacess cannot differentiate between these elements and may fail to unparse. QNames are: %s",
+                sameNamesEB.map(_.namedQName.toExtendedSyntax).mkString(", "))
+              hasNamesDifferingOnlyByNS = true
+            }
+        }
+        new SeveralPossibilitiesForNextElement(schemaFileLocation, eltMap, resolverType, hasNamesDifferingOnlyByNS)
+      }
+    }
+    resolver
+  }
+
+  final lazy val nextElementResolver: NextElementResolver = {
+    computeNextElementResolver(possibleNextChildElementsInInfoset, SiblingResolver)
+  }
+
+  final lazy val childElementResolver: NextElementResolver =
+    computeNextElementResolver(possibleFirstChildElementsInInfoset, ChildResolver)
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/GramRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/GramRuntime1Mixin.scala
new file mode 100644
index 0000000..dd3feb0
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/GramRuntime1Mixin.scala
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.grammar.Gram
+import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.processors.unparsers.Unparser
+import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.processors.parsers.Parser
+
+trait GramRuntime1Mixin { self: Gram =>
+
+  /**
+   * Provides parser.
+   *
+   * Required to examine child parsers, and optimize itself out by propagating NadaParser if there is no parser.
+   */
+  def parser: Parser
+
+  final def maybeParser: Maybe[Parser] = {
+    if (this.isEmpty) Maybe.Nope
+    else {
+      val p = this.parser
+      if (p.isEmpty) Maybe.Nope
+      else Maybe(p)
+    }
+  }
+
+  protected final def hasNoParser: Parser = Assert.invariantFailed("Has no parser.")
+  protected final def hasNoUnparser: Unparser = Assert.invariantFailed("Has no unparser.")
+
+  /**
+   * Provides unparser.
+   *
+   * Required to examine child unparsers, and optimize itself out by propagating NadaUnparser if there is no unparser.
+   */
+  def unparser: Unparser
+
+  final def maybeUnparser: Maybe[Unparser] = {
+    if (this.isEmpty) Maybe.Nope
+    else {
+      val u = this.unparser
+      if (u.isEmpty) Maybe.Nope
+      else Maybe(u)
+    }
+  }
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala
new file mode 100644
index 0000000..e9d9b0f
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.dsom.ModelGroup
+import org.apache.daffodil.processors.ModelGroupRuntimeData
+import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.processors.RuntimeData
+import org.apache.daffodil.dsom.Term
+import org.apache.daffodil.dsom.ElementBase
+
+trait ModelGroupRuntime1Mixin { self: ModelGroup =>
+
+  final override lazy val runtimeData: RuntimeData = modelGroupRuntimeData
+
+  final override lazy val termRuntimeData: TermRuntimeData = modelGroupRuntimeData
+
+  protected lazy val groupMembersRuntimeData = {
+    val res = this match {
+      case mg: ModelGroup => mg.groupMembers.map {
+        _ match {
+          case eb: ElementBase => eb.erd
+          case t: Term => t.termRuntimeData
+        }
+      }
+      case _ => Nil
+    }
+    res
+  }
+
+  def modelGroupRuntimeData: ModelGroupRuntimeData
+
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala
new file mode 100644
index 0000000..6e8c86b
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.dsom.ChoiceBranchImpliedSequence
+import org.apache.daffodil.dsom.SequenceTermBase
+import org.apache.daffodil.processors.SequenceRuntimeData
+import org.apache.daffodil.util.Maybe
+
+trait SequenceTermRuntime1Mixin { self: SequenceTermBase =>
+
+  requiredEvaluations(modelGroupRuntimeData.preSerialization)
+
+  def modelGroupRuntimeData = sequenceRuntimeData
+
+  final lazy val sequenceRuntimeData = {
+    new SequenceRuntimeData(
+      schemaSet.variableMap,
+      encodingInfo,
+      // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
+      schemaFileLocation,
+      dpathCompileInfo,
+      diagnosticDebugName,
+      path,
+      namespaces,
+      defaultBitOrder,
+      groupMembersRuntimeData,
+      isRepresented,
+      couldHaveText,
+      alignmentValueInBits,
+      hasNoSkipRegions,
+      optIgnoreCase,
+      maybeFillByteEv,
+      maybeCheckByteAndBitOrderEv,
+      maybeCheckBitOrderAndCharset)
+  }
+
+}
+
+trait ChoiceBranchImpliedSequenceRuntime1Mixin { self: ChoiceBranchImpliedSequence =>
+
+  override lazy val sequenceRuntimeData: SequenceRuntimeData = {
+    new SequenceRuntimeData(
+      schemaSet.variableMap,
+      encodingInfo,
+      schemaFileLocation,
+      dpathCompileInfo,
+      diagnosticDebugName,
+      path,
+      namespaces,
+      defaultBitOrder,
+      groupMembersRuntimeData,
+      isRepresented,
+      couldHaveText,
+      alignmentValueInBits,
+      true,
+      None,
+      Maybe.Nope,
+      Maybe.Nope,
+      Maybe.Nope)
+  }
+
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
new file mode 100644
index 0000000..cf9cb12
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.runtime1
+
+import org.apache.daffodil.xml.QNameBase
+import org.apache.daffodil.infoset.SeveralPossibilitiesForNextElement
+import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.infoset.NoNextElement
+import org.apache.daffodil.infoset.OnlyOnePossibilityForNextElement
+import org.apache.daffodil.api.WarnID
+import org.apache.daffodil.dsom.Term
+import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.dsom.ModelGroup
+import org.apache.daffodil.dsom.DPathElementCompileInfo
+import org.apache.daffodil.dsom.PrefixLengthQuasiElementDecl
+import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.schema.annotation.props.gen.NilKind
+import org.apache.daffodil.schema.annotation.props.gen.Representation
+import org.apache.daffodil.schema.annotation.props.gen.LengthKind
+
+/**
+ * Part of Daffodil's Runtime 1 Streaming Unparser Support.
+ *
+ * When streaming in some representation of an infoset for unparsing,
+ * Daffodil (in Runtime 1) must resolve what element to construct.
+ * This is context specific, and given sharing of elements and groups,
+ * requires a runtime stack of TermRuntimeData, each stack entry has
+ * an associated PartialNextElementResolver.
+ *
+ * This object computes that PartialNextElementResolver based on the
+ * possible elements that can follow the current term.
+ */
+trait TermRuntime1Mixin { self: Term =>
+
+  def termRuntimeData: TermRuntimeData
+
+  /**
+   * Set of elements referenced from an expression in the scope of this term.
+   *
+   * Specific to certain function call contexts e.g., only elements referenced
+   * by dfdl:valueLength or dfdl:contentLength.
+   *
+   * Separated by parser/unparser since parsers have to derive from
+   * dfdl:inputValueCalc, and must include discriminators and assert test
+   * expressions. Unparsers must derive from dfdl:outputValueCalc and exclude
+   * discriminators and asserts. Both must include setVariable/newVariableInstance,
+   * and property expressions are nearly the same. There are some unparser-specfic
+   * properties that take runtime-valued expressions - dfdl:outputNewLine is
+   * one example.
+   */
+  final lazy val contentLengthParserReferencedElementInfos: Set[DPathElementCompileInfo] = {
+    val propRefs = propertyContentReferencedElementInfos
+    val stmtRefs = statementContentParserReferencedElementInfos
+    val calcRefs = calcContentParserReferencedElementInfos
+    val locRefs = propRefs ++ stmtRefs ++ calcRefs
+    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.contentLengthParserReferencedElementInfos) }
+    res
+  }
+
+  /**
+   * Any element referenced from an expression in the scope of this term
+   * is in this set.
+   */
+  final lazy val contentLengthUnparserReferencedElementInfos: Set[DPathElementCompileInfo] = {
+    val propRefs = propertyContentReferencedElementInfos
+    val stmtRefs = statementContentUnparserReferencedElementInfos
+    val calcRefs = calcContentUnparserReferencedElementInfos
+    val locRefs = propRefs ++ stmtRefs ++ calcRefs
+    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.contentLengthUnparserReferencedElementInfos) }
+    res
+  }
+
+  /**
+   * Any element referenced from an expression in the scope of this term
+   * is in this set.
+   */
+  final lazy val valueLengthParserReferencedElementInfos: Set[DPathElementCompileInfo] = {
+    val propRefs = propertyValueReferencedElementInfos
+    val stmtRefs = statementValueParserReferencedElementInfos
+    val calcRefs = calcValueParserReferencedElementInfos
+    val locRefs = propRefs ++ stmtRefs ++ calcRefs
+    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.valueLengthParserReferencedElementInfos) }
+    res
+  }
+
+  /**
+   * Any element referenced from an expression in the scope of this term
+   * is in this set.
+   */
+  final lazy val valueLengthUnparserReferencedElementInfos: Set[DPathElementCompileInfo] = {
+    val propRefs = propertyValueReferencedElementInfos
+    val stmtRefs = statementValueUnparserReferencedElementInfos
+    val calcRefs = calcValueUnparserReferencedElementInfos
+    val locRefs = propRefs ++ stmtRefs ++ calcRefs
+    val res = realChildren.foldLeft(locRefs) { (s, i) => s.union(i.valueLengthUnparserReferencedElementInfos) }
+    res
+  }
+
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/package.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/package.scala
new file mode 100644
index 0000000..96eb57d
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/package.scala
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil
+
+/**
+ * Schema Compiler aspects that are specific to Runtime 1.
+ *
+ * There are some characteristics of Runtime 1 that are unlikely to be shared
+ * by other Daffodil runtime backends. This package is for those things.
+ *
+ * As an example, Runtime 1 has a streaming unparser. This requires that the schema
+ * compiler create appropriate runtime data structures to support this behavior.
+ */
+package object runtime1 {
+  // This object exists for scaladoc purposes.
+}