private def unparseWithNoSuppression()

in daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SeparatedSequenceUnparsers.scala [591:720]


  private def unparseWithNoSuppression(state: UState): Unit = {

    state.groupIndexStack.push(1L) // one-based indexing

    var index = 0
    var doUnparser = false
    val limit = childUnparsers.length

    while (index < limit) {
      val childUnparser = childUnparsers(index)
      val trd = childUnparser.trd
      state.pushTRD(trd) // because we inspect before we invoke child unparser
      //
      // Unparsing an ordered sequence depends on the incoming
      // stream of infoset events matching up with the order that
      // they are expected as the unparser recurses through the
      // child term unparsers.
      //
      childUnparser match {
        case unparser: RepOrderedSeparatedSequenceChildUnparser => {
          state.arrayIterationIndexStack.push(1L)
          state.occursIndexStack.push(1L)
          val erd = unparser.erd
          Assert.invariant(erd.isArray || erd.isOptional)
          Assert.invariant(erd.isRepresented) // arrays/optionals cannot have inputValueCalc

          var numOccurrences = 0
          val maxReps = unparser.maxRepeats(state)

          Assert.invariant(state.inspect)
          val ev = state.inspectAccessor
          val isArr = erd.isArray

          // If the event is for this Rep unparser, we need to consume the StartArray event
          if (ev.erd eq erd) {
            unparser.startArrayOrOptional(state)
          }

          // Unparse each occurrence of this array in the infoset. Note that there could be zero
          // occurrences
          while ({
            doUnparser = unparser.shouldDoUnparser(unparser, state)
            doUnparser
          }) {
            //
            // These are so we can check invariants on these stacks being
            // pushed and popped reliably, and incremented only once
            //
            val arrayIterationIndexBefore = state.arrayIterationPos
            val arrayIterationIndexStackDepthBefore =
              state.arrayIterationIndexStack.length
            val occursIndexBefore = state.occursPos
            val occursIndexStackDepthBefore = state.occursIndexStack.length
            val groupIndexBefore = state.groupPos
            val groupIndexStackDepthBefore = state.groupIndexStack.length

            if (isArr && state.dataProc.isDefined)
              state.dataProc.get.beforeRepetition(state, this)

            unparseOne(unparser, erd, state)
            numOccurrences += 1
            Assert.invariant(
              state.arrayIterationIndexStack.length == arrayIterationIndexStackDepthBefore
            )
            state.moveOverOneArrayIterationIndexOnly()
            Assert.invariant(state.arrayIterationPos == arrayIterationIndexBefore + 1)

            Assert.invariant(state.occursIndexStack.length == occursIndexStackDepthBefore)
            state.moveOverOneOccursIndexOnly()
            Assert.invariant(state.occursPos == occursIndexBefore + 1)

            Assert.invariant(state.groupIndexStack.length == groupIndexStackDepthBefore)
            state.moveOverOneGroupIndexOnly() // array elements are always represented.
            Assert.invariant(state.groupPos == groupIndexBefore + 1)

            if (isArr && state.dataProc.isDefined)
              state.dataProc.get.afterRepetition(state, this)
          }

          // If not enough occurrences are in the infoset, we output extra separators because
          // we are unparsing with no suppression
          if (maxReps > numOccurrences) {
            var numExtraSeps = {
              val sepsNeeded = erd.maxOccurs - numOccurrences
              if ((spos eq Infix) && state.groupPos == 1) {
                // If separatorPosition is infix and we haven't output anything for this sequence
                // yet, then we need one less extra separator, since the separator is skipped
                // for the first instance of infix separators.
                sepsNeeded - 1
              } else {
                sepsNeeded
              }
            }
            while (numExtraSeps > 0) {
              unparseJustSeparator(state)
              numExtraSeps -= 1
            }
          }

          unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(
            state,
            unparser,
            numOccurrences,
            maxReps,
            state.arrayIterationPos - 1
          )

          // If the event is for this Rep unparser, we need to consume the EndArray event
          if (ev.erd eq erd) {
            unparser.endArrayOrOptional(erd, state)
          }

          state.arrayIterationIndexStack.pop()
          state.occursIndexStack.pop()
        }
        case scalarUnparser => {
          unparseOne(scalarUnparser, trd, state)
          // only move over in group if the scalar "thing" is an element
          // that is represented.
          trd match {
            case erd: ElementRuntimeData if (!erd.isRepresented) => // ok, skip group advance
            case _ => state.moveOverOneGroupIndexOnly()
          }
        }
      }
      state.popTRD(trd)
      index += 1
    }
    state.groupIndexStack.pop()
  }