stevedlawrence commented on a change in pull request #419:
URL: https://github.com/apache/incubator-daffodil/pull/419#discussion_r488074239
##########
File path:
daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetWalker.scala
##########
@@ -321,132 +390,114 @@ class InfosetWalker private (
}
}
- private trait InfosetWalkerStep {
- /**
- * Output events associated with this step kind, and mutate the
- * InfosetWalker state to walk to the next node in the infoset
- */
- def step(): Unit
-
- final def moveToFirstChild(newContainer: DINode): Unit = {
- containerNode = newContainer
- containerIndexStack.push(0)
- }
+ @inline
+ private def moveToFirstChild(newContainer: DINode): Unit = {
+ containerNodeStack.push(newContainer)
+ containerIndexStack.push(0)
+ }
- final def moveToContainer(): Unit = {
- containerNode = containerNode.containerNode
- containerIndexStack.pop
- }
+ @inline
+ private def moveToContainer(): Unit = {
+ containerNodeStack.pop
+ containerIndexStack.pop
+ }
- final def moveToNextSibling(): Unit = {
- containerIndexStack.push(containerIndexStack.pop + 1)
- }
+ @inline
+ private def moveToNextSibling(): Unit = {
+ val top = containerIndexStack.top
+ containerIndexStack.setTop(top + 1)
}
- private object InfosetWalkerStepStart extends InfosetWalkerStep {
- /**
- * Start the document. Note that because the top of container index is
- * initialized to one less that the starting index, we also call
- * moveToNextSibling to increment the starting index to the correct
- * position.
- */
- override def step(): Unit = {
- outputter.startDocument()
- moveToNextSibling()
- }
+ /**
+ * Start the document. Note that because the top of container index is
+ * initialized to one less that the starting index, we also call
+ * moveToNextSibling to increment the starting index to the correct
+ * position.
+ */
+ private def infosetWalkerStepStart(): Unit = {
+ outputter.startDocument()
+ moveToNextSibling()
}
- private object InfosetWalkerStepEnd extends InfosetWalkerStep {
- /**
- * End document and clean up state. Setting finished to true causes
- * the next step to be None, walk() will return, and the caller
- * should not call walk() again because it is finished.
- */
- override def step(): Unit = {
- outputter.endDocument()
- containerNode = null
- containerIndexStack = null
- finished = true
- }
+ /**
+ * End document and clean up state. Setting finished to true causes
+ * the next step to be None, walk() will return, and the caller
+ * should not call walk() again because it is finished.
+ */
+ private def infosetWalkerStepEnd(): Unit = {
+ outputter.endDocument()
+ containerNodeStack = null
+ containerIndexStack = null
+ finished = true
}
- private object InfosetWalkerStepMove extends InfosetWalkerStep {
- /**
- * Output start/end events for DIComplex/DIArray/DISimple, and mutate state
- * so we are looking at the next node in the infoset.
- */
- def step(): Unit = {
- val children = containerNode.contents
- val childIndex = containerIndexStack.top
-
- if (childIndex < children.size) {
- // This block means we need to create a start event for the element in
- // the children array at childIndex. We then need to mutate the walker
- // state so the next call to step() is for either the first child of
- // this element or the next sibling.
-
- children(childIndex) match {
- case s: DISimple => {
- if (!s.isHidden || walkHidden) {
- outputter.startSimple(s)
- outputter.endSimple(s)
- }
- if (removeUnneeded) {
- // now we can remove this simple element to free up memory
- containerNode.freeChildIfNoLongerNeeded(containerIndexStack.top)
- }
- moveToNextSibling()
- }
- case c: DIComplex => {
- if (!c.isHidden || walkHidden) {
- outputter.startComplex(c)
- moveToFirstChild(c)
- } else {
- moveToNextSibling()
- }
- }
- case a: DIArray => {
- if (!a.isHidden || walkHidden) {
- outputter.startArray(a)
- moveToFirstChild(a)
- } else {
- moveToNextSibling()
- }
- }
- }
+ /**
+ * Output start/end events for DIComplex/DIArray/DISimple, and mutate state
+ * so we are looking at the next node in the infoset.
+ */
+ private def infosetWalkerStepMove(containerNode: DINode, containerIndex:
Int): Unit = {
+ val children = containerNode.contents
- } else {
- // This else block means that we incremented the index stack past the
- // number of children in this container (must be a DIComplex/DIDocument
- // or DIArray), which means we have created events for all if its
- // children. So we must now create the appropriate end event for the
- // container and then mutate the state so that we are looking at its
- // next sibling. Note that if there is no next sibling, that will be
- // found the next time step() is called (because we incremented past
- // this element) and we will fall into this block again, call the end
- // function again, and repeat the process.
-
- // create appropriate end event
- containerNode match {
- case a: DIArray => {
- outputter.endArray(a)
- }
- case c: DIComplex => {
- outputter.endComplex(c)
- }
- case _ => Assert.impossible()
- }
+ if (containerIndex < children.size) {
+ // This block means we need to create a start event for the element in
+ // the children array at containerIndex. We then need to mutate the
walker
+ // state so the next call to step() is for either the first child of
+ // this element or the next sibling.
Review comment:
The state of the infoset walker is always pointing at a child index for
elements to create events for. This block is going to create an event for the
containerIndex'th element in the current containerNode. After it creates that
event, it needs to mutate state so the next time we take a step we are looking
at the next element. If this is a complex type, the next element is the first
child. If this is not a complex element, the next element is the next sibling.
So that's what this is trying to say. I'll update this to be a bit more clear.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]