stevedlawrence commented on a change in pull request #207: Added support for 
enumerations and TypeValueCalc
URL: https://github.com/apache/incubator-daffodil/pull/207#discussion_r279777466
 
 

 ##########
 File path: 
daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementKindParsers.scala
 ##########
 @@ -114,42 +116,138 @@ class DynamicEscapeSchemeParser(
   }
 }
 
-class ChoiceDispatchCombinatorParser(rd: TermRuntimeData, dispatchKeyEv: 
ChoiceDispatchKeyEv, dispatchBranchKeyMap: Map[String, Parser])
+/*
+ * dispatchBranchKeyMap: choiceBranchKey -> (Parser, hasRepresentation)
+ */
+
+abstract class ChoiceDispatchCombinatorParserBase(rd: TermRuntimeData, 
+                                                  dispatchBranchKeyMap: 
Map[String, (Parser, Boolean)], 
+                                                  
dispatchKeyRangeMap:Vector[(RangeBound[BigInt],RangeBound[BigInt],Parser, 
Boolean)])
   extends CombinatorParser(rd) {
   override def nom = "ChoiceDispatch"
 
   override lazy val runtimeDependencies = Vector()
 
-  override lazy val childProcessors = dispatchBranchKeyMap.values.toVector
+  override lazy val childProcessors = 
dispatchBranchKeyMap.values.map(_._1).toVector ++ dispatchKeyRangeMap.map(_._3)
+
+  /*
+   * Returns a value if pstate.processorStatus eq Success
+   */
+  def computeDispatchKey(pstate: PState): Maybe[String]
+
+  /*
+   * having choiceDispatchKeyKind=byType introduces some subtle problems.
+   * In the basic case a naive implementation would try to parse the repType 
twice:
+   *  once to determine the dispatchKey, and once because the resulting branch 
would have the same repType
+   * However, it is also possible that the branch would have an 
inputValueCalc, in which case we would
+   *  only parse the repType when computing the dispatchKey.
+   * The difficulty is that, in both the above cases, the *correct* behavior 
is to parse the reptype exactly once
+   *
+   * Ideally, we would actually parse repType once, and pass the result into 
the branch's parser
+   * However, in practice, this would involve a significant amount of 
reworking of Daffodil parsing subsystem.
+   *
+   * Instead, we simulate parseing once by saving and restoring state as 
follows:
+   *
+   * initialState = pstate.mark()
+   * dispatchKey <- repType.parse()
+   * if(branch.isRepresented){
+   *   pstate.restore(initialState)
+   * }else{
+   *   pstate.discard(initialState)
+   * }
+   * branch.parse()
+   *
+   *
+   */
 
   def parse(pstate: PState): Unit = {
-    val key = dispatchKeyEv.evaluate(pstate)
+    val initialState = pstate.mark("ChoiceDispatchCombinatorParserBase.parse")
+    var freedInitialState = false
+    try {
+      val maybeKey = computeDispatchKey(pstate)
 
-    val parserOpt = dispatchBranchKeyMap.get(key)
-    if (parserOpt.isEmpty) {
-      val diag = new ChoiceDispatchNoMatch(context.schemaFileLocation, pstate, 
key)
-      pstate.setFailed(diag)
-    } else {
-      val parser = parserOpt.get
+      if (pstate.processorStatus eq Success) {
+        val key = maybeKey.get
+
+        val parserOpt1 = dispatchBranchKeyMap.get(key)
+        val parserOpt2 = 
+          if(parserOpt1.isDefined) {
+            parserOpt1
+          } else{
+            if(!dispatchKeyRangeMap.isEmpty){
+              val keyAsBigInt = BigInt(key)
+              val optAns1= dispatchKeyRangeMap.filter({case(min,max,_,_) => 
min.testAsLower(keyAsBigInt) && max.testAsUpper(keyAsBigInt)}).headOption
 
 Review comment:
   If we're only going to get headOption, then it probably makes sense to use 
``find`` instead of ``filter``. Otherwise we have to loop through the entire 
vector instead of just stopping at the first one that matches.

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