Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ import org.apache.daffodil.core.compiler.ForParser
import org.apache.daffodil.core.compiler.ForUnparser
import org.apache.daffodil.core.dsom.*
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.runtime1.processors.parsers.AssertExpressionEvaluationParser
import org.apache.daffodil.runtime1.processors.parsers.NadaParser
import org.apache.daffodil.runtime1.processors.parsers.SeqCompParser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.SeqCompBuilder
import org.apache.daffodil.runtime1.processors.unparsers.SeqCompUnparser
import org.apache.daffodil.unparsers.runtime1.NadaUnparser

Expand Down Expand Up @@ -124,6 +129,26 @@ class SeqComp private (context: SchemaComponent, children: Seq[Gram])
else if (unparserChildren.length == 1) unparserChildren.head
else new SeqCompUnparser(context.runtimeData, unparserChildren.toArray)
}

// Only the (usually at most one) child(ren) that actually build infoset
// content contribute here; write-only children (delimiters, padding, etc.)
// simply have no builder to collect.
lazy val builderChildren: Array[Builder] = {
children
.filter(x => !x.isEmpty && (x.forWhat != ForParser))
.flatMap { x => x.builder.toList }
.toArray
}

final override lazy val builder: Maybe[Builder] = {
if (builderChildren.isEmpty) {
Nope
} else if (builderChildren.length == 1) {
One(builderChildren.head)
} else {
One(new SeqCompBuilder(builderChildren))
}
}
}

