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 13:33:52 UTC
[incubator-daffodil] branch master updated (2a978ff -> 73d0717)
This is an automated email from the ASF dual-hosted git repository.
mbeckerle pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git.
discard 2a978ff Incorporate review changes.
discard 06b3061 Eliminates backpointers from RuntimeData structures.
discard 39c500e Review comments/fixes incorporated.
discard 83eb5fa Fix missing checks for minOccurs after zero occurrences.
discard efd7c0e Moved pushDiscriminator to fix separators bug.
new 73d0717 Moved pushDiscriminator to fix separators bug.
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (2a978ff)
\
N -- N -- N refs/heads/master (73d0717)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../processors/parsers/SequenceParserBases.scala | 39 ++--------------------
1 file changed, 3 insertions(+), 36 deletions(-)
[incubator-daffodil] 01/01: Moved pushDiscriminator to fix
separators bug.
Posted by mb...@apache.org.
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 73d071750b7b484e010cb357f226b93de2f4439a
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Tue Aug 14 14:26:14 2018 -0400
Moved pushDiscriminator to fix separators bug.
Fix missing checks for minOccurs after zero occurrences.
Also verify that assertion failure no longer occurs.
Also found some unused code and deleted it. Old methods not used
anywmore.
Removed beforeArrayState - not needed. Prevents streaming behavior.
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-1984, DAFFODIL-1985, DAFFODIL-1964, 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 +--
.../grammar/primitives/PrimitivesDelimiters.scala | 51 ----------
.../unparsers/SeparatedSequenceUnparsers.scala | 7 +-
.../unparsers/SequenceChildUnparsers.scala | 30 ++----
.../unparsers/UnseparatedSequenceUnparsers.scala | 3 +-
.../apache/daffodil/processors/RuntimeData.scala | 44 +--------
.../parsers/SeparatedSequenceParsers.scala | 12 ++-
.../processors/parsers/SequenceParserBases.scala | 57 ++---------
.../parsers/UnseparatedSequenceParsers.scala | 3 -
.../section16/array_optional_elem/ArrayComb.tdml | 104 +++++++++++++++++++++
.../TestArrayOptionalElem.scala | 6 ++
.../TestArrayOptionalElemNew.scala | 57 -----------
15 files changed, 144 insertions(+), 276 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-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDelimiters.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDelimiters.scala
index 9aaf5f3..ac3f387 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDelimiters.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDelimiters.scala
@@ -80,57 +80,6 @@ abstract class Text(es: Term, e: Term, guard: Boolean) extends StringDelimBase(e
""
}
}
-
- def getMatchedDelimiterInfo(remoteDelimRegex: Set[(String, String)], foundDelimiter: String,
- delimiters: List[(List[String], String, String)]) = {
- val matchedDelim = remoteDelimRegex.find {
- case (delimRegex, _) => {
- foundDelimiter.matches("(?s)^(" + delimRegex + ")$")
- }
- } match {
- case Some((_, theValue)) => theValue
- case None => Assert.impossibleCase()
- }
-
- val (remoteDelimValue, remoteElemName, remoteElemPath, _) =
- {
- val findResult = delimiters.map {
- case (delimValueList, elemName, elemPath) => {
- delimValueList.find(delim => delim == matchedDelim) match {
- case Some(d) => (d, elemName, elemPath, true)
- case None => (delimValueList.mkString(","), elemName, elemPath, false)
- }
- }
- }.toSet.filter { x => x._4 == true }
-
- if (findResult.size == 0) Assert.impossibleCase()
- findResult.head
- }
- (remoteDelimValue, remoteElemName, remoteElemPath)
- }
-
- def getMatchedDelimiterInfo(
- originalDelimRep: String,
- delimiters: List[(List[String], String, String)]) = {
-
- val (remoteDelimValue, remoteElemName, remoteElemPath, _) =
- {
- val findResult = delimiters.map {
- case (delimValueList, elemName, elemPath) => {
- val res = delimValueList.find(delim => delim == originalDelimRep) match {
- case Some(d) => (d, elemName, elemPath, true)
- case None => (delimValueList.mkString(","), elemName, elemPath, false)
- }
- res
- }
- }.toSet.filter { x => x._4 == true }
-
- if (findResult.size == 0) Assert.impossibleCase()
- findResult.head
- }
- (remoteDelimValue, remoteElemName, remoteElemPath)
- }
-
}
// NOTE: LiteralNil still uses this as it can only be Static/Constant
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SeparatedSequenceUnparsers.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SeparatedSequenceUnparsers.scala
index f4e7a65..a4645ed 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SeparatedSequenceUnparsers.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SeparatedSequenceUnparsers.scala
@@ -364,7 +364,7 @@ class OrderedSeparatedSequenceUnparser(
}
// System.err.println("Finished unparse of array/opt %s. Array Index Stack is: %s, maxReps %s, numOccurrences %s".format(
// erd.namedQName, state.arrayIndexStack, maxReps, numOccurrences))
- unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps)
+ unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps, state.arrayPos - 1)
unparser.endArrayOrOptional(erd, state)
} else {
//
@@ -384,9 +384,8 @@ class OrderedSeparatedSequenceUnparser(
val eventNQN = ev.node.namedQName
Assert.invariant(eventNQN != erd.namedQName)
} else {
- // if (!(ev.isEnd && ev.isComplex))
- // Assert.invariantFailed("Expected end of complex. Was " + ev)
- // System.err.println("End event: " + ev)
+ Assert.invariant(ev.isEnd && ev.isComplex)
+ unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps, 0)
}
} else {
// no event (state.inspect returned false)
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 516d3ee..bae795f 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
@@ -169,27 +169,14 @@ abstract class RepeatingChildUnparser(
// System.err.println("Stopping occurrences(1) of %s due to event %s".format(erd.namedQName, ev))
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
- //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))
- }
} 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))
+ Assert.invariant(ev.isEnd)
+ // could be end of simple elemnet - we handle on the start event. Nothing to do.
+ // or could be end of complex event, i.e., 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.
+ // Nothing to do for complex type either.
false
}
} else {
@@ -232,7 +219,7 @@ abstract class RepeatingChildUnparser(
def checkFinalOccursCountBetweenMinAndMaxOccurs(
state: UState,
unparser: RepeatingChildUnparser,
- numOccurrences: Int, maxReps: Long): Unit = {
+ numOccurrences: Int, maxReps: Long, arrPos: Long): Unit = {
import OccursCountKind._
val minReps = unparser.minRepeats(state)
@@ -254,7 +241,6 @@ abstract class RepeatingChildUnparser(
//
val ock = erd.maybeOccursCountKind.get
// System.err.println("Checking for events consistent with Array index:\n ==> Array Index Stack is:" + state.arrayIndexStack)
- val arrPos = state.arrayPos - 1 // because we advance after each unparse so this is the position of the next (non-existing) occurrence
Assert.invariant(arrPos <= maxReps || !(ock eq Implicit))
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/UnseparatedSequenceUnparsers.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/UnseparatedSequenceUnparsers.scala
index 7fbd25f..ae44f98 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/UnseparatedSequenceUnparsers.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/UnseparatedSequenceUnparsers.scala
@@ -128,7 +128,7 @@ class OrderedUnseparatedSequenceUnparser(rd: SequenceRuntimeData, childUnparsers
if (isArr) if (state.dataProc.isDefined) state.dataProc.get.afterRepetition(state, this)
}
- unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps)
+ unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps, state.arrayPos - 1)
unparser.endArrayOrOptional(erd, state)
} else {
//
@@ -153,6 +153,7 @@ class OrderedUnseparatedSequenceUnparser(rd: SequenceRuntimeData, childUnparsers
Assert.invariant(eventNQN != erd.namedQName)
} else {
Assert.invariant(ev.isEnd && ev.isComplex)
+ unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(state, unparser, numOccurrences, maxReps, 0)
}
} else {
// no event (state.inspect returned false)
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 {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
index 889e5dd..38e39ca 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
@@ -299,6 +299,15 @@ final class OrderedSeparatedSequenceParser(
val bitPosBeforeSeparator = pstate.bitPos0b
+ //
+ // Note: Performance. All this conditional branch logic could in principle be hoisted
+ // out and decided at schema compile time, as what is being tested here is statically known.
+ //
+ // However, that's trading a few conditional branches for a virtual function call, and that
+ // might or might not be an improvement worth making. Not worth bothering with unless
+ // some profiling makes it look like this could help.
+ //
+
// parse prefix sep if any
val prefixSepSuccessful =
if (spos eq SeparatorPosition.Prefix) {
@@ -342,8 +351,6 @@ final class OrderedSeparatedSequenceParser(
//
val prevBitPosBeforeChild = pstate.bitPos0b
- pstate.pushDiscriminator
-
if (pstate.dataProc.isDefined) pstate.dataProc.get.beforeRepetition(pstate, this)
parser.parse1(pstate)
@@ -496,7 +503,6 @@ final class OrderedSeparatedSequenceParser(
result
} // end if child success/fail
} // end val res
- pstate.popDiscriminator
res
} // end if postfix
} // end if infix
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
index 541137a..a9ba907 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
@@ -118,20 +118,11 @@ abstract class OrderedSequenceParserBase(
// different, or OCK=parsed.
//
- //
- // The beforeArrayState will be assigned the priorState before the whole array
- // This is the same object as the priorState before the first
- // occurrence.
- //
- var beforeArrayState: PState.Mark = null
-
var resultOfTry: ParseAttemptStatus = ParseAttemptStatus.Uninitialized
var ais: ArrayIndexStatus = null
var goAIS: GoArrayIndexStatus = null
- var isFirstIteration = true
-
while ({
ais = parser.arrayIndexStatus(min, max, pstate, resultOfTry)
ais match {
@@ -142,46 +133,31 @@ abstract class OrderedSequenceParserBase(
//
// Saved state before an individual occurrence.
- //
- // On the first iteration this is the same as the beforeArrayState
- // and by "same" we mean same object in the 'eq' sense.
- //
- // If we are in a second or subsequent iteration then an invariant is
- // that this is NOT the same as the beforeArrayState.
- //
// These should not leak as we iterate the occurrences.
// The lifetime of these is the parse attempt for a single occurrence
// only.
//
- val priorState =
- if (isFirstIteration) {
- beforeArrayState = pstate.mark("before all occurrences")
- beforeArrayState
- } else {
- pstate.mark("before second/subsequent occurrence")
- }
+ val priorState = pstate.mark("before occurrence")
checkN(pstate) // check if arrayIndex exceeds tunable limit.
var markLeakCausedByException = false
var wasThrow = true
try {
+ pstate.pushDiscriminator
resultOfTry =
parseOneWithPoU(parser, erd, pstate, priorState, goAIS, isBounded)
wasThrow = false
+ pstate.popDiscriminator
//
// Now we handle the result of the parse attempt.
//
-
// check for consistency - failure comes with a PE in the PState.
Assert.invariant((pstate.processorStatus eq Success) ||
resultOfTry.isInstanceOf[FailedParseAttemptStatus])
resultOfTry match {
- //
- // These statuses for whole array/optional are not used
- // for PoU occurrences.
- //
+
case ParseAttemptStatus.Failed_EntireArray |
ParseAttemptStatus.Success_EndOfArray =>
Assert.invariantFailed("not valid return status for a PoU array/optional.")
@@ -197,10 +173,6 @@ abstract class OrderedSequenceParserBase(
}
case _: SuccessParseAttemptStatus => {
pstate.mpstate.moveOverOneGroupIndexOnly()
- //
- // Here we leave beforeArrayState alone. May still
- // need it later.
- //
wasLastChildZeroLength = resultOfTry eq ParseAttemptStatus.Success_ZeroLength
}
@@ -221,17 +193,7 @@ abstract class OrderedSequenceParserBase(
//
val Failure(cause) = pstate.processorStatus
- //
- // Discarding has to be done before resetting of an outer/earlier mark
- // because the InputDataStream marks are unwound in a stack manner. I.e., resetting
- // to an earlier one implicitly discards any nested within that.
- //
- // This was causing a problem when we didn't discard priorState until later, since it
- // would then try to discard the InputDataStream's mark, and find it had already been
- // discarded.
- //
- if (!isFirstIteration) pstate.discard(priorState)
- pstate.reset(beforeArrayState)
+ pstate.discard(priorState)
pstate.setFailed(cause)
resultOfTry = ParseAttemptStatus.Failed_EntireArray
}
@@ -284,10 +246,9 @@ abstract class OrderedSequenceParserBase(
}
}
// if it wasn't reset, we discard priorState here.
- if (!isFirstIteration && pstate.isInUse(priorState)) {
+ if (pstate.isInUse(priorState)) {
pstate.discard(priorState)
}
-
//
// advance array position.
// Done unconditionally, as some failures get converted into successes
@@ -296,15 +257,9 @@ abstract class OrderedSequenceParserBase(
// about to get poppped/cleared anyway.
//
pstate.mpstate.moveOverOneArrayIndexOnly()
- isFirstIteration = false
} // end while for each repeat
- // if it wasn't reset or discarded, discard here.
- if (pstate.isInUse(beforeArrayState)) {
- pstate.discard(beforeArrayState)
- }
-
} // end match case hasPoU = true
case false => {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
index 3210f7d..8ea27fe 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
@@ -118,8 +118,6 @@ class OrderedUnseparatedSequenceParser(rd: SequenceRuntimeData, childParsersArg:
Assert.invariant(erd.isArray || erd.isOptional) // not a PoU otherwise.
- pstate.pushDiscriminator
-
if (pstate.dataProc.isDefined) pstate.dataProc.get.beforeRepetition(pstate, this)
val posBefore = pstate.bitPos0b
@@ -160,7 +158,6 @@ class OrderedUnseparatedSequenceParser(rd: SequenceRuntimeData, childParsersArg:
}
}
}
- pstate.popDiscriminator
res
}
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayComb.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayComb.tdml
new file mode 100644
index 0000000..cf42a34
--- /dev/null
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayComb.tdml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<tdml:testSuite suiteName="ArrayCombTest"
+ description="Section 16 - Arrays and Optional Elements" xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ct="http://w3.ibm.com/xmlns/dfdl/ctInfoset"
+ xmlns:ex="http://example.com"
+ xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
+ defaultRoundTrip="true">
+
+ <tdml:defineSchema name="s1" elementFormDefault="unqualified">
+
+ <dfdl:format lengthKind="delimited" lengthUnits="bytes"
+ ref="ex:GeneralFormat" encoding="UTF-8" separator="" initiator="" terminator=""
+ occursCountKind="implicit" ignoreCase="no" textNumberRep="standard"
+ representation="text" />
+
+ <xs:element name="root1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="foo" type="xs:int" />
+ <xs:element name="bar" minOccurs="1" maxOccurs="2" dfdl:occursCountKind="implicit">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:discriminator>{ ../foo gt 0 }</dfdl:discriminator>
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:sequence dfdl:hiddenGroupRef="ex:hiddenGroup" />
+ <xs:group ref="someGroupWithRequiredElement" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:group name="hiddenGroup">
+ <xs:sequence>
+ <xs:element name="hiddenThing" type="xs:int" dfdl:outputValueCalc="{ 0 }"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="someGroupWithRequiredElement">
+ <xs:sequence>
+ <xs:element name="quux" type="xs:int"/>
+ </xs:sequence>
+ </xs:group>
+
+ </tdml:defineSchema>
+
+
+ <tdml:parserTestCase name="arrayComb1" root="root1" model="s1"
+ description="Test for user-reported bug - Assertion failure.">
+
+ <tdml:document><![CDATA[0]]></tdml:document>
+
+ <tdml:errors>
+ <tdml:error>Parse Error</tdml:error>
+ <tdml:error>Assertion Failed</tdml:error>
+ <tdml:error>../foo gt 0</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:unparserTestCase name="arrayComb2" root="root1" model="s1"
+ description="Test for user-reported bug - Assertion failure."
+ roundTrip="none">
+
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:root1>
+ <foo>1</foo>
+ </ex:root1>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+
+ <tdml:errors>
+ <tdml:error>Unparse Error</tdml:error>
+ <tdml:error>Expected 1 additional</tdml:error>
+ <tdml:error>bar</tdml:error>
+ <tdml:error>received element end event</tdml:error>
+ <tdml:error>ex:root1</tdml:error>
+ </tdml:errors>
+ </tdml:unparserTestCase>
+
+
+ </tdml:testSuite>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
index b965dbd..de4a50f 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
@@ -30,12 +30,14 @@ object TestArrayOptionalElem {
val runner01 = Runner(testDir01, "Facets.tdml", validateTDMLFile = false)
val runner1 = Runner(testDir1, "dpaext2.tdml")
val rBack = Runner(testDir, "backtracking.tdml")
+ val runnerAC = Runner(testDir, "ArrayComb.tdml")
@AfterClass def shutDown {
runner.reset
runner01.reset
runner1.reset
rBack.reset
+ runnerAC.reset
}
}
@@ -44,6 +46,10 @@ class TestArrayOptionalElem {
import TestArrayOptionalElem._
+ // DAFFODIL-1964
+ @Test def test_arrayComb1() = { runnerAC.runOneTest("arrayComb1") }
+ @Test def test_arrayComb2() = { runnerAC.runOneTest("arrayComb2") }
+
@Test def test_arrayExpressions01() { runner.runOneTest("arrayExpressions01") }
@Test def test_arrayExpressions02() { runner.runOneTest("arrayExpressions02") }
@Test def test_arrayExpressions02b() { runner.runOneTest("arrayExpressions02b") }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElemNew.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElemNew.scala
deleted file mode 100644
index 1250647..0000000
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElemNew.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.section16.array_optional_elem
-
-import org.apache.daffodil.util._
-import org.apache.daffodil.tdml.DFDLTestSuite
-import org.junit.AfterClass
-
-object TestArrayOptionalElemNew {
-
- val testDir = "/org/apache/daffodil/section16/array_optional_elem/"
- // val aa_fixed = testDir + "UnparseArrayFixedOptionalElem.tdml"
- // var runner_fixed = new DFDLTestSuite(Misc.getRequiredResource(aa_fixed))
- //
- // val aa_imp = testDir + "UnparseArrayImplicitOptionalElem.tdml"
- // var runner_imp = new DFDLTestSuite(Misc.getRequiredResource(aa_imp))
- //
- // val aa_parsed = testDir + "UnparseArrayParsedOptionalElem.tdml"
- // var runner_parsed = new DFDLTestSuite(Misc.getRequiredResource(aa_parsed))
- //
- // val aa_expr = testDir + "UnparseArrayExpressionConstant.tdml"
- // var runner_expr = new DFDLTestSuite(Misc.getRequiredResource(aa_expr))
-
- val aa_delim = testDir + "UnparseArrayDelimitedOptionalElem.tdml"
- var runner_delim = new DFDLTestSuite(Misc.getRequiredResource(aa_delim))
-
- /**
- * Avoid memory leak of adding more and more test suites to static objects as we run more and more test suites.
- */
- @AfterClass def tearDown() {
- // runner_fixed = null
- // runner_imp = null
- // runner_parsed = null
- // runner_expr = null
- runner_delim = null
- }
-
-}
-
-class TestArrayOptionalElemNew {
-
-}