From 7e7bd04b20cb61fa050178cd08b7d25542dec1d6 Mon Sep 17 00:00:00 2001
From: olabusayoT <50379531+olabusayoT@users.noreply.github.com>
Date: Fri, 3 Apr 2026 14:40:43 -0400
Subject: [PATCH] Add support for `dfdl:lengthKind="endOfParent"`
- Implemented logic to handle elements with `dfdl:lengthKind="endOfParent"`.
- Added validations to enforce schema/spec constraints and error conditions specific to `endOfParent` lengthKind.
- Introduced determination of effective length units for parent elements and related error checks.
- removed NYI Errors
- add tests for endOfParent elements with different LengthKinds incl nested EndOfParent
DAFFODIL-238
---
.../core/dsom/LocalElementMixin.scala | 6 +-
.../org/apache/daffodil/core/dsom/Term.scala | 20 +
.../daffodil/core/grammar/AlignedMixin.scala | 6 +-
.../grammar/ElementBaseGrammarMixin.scala | 157 +-
.../primitives/PrimitivesLengthKind.scala | 10 +
.../grammar/primitives/SpecifiedLength.scala | 24 +
.../parsers/HexBinaryLengthParsers.scala | 7 +-
...yNumberTraits.scala => ParserTraits.scala} | 0
.../parsers/SpecifiedLengthParsers.scala | 11 +
.../runtime1/SpecifiedLengthUnparsers.scala | 14 +
.../section12/aligned_data/Aligned_Data.tdml | 79 +
.../lengthKind/EndOfParentTests.tdml | 1965 ++++++++++++++++-
.../aligned_data/TestAlignedData.scala | 4 +
.../TestLengthKindEndOfParent.scala | 74 +
.../TestLengthKindEndOfParent2.scala | 34 -
15 files changed, 2319 insertions(+), 92 deletions(-)
rename daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/{BinaryNumberTraits.scala => ParserTraits.scala} (100%)
create mode 100644 daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent.scala
delete mode 100644 daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent2.scala
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/LocalElementMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/LocalElementMixin.scala
index 0e9aaf57e9..4756afcc0f 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/LocalElementMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/LocalElementMixin.scala
@@ -61,10 +61,8 @@ trait LocalElementMixin extends ParticleMixin with LocalElementGrammarMixin {
else if (representation =:= Representation.Binary) true
else false
}
- case LengthKind.EndOfParent if isComplexType =>
- notYetImplemented("lengthKind='endOfParent' for complex type")
- case LengthKind.EndOfParent =>
- notYetImplemented("lengthKind='endOfParent' for simple type")
+ // per DFDL Spec 9.3.2, endOfParent is already positioned at parent's end so length is zero
+ case LengthKind.EndOfParent => false
}
res
}.value
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Term.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Term.scala
index 7558483d5b..4e6495b3d1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Term.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/Term.scala
@@ -269,6 +269,26 @@ trait Term
.getOrElse(false)
}
+ final lazy val immediatelyEnclosingElementParent: Option[ElementBase] = {
+ val p = optLexicalParent.flatMap {
+ case e: ElementBase => Some(e)
+ case ge: GlobalElementDecl => Some(ge.asRoot)
+ case s: SequenceTermBase => s.immediatelyEnclosingElementParent
+ case c: ChoiceTermBase => c.immediatelyEnclosingElementParent
+ case ct: ComplexTypeBase => {
+ ct.optLexicalParent.flatMap {
+ case e: ElementBase => Some(e)
+ case ge: GlobalElementDecl => Some(ge.asRoot)
+ case _ => {
+ None
+ }
+ }
+ }
+ case _ => None
+ }
+ p
+ }
+
final lazy val immediatelyEnclosingGroupDef: Option[GroupDefLike] = {
optLexicalParent.flatMap { lexicalParent =>
val res: Option[GroupDefLike] = lexicalParent match {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
index 00ebdee130..63c7936eb3 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
@@ -456,7 +456,11 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
}
case LengthKind.Delimited => encodingLengthApprox
case LengthKind.Pattern => encodingLengthApprox
- case LengthKind.EndOfParent => LengthMultipleOf(1) // NYI
+ case LengthKind.EndOfParent =>
+ eb.immediatelyEnclosingElementParent match {
+ case Some(parent) => parent.elementSpecifiedLengthApprox
+ case _ => LengthMultipleOf(1)
+ }
// If an element is lengthKind="prefixed", the element's length is the length
// of the value of the prefix element, which can't be known till runtime
case LengthKind.Prefixed => LengthMultipleOf(1) // NYI (see DAFFODIL-3066)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
index 3a33fdfb07..011f323b23 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
@@ -19,10 +19,14 @@ package org.apache.daffodil.core.grammar
import java.lang.Long as JLong
+import org.apache.daffodil.core.dsom.ChoiceTermBase
import org.apache.daffodil.core.dsom.ElementBase
import org.apache.daffodil.core.dsom.ExpressionCompilers
import org.apache.daffodil.core.dsom.InitiatedTerminatedMixin
+import org.apache.daffodil.core.dsom.ModelGroup
import org.apache.daffodil.core.dsom.PrefixLengthQuasiElementDecl
+import org.apache.daffodil.core.dsom.Root
+import org.apache.daffodil.core.dsom.SequenceTermBase
import org.apache.daffodil.core.grammar.primitives.*
import org.apache.daffodil.core.runtime1.ElementBaseRuntime1Mixin
import org.apache.daffodil.lib.exceptions.Assert
@@ -52,6 +56,7 @@ trait ElementBaseGrammarMixin
requiredEvaluationsIfActivated(checkPrefixedLengthElementDecl)
requiredEvaluationsIfActivated(checkDelimitedLengthEVDP)
+ requiredEvaluationsIfActivated(checkEndOfParentElem)
private val context = this
@@ -252,6 +257,134 @@ trait ElementBaseGrammarMixin
}
final lazy val prefixedLengthBody = prefixedLengthElementDecl.parsedValue
+ final lazy val parentEffectiveLengthUnits: LengthUnits =
+ immediatelyEnclosingElementParent match {
+ case Some(parent: ElementBase) => {
+ parent.lengthKind match {
+ case LengthKind.Explicit | LengthKind.Prefixed => parent.lengthUnits
+ case LengthKind.Pattern => LengthUnits.Characters
+ case _
+ if parent.isInstanceOf[ChoiceTermBase] && (parent
+ .asInstanceOf[ChoiceTermBase]
+ .choiceLengthKind == ChoiceLengthKind.Explicit) =>
+ LengthUnits.Bytes
+ case LengthKind.EndOfParent => parent.parentEffectiveLengthUnits
+ case _ =>
+ Assert.invariantFailed(
+ s"Could not figure effective length unit of parents of ${context}"
+ )
+ }
+ }
+ case None if this.isInstanceOf[Root] => LengthUnits.Characters
+ case _ =>
+ Assert.invariantFailed(
+ s"Could not figure effective length unit of parents of ${context}"
+ )
+ }
+ final lazy val checkEndOfParentElem: Unit = {
+ if (lengthKind != LengthKind.EndOfParent) ()
+ else {
+ schemaDefinitionWhen(
+ hasTerminator,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but specifies a dfdl:terminator.",
+ context
+ )
+ schemaDefinitionWhen(
+ trailingSkip != 0,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but specifies a non-zero dfdl:trailingSkip.",
+ context
+ )
+ schemaDefinitionWhen(
+ maxOccurs > 1,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but specifies a maxOccurs greater than 1.",
+ context
+ )
+ schemaDefinitionWhen(
+ nextSibling.isDefined && nextSibling.get.isInstanceOf[ModelGroup],
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but a model group is defined between this element and the end of the enclosing component",
+ context
+ )
+ schemaDefinitionWhen(
+ nextSibling.isDefined && nextSibling.get.isRepresented,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but a represented element is defined between this element and the end of the enclosing component",
+ context
+ )
+ immediatelyEnclosingElementParent match {
+ case Some(parent: ElementBase) =>
+ parent.lengthKind match {
+ case LengthKind.Implicit | LengthKind.Delimited =>
+ schemaDefinitionError(
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but its parent is an element with dfdl:lengthKind 'implicit' or 'delimited'.",
+ context
+ )
+ case _ => // do nothing
+ }
+ case _ => // do nothing
+ }
+ schemaDefinitionWhen(
+ representation == Representation.Text && knownEncodingWidthInBits != 8 && parentEffectiveLengthUnits != LengthUnits.Characters,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but the element has text representation, does not have a single-byte character set encoding, and the effective length units of the parent is not 'characters'.",
+ context
+ )
+
+ immediatelyEnclosingModelGroup match {
+ case Some(s: SequenceTermBase) => {
+ schemaDefinitionWhen(
+ s.separatorPosition == SeparatorPosition.Postfix,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a sequence with dfdl:separatorPosition defined as 'postfix'.",
+ context
+ )
+ schemaDefinitionWhen(
+ s.sequenceKind != SequenceKind.Ordered,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a sequence with dfdl:sequenceKind defined as 'unordered'.",
+ context
+ )
+ schemaDefinitionWhen(
+ s.hasTerminator,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a sequence with a dfdl:terminator.",
+ context
+ )
+ schemaDefinitionWhen(
+ s.elementChildren.exists(e => e.floating == YesNo.Yes),
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a sequence with elements defining dfdl:floating='yes'.",
+ context
+ )
+ schemaDefinitionWhen(
+ s.trailingSkip != 0,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a sequence with a non-zero dfdl:trailingSkip."
+ )
+ }
+ case Some(c: ChoiceTermBase) if c.choiceLengthKind == ChoiceLengthKind.Implicit => {
+ schemaDefinitionWhen(
+ c.hasTerminator,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a choice with a dfdl:terminator.",
+ context
+ )
+ schemaDefinitionWhen(
+ c.trailingSkip != 0,
+ "%s is specified as dfdl:lengthKind=\"endOfParent\", but is in a choice with a non-zero dfdl:trailingSkip.",
+ context
+ )
+ }
+ case _ => // do nothing
+ }
+
+ if (isSimpleType) {
+ schemaDefinitionUnless(
+ (primType eq PrimType.String)
+ || (representation == Representation.Text)
+ || (primType eq PrimType.HexBinary)
+ || (representation == Representation.Binary
+ && Seq(BinaryNumberRep.Packed, BinaryNumberRep.Bcd, BinaryNumberRep.Ibm4690Packed)
+ .contains(binaryNumberRep)),
+ "%s is a simple type specified as dfdl:lengthKind=\"endOfParent\", but isn't a string type, doesn't have text representation, isn't a hexbinary type, or doesn't have binary representation with packed decimal representation.",
+ context
+ )
+ }
+
+ }
+ }
+
/**
* Quite tricky when we add padding or fill
*
@@ -648,10 +781,7 @@ trait ElementBaseGrammarMixin
Assert.invariant(pt == PrimType.String)
StringOfSpecifiedLength(this)
}
- case LengthKind.EndOfParent if isComplexType =>
- notYetImplemented("lengthKind='endOfParent' for complex type")
- case LengthKind.EndOfParent =>
- notYetImplemented("lengthKind='endOfParent' for simple type")
+ case LengthKind.EndOfParent => StringOfSpecifiedLength(this)
}
}
@@ -667,6 +797,10 @@ trait ElementBaseGrammarMixin
new HexBinaryLengthPrefixed(this)
}
+ private lazy val hexBinaryLengthEndOfParent = prod("hexBinaryLengthEndOfParent") {
+ new HexBinaryLengthEndOfParent(this)
+ }
+
private lazy val hexBinaryValue = prod("hexBinaryValue") {
schemaDefinitionWhen(
lengthUnits == LengthUnits.Characters,
@@ -678,10 +812,7 @@ trait ElementBaseGrammarMixin
case LengthKind.Delimited => hexBinaryDelimitedEndOfData
case LengthKind.Pattern => hexBinaryLengthPattern
case LengthKind.Prefixed => hexBinaryLengthPrefixed
- case LengthKind.EndOfParent if isComplexType =>
- notYetImplemented("lengthKind='endOfParent' for complex type")
- case LengthKind.EndOfParent =>
- notYetImplemented("lengthKind='endOfParent' for simple type")
+ case LengthKind.EndOfParent => hexBinaryLengthEndOfParent
}
}
@@ -1280,10 +1411,7 @@ trait ElementBaseGrammarMixin
case LengthKind.Implicit =>
LiteralValueNilOfSpecifiedLength(this)
case LengthKind.Prefixed => LiteralValueNilOfSpecifiedLength(this)
- case LengthKind.EndOfParent if isComplexType =>
- notYetImplemented("lengthKind='endOfParent' for complex type")
- case LengthKind.EndOfParent =>
- notYetImplemented("lengthKind='endOfParent' for simple type")
+ case LengthKind.EndOfParent => LiteralValueNilOfSpecifiedLength(this)
}
}
case NilKind.LiteralCharacter => {
@@ -1396,10 +1524,7 @@ trait ElementBaseGrammarMixin
case LengthKind.Implicit
if isSimpleType && impliedRepresentation == Representation.Binary =>
new SpecifiedLengthImplicit(this, body, implicitBinaryLengthInBits)
- case LengthKind.EndOfParent if isComplexType =>
- notYetImplemented("lengthKind='endOfParent' for complex type")
- case LengthKind.EndOfParent =>
- notYetImplemented("lengthKind='endOfParent' for simple type")
+ case LengthKind.EndOfParent => new SpecifiedLengthEndOfParent(this, body)
case LengthKind.Delimited | LengthKind.Implicit =>
Assert.impossibleCase(
"Delimited and ComplexType Implicit cases should not be reached"
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
index e069353bd5..fcda6161f8 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
@@ -191,6 +191,16 @@ case class HexBinaryLengthPrefixed(e: ElementBase) extends Terminal(e, true) {
new HexBinaryMinLengthInBytesUnparser(e.minLength.longValue, e.elementRuntimeData)
}
+case class HexBinaryLengthEndOfParent(e: ElementBase) extends Terminal(e, true) {
+
+ override lazy val parser: DaffodilParser = new HexBinaryEndOfBitLimitParser(
+ e.elementRuntimeData
+ )
+
+ override lazy val unparser: DaffodilUnparser =
+ new HexBinaryMinLengthInBytesUnparser(e.minLength.longValue, e.elementRuntimeData)
+}
+
abstract class PackedIntegerDelimited(
e: ElementBase,
packedSignCodes: PackedSignCodes
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/SpecifiedLength.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/SpecifiedLength.scala
index 0ae3e6a4d9..49baa728c2 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/SpecifiedLength.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/SpecifiedLength.scala
@@ -132,6 +132,30 @@ class SpecifiedLengthExplicit(e: ElementBase, eGram: => Gram, bitsMultiplier: In
}
+class SpecifiedLengthEndOfParent(e: ElementBase, eGram: => Gram)
+ extends SpecifiedLengthCombinatorBase(e, eGram) {
+
+ lazy val kind = "EndOfParent_" + e.lengthUnits.toString
+
+ lazy val parser: Parser = {
+ if (eParser.isEmpty) eParser
+ else
+ new SpecifiedLengthEndOfParentParser(
+ eParser,
+ e.elementRuntimeData
+ )
+ }
+
+ lazy val unparser: Unparser = {
+ if (eUnparser.isEmpty) eUnparser
+ else
+ new SpecifiedLengthEndOfParentUnparser(
+ eUnparser,
+ e.elementRuntimeData
+ )
+ }
+}
+
class SpecifiedLengthImplicit(e: ElementBase, eGram: => Gram, nBits: Long)
extends SpecifiedLengthCombinatorBase(e, eGram)
with SpecifiedLengthExplicitImplicitUnparserMixin {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
index 7c9f50efca..0dc7b21996 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
@@ -84,11 +84,8 @@ final class HexBinarySpecifiedLengthParser(erd: ElementRuntimeData, lengthEv: Le
}
final class HexBinaryEndOfBitLimitParser(erd: ElementRuntimeData)
- extends HexBinaryLengthParser(erd) {
+ extends HexBinaryLengthParser(erd),
+ BitLengthFromBitLimitMixin {
override def runtimeDependencies = Vector()
-
- override def getLengthInBits(pstate: PState): Long = {
- pstate.bitLimit0b.get - pstate.bitPos0b
- }
}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ParserTraits.scala
similarity index 100%
rename from daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala
rename to daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ParserTraits.scala
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
index 2f3ee1f5dd..1d2bb11521 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
@@ -132,6 +132,17 @@ class SpecifiedLengthPatternParser(
}
}
+class SpecifiedLengthEndOfParentParser(
+ eParser: Parser,
+ erd: ElementRuntimeData
+) extends SpecifiedLengthParserBase(eParser, erd),
+ BitLengthFromBitLimitMixin {
+
+ override protected def getBitLength(s: PState): MaybeULong = {
+ MaybeULong(super[BitLengthFromBitLimitMixin].getBitLength(s))
+ }
+}
+
class SpecifiedLengthExplicitParser(
eParser: Parser,
erd: ElementRuntimeData,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala b/daffodil-core/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
index 44af8e887a..071c810a04 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
@@ -72,6 +72,20 @@ final class SpecifiedLengthExplicitImplicitUnparser(
}
}
+final class SpecifiedLengthEndOfParentUnparser(
+ eUnparser: Unparser,
+ erd: ElementRuntimeData
+) extends CombinatorUnparser(erd) {
+
+ override def runtimeDependencies = Vector()
+
+ override def childProcessors = Vector(eUnparser)
+
+ override final def unparse(state: UState): Unit = {
+ eUnparser.unparse1(state)
+ }
+}
+
/**
* This trait is to be used with prefixed length unparsers where the length
* must be calculated based on the content length of the data. This means the
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
index c2be97ef3f..e97a545c6b 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
@@ -639,6 +639,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -664,6 +686,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4357,6 +4403,21 @@
+
+ IaaBbb
+
+
+
+
+
+ aa
+ bb
+
+
+
+
+
+
IAaabbee
@@ -4373,6 +4434,22 @@
+
+ IAaabbee
+
+
+
+
+
+ aa
+ bb
+
+ ee
+
+
+
+
+
aaTBbb
@@ -4613,4 +4690,6 @@
+
+
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml
index fdbcc2e32d..29aa3214f0 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml
@@ -20,9 +20,9 @@
description="Section 12 - lengthKind=endOfParent" 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:fn="http://www.w3.org/2005/xpath-functions"
- xmlns:ex="http://example.com" defaultRoundTrip="true">
+ xmlns:ex="http://example.com" defaultRoundTrip="onePass">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Schema Definition Error
+ endOfParent
+ but its parent
+ lengthKind
+ delimited
+
+
+
+
+
+
+ Schema Definition Error
+ endOfParent
+ but its parent
+ lengthKind
+ delimited
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Schema Definition Error
+ endOfParent
+ but its parent
+ lengthKind
+ implicit
+
+
+
+
+
+
+ Schema Definition Error
+ endOfParent
+ but its parent
+ lengthKind
+ implicit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+ 3
+ 3
+
+
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+ X
+ YZ
+
+ A
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+ 3
+ 3
+
+
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+ X
+ YZ
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+ 3
+ 3
+
+
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+ X
+ YZ
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+ 3
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+ YZ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ represented element
+ between this element and
+ end of the enclosing component
+
+
+
+
+
+
+ endOfParent
+ represented element
+ between this element and
+ end of the enclosing component
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
- Schema Definition Error
- not
- implemented
endOfParent
- complex
- type
+ model group
+ between this element and
+ end of the enclosing component
-
-
+
+
- Schema Definition Error
- not
- implemented
endOfParent
- simple
- type
+ model group
+ between this element and
+ end of the enclosing component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+ 3
+ 3
+
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+ YZ
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ specifies
+ terminator
+
+
+
+
+
+
+ endOfParent
+ specifies
+ terminator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ specifies
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+ endOfParent
+ specifies
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ specifies
+ maxOccurs
+ greater than 1
+
+
+
+
+
+
+ endOfParent
+ specifies
+ maxOccurs
+ greater than 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ does not have
+ single-byte character set encoding
+
+
+
+
+
+
+ endOfParent
+ does not have
+ single-byte character set encoding
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ separatorPosition
+ postfix
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ separatorPosition
+ postfix
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ sequenceKind
+ unordered
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ sequenceKind
+ unordered
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ elements
+ floating='yes
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ elements
+ floating='yes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+ endOfParent
+ in a sequence with
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a choice with
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+ endOfParent
+ in a choice with
+ non-zero
+ trailingSkip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ endOfParent
+ in a choice with
+ terminator
+
+
+
+
+
+
+ endOfParent
+ in a choice with
+ terminator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ simple type
+ endOfParent
+ isn't a string type
+
+
+
+
+
+
+ simple type
+ endOfParent
+ doesn't have binary representation with packed decimal representation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+ 3132
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+ 12
+
+
+
+
+
+
+
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
index 3c4de0add4..ad587d2a09 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
@@ -209,6 +209,10 @@ class TestAlignedData extends TdmlTests {
@Test def prior_siblings_3 = test
@Test def prior_siblings_4 = test
@Test def prior_siblings_5 = test
+
+ // DAFFODIL-238
+ @Test def test_init_alignment_1_eop = test
+ @Test def test_init_alignment_2_eop = test
}
class TestBinaryInput extends TdmlTests {
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent.scala
new file mode 100644
index 0000000000..53f25c3720
--- /dev/null
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent.scala
@@ -0,0 +1,74 @@
+/*
+ * 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.section12.lengthKind
+
+import org.apache.daffodil.junit.tdml.TdmlSuite
+import org.apache.daffodil.junit.tdml.TdmlTests
+
+import org.junit.Test
+
+object TestLengthKindEndOfParent extends TdmlSuite {
+ val tdmlResource = "/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml"
+}
+
+class TestLengthKindEndOfParent extends TdmlTests {
+ val tdmlSuite = TestLengthKindEndOfParent
+
+ @Test def TestEndOfParentComplexTypesDelimited = test
+ @Test def TestEndOfParentSimpleTypesDelimited = test
+ @Test def TestEndOfParentComplexTypesImplicit = test
+ @Test def TestEndOfParentSimpleTypesImplicit = test
+ @Test def TestEndOfParentComplexTypesExplicit = test
+ @Test def TestEndOfParentSimpleTypesExplicit = test
+ @Test def TestEndOfParentComplexTypesPrefixed = test
+ @Test def TestEndOfParentSimpleTypesPrefixed = test
+ @Test def TestEndOfParentComplexTypesPattern = test
+ @Test def TestEndOfParentSimpleTypesPattern = test
+ @Test def TestEndOfParentComplexTypesEOP = test
+ @Test def TestEndOfParentSimpleTypesEOP = test
+ @Test def TestEndOfParentComplexTypes1 = test
+ @Test def TestEndOfParentSimpleTypes1 = test
+ @Test def TestEndOfParentComplexTypes2 = test
+ @Test def TestEndOfParentSimpleTypes2 = test
+ @Test def TestEndOfParentComplexTypes3 = test
+ @Test def TestEndOfParentSimpleTypes3 = test
+ @Test def TestEndOfParentComplexTypes4 = test
+ @Test def TestEndOfParentSimpleTypes4 = test
+ @Test def TestEndOfParentComplexTypes5 = test
+ @Test def TestEndOfParentSimpleTypes5 = test
+ @Test def TestEndOfParentComplexTypes6 = test
+ @Test def TestEndOfParentSimpleTypes6 = test
+ @Test def TestEndOfParentComplexTypes7 = test
+ @Test def TestEndOfParentSimpleTypes7 = test
+ @Test def TestEndOfParentComplexTypes8 = test
+ @Test def TestEndOfParentSimpleTypes8 = test
+ @Test def TestEndOfParentComplexTypes9 = test
+ @Test def TestEndOfParentSimpleTypes9 = test
+ @Test def TestEndOfParentComplexTypes10 = test
+ @Test def TestEndOfParentSimpleTypes10 = test
+ @Test def TestEndOfParentComplexTypes11 = test
+ @Test def TestEndOfParentSimpleTypes11 = test
+ @Test def TestEndOfParentComplexTypes12 = test
+ @Test def TestEndOfParentSimpleTypes12 = test
+ @Test def TestEndOfParentComplexTypes13 = test
+ @Test def TestEndOfParentSimpleTypes13 = test
+ @Test def TestEndOfParentSimpleTypes14 = test
+ @Test def TestEndOfParentSimpleTypes15 = test
+ @Test def TestEndOfParentSimpleTypes16 = test
+ @Test def TestEndOfParentSimpleTypes17 = test
+}
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent2.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent2.scala
deleted file mode 100644
index 5928ed5f71..0000000000
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindEndOfParent2.scala
+++ /dev/null
@@ -1,34 +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.section12.lengthKind
-
-import org.apache.daffodil.junit.tdml.TdmlSuite
-import org.apache.daffodil.junit.tdml.TdmlTests
-
-import org.junit.Test
-
-object TestLengthKindEndOfParent2 extends TdmlSuite {
- val tdmlResource = "/org/apache/daffodil/section12/lengthKind/EndOfParentTests.tdml"
-}
-
-class TestLengthKindEndOfParent2 extends TdmlTests {
- val tdmlSuite = TestLengthKindEndOfParent2
-
- @Test def TestEndOfParentNYIComplexTypes = test
- @Test def TestEndOfParentNYISimpleTypes = test
-}