in daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ElementCombinator1.scala [99:214]
def parse(pstate: PState): Unit = {
// Note that pattern discriminators and asserts do not advance the position
// in the input stream, so there is no need to mark/reset the inputstream
if (patDiscrimParser.isDefined) {
patDiscrimParser.get.parse1(pstate)
if (pstate.processorStatus ne Success) {
return
}
} else if (patAssertParser.length > 0) {
var i: Int = 0
val size = patAssertParser.size
while (i < size) {
val d = patAssertParser(i)
d.parse1(pstate)
if (pstate.processorStatus ne Success) {
return
}
i += 1
}
}
parseBegin(pstate)
try {
// TODO: Performance/Maintainability - get rid of use of return statements.
if (pstate.processorStatus ne Success) return // but finally at the bottom will run!
if (eBeforeParser.isDefined)
eBeforeParser.get.parse1(pstate)
if (pstate.processorStatus ne Success) return
// We just successfully created the element in the infoset. Notify the
// debugger of this so it can do things like check for break points
if (pstate.dataProc.isDefined) pstate.dataProc.value.startElement(pstate, this)
if (eRepTypeParser.isDefined) {
eRepTypeParser.get.parse1(pstate)
} else if (eParser.isDefined) {
eParser.get.parse1(pstate)
}
Assert.invariant(pstate.hasInfoset)
var setVarFailureDiags: Seq[Diagnostic] = Nil
if (pstate.processorStatus eq Success) {
var i: Int = 0
while (i < setVarParser.length) {
val d = setVarParser(i)
i += 1
d.parse1(pstate)
if (pstate.processorStatus ne Success) {
setVarFailureDiags = pstate.diagnostics
// a setVariable statement may fail. But we want to continue to try
// more of the setVariable statements, as they may be necessary
// to evaluate the test discriminator below, and some might
// be successful even if one fails, allowing the discriminator to be true.
//
// So it's a bit odd, but we're going to just keep parsing using this
// failed state as the input to the next setVariable parse step.
}
}
}
if (testDiscrimParser.isDefined) {
testDiscrimParser.get.parse1(pstate)
// Tests fail at the end of the Element
if (pstate.processorStatus ne Success) { return }
}
//
// We're done with the discriminator, so now we revisit the set variable statements.
// If a failure occurred there, then now we can fail out right here.
//
if (!setVarFailureDiags.isEmpty) {
pstate.setFailed(setVarFailureDiags.head)
return
}
// Element evaluation failed, return
if (pstate.processorStatus ne Success) { return }
{
var i = 0
while (i < testAssertParser.length) {
val d = testAssertParser(i)
i += 1
d.parse1(pstate)
// Tests fail at the end of the Element
if (pstate.processorStatus ne Success) { return }
}
}
if (eAfterParser.isDefined)
eAfterParser.get.parse1(pstate)
if (pstate.processorStatus ne Success) return
// if we should do limited validation via CheckConstraints
val shouldValidate = erd.isSimpleType &&
pstate.dataProc.isDefined &&
pstate.dataProc.value.validationMode == ValidationMode.Limited
if (shouldValidate) {
validate(pstate)
}
} finally {
parseEnd(pstate)
if (pstate.dataProc.isDefined) pstate.dataProc.value.endElement(pstate, this)
}
}