object EmptyGram extends Gram(null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import org.apache.daffodil.core.compiler.ForUnparser
import org.apache.daffodil.core.compiler.ParserOrUnparser
import org.apache.daffodil.core.dsom.SchemaComponent
import org.apache.daffodil.lib.util.Logger
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.runtime1.processors.parsers.NadaParser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.unparsers.runtime1.NadaUnparser

/**
Expand Down Expand Up @@ -107,4 +110,16 @@ final class Prod(
else
unp
}

final override lazy val builder: Maybe[Builder] = {
if (gram.isEmpty) {
Nope
} else {
(forWhat, gram.forWhat) match {
case (ForParser, _) => Nope
case (_, ForParser) => Nope
case _ => gram.builder
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ import org.apache.daffodil.lib.cookers.ChoiceBranchKeyCooker
import org.apache.daffodil.lib.cookers.IntRangeCooker
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.schema.annotation.props.gen.ChoiceLengthKind
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.lib.util.MaybeInt
import org.apache.daffodil.lib.util.ProperlySerializableMap.*
import org.apache.daffodil.runtime1.infoset.ChoiceBranchEvent
import org.apache.daffodil.runtime1.processors.RangeBound
import org.apache.daffodil.runtime1.processors.TermRuntimeData
import org.apache.daffodil.runtime1.processors.parsers.*
import org.apache.daffodil.runtime1.processors.unparsers.*
import org.apache.daffodil.unparsers.runtime1.*
Expand Down Expand Up @@ -332,4 +336,31 @@ case class ChoiceCombinator(ch: ChoiceTermBase, alternatives: Seq[Gram])
new ChoiceCombinatorUnparser(ch.modelGroupRuntimeData, cbm, choiceLengthInBits)
}
}

override lazy val builder: Maybe[Builder] = {
val (eventRDMap, optDefaultBranch) = ch.choiceBranchMap

def builderFor(term: Term): (TermRuntimeData, Builder) = {
val cb = term.termContentBody.builder
val b = if (cb.isDefined) {
cb.get
} else {
EmptyBuilder
}
(term.termRuntimeData, b)
}

val branchMap: Map[ChoiceBranchEvent, (TermRuntimeData, Builder)] =
eventRDMap.map { case (cbe, branchTerm) => (cbe, builderFor(branchTerm)) }
val defaultBranch: Maybe[(TermRuntimeData, Builder)] = optDefaultBranch match {
case Some(term) => One(builderFor(term))
case None => Nope
}

if (branchMap.isEmpty && defaultBranch.isEmpty) {
Nope
} else {
One(new ChoiceBuilder(ch.modelGroupRuntimeData, branchMap, defaultBranch))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import org.apache.daffodil.core.dsom.*
import org.apache.daffodil.core.grammar.Gram
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.*
import org.apache.daffodil.lib.util.Misc
import org.apache.daffodil.lib.xml.XMLUtils
import org.apache.daffodil.runtime1.processors.parsers.{ Parser as DaffodilParser, * }
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.Unparser as DaffodilUnparser
import org.apache.daffodil.unparsers.runtime1.*

Expand Down Expand Up @@ -55,6 +57,10 @@ case class DelimiterStackCombinatorSequence(sq: SequenceTermBase, body: Gram)

override lazy val unparser: DaffodilUnparser =
new DelimiterStackUnparser(uInit, uSep, uTerm, sq.termRuntimeData, body.unparser)

// Delimiters are write-only content; the builder tree skips straight to
// whatever this sequence's body itself builds, if anything.
override lazy val builder: Maybe[Builder] = body.builder
}

case class DelimiterStackCombinatorChoice(ch: ChoiceTermBase, body: Gram)
Expand All @@ -77,6 +83,10 @@ case class DelimiterStackCombinatorChoice(ch: ChoiceTermBase, body: Gram)

override lazy val unparser: DaffodilUnparser =
new DelimiterStackUnparser(uInit, None, uTerm, ch.termRuntimeData, body.unparser)

// Delimiters are write-only content; the builder tree skips straight to
// whatever this choice's body itself builds, if anything.
override lazy val builder: Maybe[Builder] = body.builder
}

case class DelimiterStackCombinatorElement(e: ElementBase, body: Gram)
Expand Down Expand Up @@ -111,6 +121,10 @@ case class DelimiterStackCombinatorElement(e: ElementBase, body: Gram)
if (u.isEmpty) u
else new DelimiterStackUnparser(uInit, None, uTerm, e.termRuntimeData, u)
}

// Delimiters are write-only content; the builder tree skips straight to
// whatever this element's body itself builds, if anything.
override lazy val builder: Maybe[Builder] = body.builder
}

case class DynamicEscapeSchemeCombinatorElement(e: ElementBase, body: Gram)
Expand All @@ -135,4 +149,9 @@ case class DynamicEscapeSchemeCombinatorElement(e: ElementBase, body: Gram)
if (u.isEmpty || schemeUnparseIsConstant) u
else new DynamicEscapeSchemeUnparser(schemeUnparseOpt.get, e.termRuntimeData, u)
}

// The escape scheme only governs delimiter matching in written bytes; the
// builder tree skips straight to whatever this element's body itself
// builds, if anything.
override lazy val builder: Maybe[Builder] = body.builder
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import org.apache.daffodil.lib.schema.annotation.props.gen.LengthKind
import org.apache.daffodil.lib.schema.annotation.props.gen.Representation
import org.apache.daffodil.lib.schema.annotation.props.gen.TestKind
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.runtime1.processors.parsers.CaptureEndOfContentLengthParser
import org.apache.daffodil.runtime1.processors.parsers.CaptureEndOfValueLengthParser
import org.apache.daffodil.runtime1.processors.parsers.CaptureStartOfContentLengthParser
Expand All @@ -36,6 +38,8 @@ import org.apache.daffodil.runtime1.processors.parsers.ElementParser
import org.apache.daffodil.runtime1.processors.parsers.ElementParserInputValueCalc
import org.apache.daffodil.runtime1.processors.parsers.NadaParser
import org.apache.daffodil.runtime1.processors.parsers.Parser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.ElementBuilder
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
import org.apache.daffodil.unparsers.runtime1.CaptureEndOfContentLengthUnparser
import org.apache.daffodil.unparsers.runtime1.CaptureEndOfValueLengthUnparser
Expand All @@ -44,6 +48,7 @@ import org.apache.daffodil.unparsers.runtime1.CaptureStartOfValueLengthUnparser
import org.apache.daffodil.unparsers.runtime1.ElementOVCSpecifiedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.ElementOVCUnspecifiedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.ElementSpecifiedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.ElementUnparserBase
import org.apache.daffodil.unparsers.runtime1.ElementUnparserInputValueCalc
import org.apache.daffodil.unparsers.runtime1.ElementUnspecifiedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.ElementUnusedUnparser
Expand Down Expand Up @@ -143,6 +148,37 @@ class ElementCombinator(
}
}

private lazy val eBuilder: Maybe[Builder] = {
if (eValue.isEmpty) {
Nope
} else {
eValue.builder
}
}
private lazy val eReptypeBuilder: Maybe[Builder] = repTypeElementGram.builder

// Reuses the same already-memoized instance above for unparseBegin/
// unparseEnd, so build() and write() see identical node-creation
// behavior; the third branch's builder is whatever subComb builds.
override lazy val builder: Maybe[Builder] = unparser match {
case eu @ (_: ElementOVCSpecifiedLengthUnparser | _: ElementSpecifiedLengthUnparser) => {
val eub = eu.asInstanceOf[ElementUnparserBase]
val contentBuilder = if (eReptypeBuilder.isDefined) {
eReptypeBuilder
} else {
eBuilder
}
One(
new ElementBuilder(
context.erd,
eub.unparseBeginForBuild,
eub.unparseEndForBuild,
contentBuilder
)
)
}
case _ => subComb.builder
}
}

case class ElementUnused(ctxt: ElementBase)
Expand Down Expand Up @@ -374,6 +410,26 @@ class ElementParseAndUnspecifiedLength(
new ElementUnparserInputValueCalc(context.erd, uSetVar)
}
}

// Reuses the same already-memoized ElementUnparserBase instance above for
// unparseBegin/unparseEnd, so build() and write() see identical
// nilled/OVC/IVC node-creation behavior.
override lazy val builder: Maybe[Builder] = {
val eu = unparser.asInstanceOf[ElementUnparserBase]
val contentBuilder = if (eRepTypeBuilder.isDefined) {
eRepTypeBuilder
} else {
eBuilder
}
One(
new ElementBuilder(
context.erd,
eu.unparseBeginForBuild,
eu.unparseEndForBuild,
contentBuilder
)
)
}
}

abstract class ElementCombinatorBase(
Expand Down Expand Up @@ -449,4 +505,8 @@ abstract class ElementCombinatorBase(

def unparser: Unparser

lazy val eBuilder: Maybe[Builder] = eGram.builder

lazy val eRepTypeBuilder: Maybe[Builder] = repTypeElementGram.builder

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ package org.apache.daffodil.core.grammar.primitives
import org.apache.daffodil.core.dsom.ModelGroup
import org.apache.daffodil.core.grammar.Gram
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.runtime1.processors.parsers.HiddenGroupCombinatorParser
import org.apache.daffodil.runtime1.processors.parsers.Parser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.HiddenGroupBuilder
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
import org.apache.daffodil.unparsers.runtime1.HiddenGroupCombinatorUnparser

Expand All @@ -34,4 +39,12 @@ final class HiddenGroupCombinator(ctxt: ModelGroup, body: Gram)
override lazy val unparser: Unparser =
new HiddenGroupCombinatorUnparser(ctxt.modelGroupRuntimeData, body.unparser)

override lazy val builder: Maybe[Builder] = {
val bb = body.builder
if (bb.isEmpty) {
Nope
} else {
One(new HiddenGroupBuilder(bb.get))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ package org.apache.daffodil.core.grammar.primitives
import org.apache.daffodil.core.dsom.*
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.core.layers.LayerSchemaCompiler
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.lib.util.Misc
import org.apache.daffodil.runtime1.processors.parsers.LayeredSequenceParser
import org.apache.daffodil.runtime1.processors.parsers.Parser as DaffodilParser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.SequenceBuilder
import org.apache.daffodil.runtime1.processors.unparsers.Unparser as DaffodilUnparser
import org.apache.daffodil.unparsers.runtime1.LayeredSequenceUnparser

Expand All @@ -47,4 +52,18 @@ case class LayeredSequence(sq: SequenceGroupTermBase, bodyTerm: SequenceChild)

override lazy val unparser: DaffodilUnparser =
new LayeredSequenceUnparser(srd, bodyUnparser)

// The layer transform itself is a write-only, byte-level concern, but
// (unlike delimiters/escape schemes) this is still a genuine one-child
// sequence position: it must push/pop bodyTerm's TRD and advance the
// group index the same way SequenceBuilder does for any other sequence
// child, or next-element resolution on the shared InfosetInputter breaks.
override lazy val builder: Maybe[Builder] = {
val info = bodyTerm.optSequenceChildBuildInfo
if (info.isEmpty) {
Nope
} else {
One(new SequenceBuilder(IndexedSeq(info.get)))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ import org.apache.daffodil.core.dsom.ElementBase
import org.apache.daffodil.core.grammar.Gram
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.runtime1.processors.parsers.ComplexNilOrContentParser
import org.apache.daffodil.runtime1.processors.parsers.SimpleNilOrValueParser
import org.apache.daffodil.runtime1.processors.unparsers.Builder
import org.apache.daffodil.runtime1.processors.unparsers.NilOrContentBuilder
import org.apache.daffodil.unparsers.runtime1.ComplexNilOrContentUnparser
import org.apache.daffodil.unparsers.runtime1.SimpleNilOrValueUnparser

Expand Down Expand Up @@ -59,4 +64,15 @@ case class ComplexNilOrContent(ctxt: ElementBase, nilGram: Gram, contentGram: Gr
override lazy val unparser =
ComplexNilOrContentUnparser(ctxt.erd, nilUnparser, contentUnparser)

// A nilled complex element has no children to build; nilled-ness is only
// known once the node exists, so this needs a real runtime check, not a
// static pass-through.
override lazy val builder: Maybe[Builder] = {
val cb = contentGram.builder
if (cb.isEmpty) {
Nope
} else {
One(new NilOrContentBuilder(cb.get))
}
}
}
Loading
Loading