def parse()

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)
    }
  }