stevedlawrence commented on code in PR #901:
URL: https://github.com/apache/daffodil/pull/901#discussion_r1067276335


##########
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/generators/CodeGeneratorState.scala:
##########
@@ -404,76 +542,117 @@ class CodeGeneratorState(private val root: ElementBase) {
     finalStructs += struct
   }
 
-  def addSimpleTypeStatements(initERDStatement: String, initSelfStatement: 
String, parseStatement: String, unparseStatement: String): Unit = {
-    if (initERDStatement.nonEmpty) structs.top.initERDStatements += 
initERDStatement
-    if (initSelfStatement.nonEmpty) structs.top.initSelfStatements += 
initSelfStatement
+  // Add C code to initialize, parse, and unparse a primitive value element
+  def addSimpleTypeStatements(initERDStatement: String, parseStatement: 
String, unparseStatement: String): Unit = {
+    if (initERDStatement.nonEmpty) {
+      if (hasChoice)
+        structs.top.initChoiceStatements += initERDStatement
+      else
+        structs.top.initERDStatements += initERDStatement
+    }
     if (parseStatement.nonEmpty) structs.top.parserStatements += parseStatement
     if (unparseStatement.nonEmpty) structs.top.unparserStatements += 
unparseStatement
   }
 
-  def addComplexTypeStatements(child: ElementBase): Unit = {
+  // Generate C code to initialize, parse, and unparse a child element
+  def addPerChildStatements(child: ElementBase): Unit = {
     val C = cStructName(child)
-    val e = child.name
-    val hasChoice = structs.top.initChoiceStatements.nonEmpty
-    val arraySize = if (child.occursCountKind == OccursCountKind.Fixed) 
child.maxOccurs else 0
+    val e = child.namedQName.local
 
+    // Generate a choice statement case if the child is in a choice element
+    val hasChoice = structs.top.initChoiceStatements.nonEmpty
     if (hasChoice) {
+      val position = child.position
       structs.top.initChoiceStatements ++= 
ChoiceBranchKeyCooker.convertConstant(
         child.choiceBranchKey, child, forUnparse = false).map { key => s"    
case $key:"}
-
-      val offset = child.position - 1
-      val initChoiceStatement = s"        instance->_choice = $offset;"
-      val parseStatement = s"    case $offset:"
-      val unparseStatement = s"    case $offset:"
-
-      structs.top.initChoiceStatements += initChoiceStatement
-      structs.top.parserStatements += parseStatement
-      structs.top.unparserStatements += unparseStatement
+      structs.top.initChoiceStatements += s"        instance->_choice = 
$position;"
+      structs.top.parserStatements += s"    case $position:"
+      structs.top.unparserStatements += s"    case $position:"
     }
+    val indent1 = if (hasChoice) "    " else ""
 
-    def addStatements(deref: String): Unit = {
-      val initChoiceStatement = s"        ${C}_initERD(&instance->$e$deref);"
-      val initERDStatement = s"    ${C}_initERD(&instance->$e$deref);"
-      val initSelfStatement = s"    ${C}_initSelf(&instance->$e$deref);"
-      val moreIndent = if (hasChoice) "    " else ""
-      val parseStatement =
-        s"""$moreIndent    ${C}_parseSelf(&instance->$e$deref, pstate);
-           |$moreIndent    if (pstate->error) return;""".stripMargin
-      val unparseStatement =
-        s"""$moreIndent    ${C}_unparseSelf(&instance->$e$deref, ustate);
-           |$moreIndent    if (ustate->error) return;""".stripMargin
+    // Add an array if the child occurs multiple times
+    val hasArray = arrayMaxOccurs(child) > 0
+    val deref = if (hasArray) "[i]" else ""
+    val indent2 = if (hasArray) "    " else ""
+    if (hasArray) pushArray(child)
 
+    // Generate statements to initialize, parse, and unparse the child
+    Runtime2CodeGenerator.generateCode(child.enclosedElement, this)
+    if (!child.isSimpleType) {
       if (hasChoice)
-        structs.top.initChoiceStatements += initChoiceStatement
+        structs.top.initChoiceStatements += s"$indent2        
${C}_initERD(&instance->$e$deref, (InfosetBase *)instance);"
       else
-        structs.top.initERDStatements += initERDStatement
-      structs.top.initSelfStatements += initSelfStatement
-      structs.top.parserStatements += parseStatement
-      structs.top.unparserStatements += unparseStatement
+        structs.top.initERDStatements += s"$indent2    
${C}_initERD(&instance->$e$deref, (InfosetBase *)instance);"
+      structs.top.parserStatements +=
+        s"""$indent1$indent2    ${C}_parseSelf(&instance->$e$deref, pstate);
+           |$indent1$indent2    if (pstate->error) return;""".stripMargin
+      structs.top.unparserStatements +=
+        s"""$indent1$indent2    ${C}_unparseSelf(&instance->$e$deref, ustate);
+           |$indent1$indent2    if (ustate->error) return;""".stripMargin
     }
-    if (arraySize > 0)
-      for (i <- 0 until arraySize)
-        addStatements(s"[$i]")
-    else
-      addStatements("")
 
-    if (hasChoice) {
-      val initChoiceStatement = s"        break;"
-      val parseStatement = s"        break;"
-      val unparseStatement = s"        break;"
+    // Generate statements to align the next element
+    val mustAlign = child.endingAlignmentApprox.nBits > 
child.priorAlignmentApprox.nBits

Review Comment:
   > there still was a need for extra alignment between two elements aligned to 
8 bits
   because the schema writer had used an empty sequence aligned to 32
   bits following a hexBinary element to artificially pad the hexBinary
   element's length to a multiple of 32 bits, and furthermore, the schema
   compiler had optimized away that empty sequence so the only place that
   extra 32-bit alignment could be found was in the hexBinary element's
   endingAlignmentApprox.nBits (32) which was bigger than its
   priorAlignmentApprox.nBits (8) and its alignmentValueInBits (8).
   
   I'm not sure why DFDL would have optimized out the sequence if there's 
required alignment. That sounds like it might be a bug in the compiler if 
that's the case.
   
   It feels like runtime2 should be inserting framing code for sequences that 
are not known to be aligned, in addition to elements. Would it work to add the 
same `isKnownToBeAligned` and `parse_align` logic in 
`orderedSequeneGenrateConfig` or wherever runtime2 walks into sequences?



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

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to