jadams-tresys commented on a change in pull request #214: Sequences and 
Separators Refactoring and Rewrite
URL: https://github.com/apache/incubator-daffodil/pull/214#discussion_r286525077
 
 

 ##########
 File path: 
daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
 ##########
 @@ -27,60 +27,294 @@ import 
org.apache.daffodil.schema.annotation.props.gen.OccursCountKind
 import org.apache.daffodil.schema.annotation.props.SeparatorSuppressionPolicy
 import org.apache.daffodil.schema.annotation.props.gen.LengthKind
 import org.apache.daffodil.schema.annotation.props.gen.Representation
+import SeparatorSuppressionPolicy._
+import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.schema.annotation.props.EmptyElementParsePolicy
+import org.apache.daffodil.processors.parsers._
+import org.apache.daffodil.processors.TerminatorParseEv
 
 /**
  * A SequenceChild is exactly that, a child Term of a Sequence
  *
+ * Methods/members of this class combine information about a child term
+ * with that about the sequence itself. This class is really a part of the
+ * state of the sequence object.
+ *
+ * This is the class primarily responsible for compilation of sequence
+ * and term information into digested form for the runtime, such
+ * that the runtime can properly implement complex DFDL behaviors like
+ * separator suppression and emptyElementParsePolicy.
+ *
  * These objects are part of the Gram object hierarchy.
  * They represent the use of a Term in a context. They are
  * objects that belong to (are owned by exactly one) the enclosing sequence, 
are part of it, and
  * so it is reasonable for a SequenceChild to have a backpointer to the
- * enclosing Sequence object.
+ * enclosing Sequence object in all cases, and this is passed to them on 
construction.
+ * This particular backpointer is
+ * not a challenge to sharing substructure as these objects cannot and are
+ * not intended to be shared. They really are state of the enclosing sequence
+ * broken out for convenience.
  *
- * This allows the Term object that provides the definition of the 
SequenceChild
- * to be shared/reused, in principle without having a backpointer to the
- * enclosing Sequence. That allows sharing, and removes lots of 
duplication/copying
- * in the schema compiler data strucures.
+ * This allows the child (of the Sequence) Term object (dsom object) that 
provides the
+ * definition of the SequenceChild to be shared/reused, in principle without 
having
+ * a backpointer to the enclosing Sequence. That allows sharing, and removes 
lots of
+ * duplication/copying that is otherwise needed in the schema compiler data 
structures.
  *
  * Eventually things like alignment calculations should move from
  * Terms to these objects. That is, those calculations should not be done
  * on the DSOM objects, but on these SequenceChild objects in the Gram
  * objects.
  */
-abstract class SequenceChild(
-  protected val sq: SequenceTermBase, child: Term, groupIndex: Int)
+abstract class SequenceChild(protected val sq: SequenceTermBase, child: Term, 
groupIndex: Int)
   extends Terminal(child, true) {
+  import SeparatorSuppressionPolicy._
+  import SeparatedSequenceChildBehavior._
+
+  private lazy val sgtb = sq.asInstanceOf[SequenceGroupTermBase]
 
-  protected def childParser = child.termContentBody.parser
-  protected def childUnparser = child.termContentBody.unparser
+  protected lazy val childParser = child.termContentBody.parser
+  protected lazy val childUnparser = child.termContentBody.unparser
 
-  final override def parser = sequenceChildParser
-  final override def unparser = sequenceChildUnparser
+  final override lazy val parser = sequenceChildParser
+  final override lazy val unparser = sequenceChildUnparser
 
   protected def sequenceChildParser: SequenceChildParser
   protected def sequenceChildUnparser: SequenceChildUnparser
 
-  def optSequenceChildParser: Option[SequenceChildParser] =
+  final lazy val optSequenceChildParser: Option[SequenceChildParser] =
     if (childParser.isEmpty) None else Some(parser)
 
-  def optSequenceChildUnparser: Option[SequenceChildUnparser] =
+  final lazy val optSequenceChildUnparser: Option[SequenceChildUnparser] =
     if (childUnparser.isEmpty) None else Some(unparser)
 
-  protected lazy val sepGram = sq.sequenceSeparator
+  /**
+   * There's only parse result helpers here, so let's abbreviate
+   */
+  protected type SeparatedHelper = SeparatedSequenceChildParseResultHelper
+  protected type UnseparatedHelper = UnseparatedSequenceChildParseResultHelper
+
+  protected def separatedHelper: SeparatedHelper
+  protected def unseparatedHelper: UnseparatedHelper
+
+  protected lazy val sepGram = {
+    sscb match {
+      case _: PositionalLike =>
+        sgtb.checkSeparatorTerminatorConflict
+      case _ => // ok
+    }
+    sq.sequenceSeparator
+  }
+
   protected lazy val sepParser = sepGram.parser
   protected lazy val sepUnparser = sepGram.unparser
 
-  lazy val srd = sq.sequenceRuntimeData
-  lazy val trd = child.termRuntimeData
+  final protected def srd = sq.sequenceRuntimeData
+  final protected def trd = child.termRuntimeData
+  final def termRuntimeData = trd
+  final protected lazy val mgrd = 
child.asInstanceOf[ModelGroup].modelGroupRuntimeData
+  final protected lazy val erd = 
child.asInstanceOf[ElementBase].elementRuntimeData
+
+  private lazy val childElement = child.asInstanceOf[ElementBase]
+  private lazy val childModelGroup = child.asInstanceOf[ModelGroup]
+
+  protected final def ssp = sq.separatorSuppressionPolicy
+
+  protected lazy val separatedSequenceChildBehavior: 
SeparatedSequenceChildBehavior = {
+    import SeparatorSuppressionPolicy._
+    import SeparatedSequenceChildBehavior._
+    child match {
+      case m: ModelGroup => {
+        if (child.isPotentiallyTrailing) {
+          ssp match {
+            case AnyEmpty => NonPositional
+            case TrailingEmpty => PositionalTrailingLax
+            case TrailingEmptyStrict => PositionalTrailingStrict
+            case Never => Positional
+          }
+        } else {
+          Positional
+        }
+      }
+      case eb: ElementBase if (eb.isArray || eb.isOptional) => {
+        import OccursCountKind._
+        eb.occursCountKind match {
+          case Fixed => Positional
+          case Expression => Positional
+          case Parsed => NonPositional
+          case StopValue => NonPositional
+          case Implicit => {
+            val UNB = -1
+            (
 
 Review comment:
   I know this was probably a result of your formatting tool settings, but this 
lone parens looks really weird to me.

----------------------------------------------------------------
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]


With regards,
Apache Git Services

Reply via email to