tuxji commented on a change in pull request #488:
URL: https://github.com/apache/incubator-daffodil/pull/488#discussion_r575692835
##########
File path: daffodil-runtime2/src/main/resources/c/libruntime/infoset.c
##########
@@ -160,10 +160,11 @@ walkInfosetNode(const VisitEventHandler *handler, const
InfosetBase *infoNode)
handler->visitNumberElem(handler, childERD, numLocation);
break;
case CHOICE:
+ // Point next ERD to choice of alternative elements' ERDs
if (!infoNode->erd->initChoice(infoNode, rootElement()))
{
error_msg =
- "node's _choice field was not initialized during walk";
+ "Walk error: no match between choice dispatch key and any
branch key";
Review comment:
Actually, daffodil_main.c calls walkInfoset() in two places (from both
the parse and unparse use cases). You're right that when we parse a binary
data file, the parseSelf() function has already dealt with the choice
(initChoice() is just re-initializing the _choice member field at this time).
However, when we read an unparse XML file into an infoset in memory, we also
walk the uninitialized infoset before we call unparseSelf() to write the
unparsed binary data to the output file. The walk validates each new XML
element matches the schema's next infoset element and calls the correct number
conversion function (float, integer, etc.). The _choice member field is
uninitialized at this time and I didn't know I could write a choice branch
resolver which looks at the next XML element and figures out which branch does
that element indicate exists inside the choice group. I thought I would just
call initChoice() from walkInfosetNode(), it would use the choice dispatch key
to selec
t the right branch, and then walkInfosetNode() would know what the next
infoset element should be. This behavior causes c-daffodil to behave more
strictly than scala-daffodil; if the unparse XML file has no match between the
choice dispatch key and any branch key, c-daffodil reports a no match
processing error at this very place while scala-daffodil reports no error at
all:
```shell
$ emacs unparse.xml # change <tag>4</tag> to <tag>0</tag>
$ make unparse-test
./daffodil unparse unparse.xml -o test_parse.dat
./daffodil: Walk error: no match between choice dispatch key and any branch
key
make: *** [Makefile:46: unparse-test] Error 1
$ daffodil unparse -s nested.dfdl.xsd -r NestedUnion -o test_parse.dat
unparse.xml # No errors
$ diff parse.dat test_parse.dat # No errors, 4th byte is zero in both files
```
Perhaps c-daffodil should load such an XML file without a no match
processing error and unparse the infoset to a binary data file without a no
match processing error. We would have to code and call a choice branch
resolver in C which peeks at the next XML element, figures out which branch
does that element indicate exists inside the choice group, and initializes the
choice and element runtime data (_choice and childNode->erd member fields)
accordingly. We probably would replace the initChoice() call in
walkInfosetNode() with a call to that choice branch resolver and we might or
might not call initChoice() in unparseSelf(). The reason I called initChoice()
in all these places is that I thought we might want to remove the _choice
member field and just call initChoice() to tell us the correct element to visit
next in parse, walk, and unparse.
----------------------------------------------------------------
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]