`MessageCodeGenerator` fails to set group delimiter for nested components
Describe the bug
When you run QuickFIX/J's MessageCodeGenerator on the attached Test.xml QuickFIX dictionary, the generated code does not compile because the generator does not set the group delimiter for the NestedTwiceGrp.
The generated code for NoEntries inside NestedTwice.java begins as follows:
public static class NoEntries extends Group {
static final long serialVersionUID = 20050617;
private static final int[] ORDER = {58, 0};
public NoEntries() {
super(20001, , ORDER);
}
As you can see, the super call is malformed, because it does not specify anything for the delim parameter.
The same behavior cannot be observed when putting a field as the first item of a group (taken from Unnested.java):
public static class NoEntries extends Group {
static final long serialVersionUID = 20050617;
private static final int[] ORDER = {58, 0};
public NoEntries() {
super(20001, 58, ORDER);
}
Nor can the same behavior be observed when putting a component which does not itself contain another component as the first item of a group (taken from NestedOnce.java):
public static class NoEntries extends Group {
static final long serialVersionUID = 20050617;
private static final int[] ORDER = {58, 0};
public NoEntries() {
super(20001, 58, ORDER);
}
As you can see, both Unnested.java as well as NestedOnce.java set the delim parameter correctly and as expected. Only NestedTwice.java fails to do so.
To Reproduce
Run MessageCodeGenerator on the attached Test.xml. Let me know if you absolutely require a ready to run setup for this and I can provide it. I would however prefer not to spend that time at this point.
Expected behavior
NestedTwice.java should set the delim parameter correctly, just as NestedOnce.java and Unnested.java do.
system information:
- OS: Linux
- Java version Temurin-21.0.8+9
- QFJ Version 2.3.2
Additional context
I am not aware of FIX TagValue placing any restrictions on nesting components inside repeating groups. Therefore if my understanding regarding this is correct, I would consider the observed behavior a bug. If such restrictions are stated by the spec it would be great if someone could point them out.
From what I understand, QuickFIX/J uses the file MessageSubclass.xsl to generate Java source code in this case and more specifically this line to generate the super call. I am not familiar with XSL and can therefore not tell if the required recursion in order to handle cases like NestedTwice.java is possible when using XSL.
Hi @maxstreese , I am no XSLT expert either, but as far as I know apply-templates should do the "trick" with the recursion. I'll try to come up with something, otherwise I'll try to throw the AI at it. ;)
I could also not find any restriction on nesting components, but I could also not find that it is used anywhere except in one place. I recalled one place where it was used in a similar way: https://github.com/quickfix-j/quickfixj/commit/24bb494fcb4c5d5a659d945549ddb9c3ba02cdc3 (note the comment about StrmAsgnReqGrp which has no delimiter field and would generate code similar to your constructor above where the second parameter is empty).
@jetbrains-junie could you please come up with a solution to this problem?
Hey, itβs Junie by JetBrains! I started processing your request π
β The execution was successful
fix(codegen): set group delimiter for deeply nested components
The MessageSubclass.xsl was fixed to correctly set the group delimiter for nested components deeper than one level. The fix adds a template to recurse within component definitions to find the delimiter tag. This change ensures generated code such as NestedTwice.java now compiles with a valid constructor.
More information:
@maxstreese could you please check if #1089 fixes the problem?
Hi @chrjohn, I can confirm that #1089 fixes the problem. Thanks!
(I installed the mentioned branch locally and run the code-generation on the project I am working on, which includes cases like the one described in this issue. The generation ran successfully and subsequently compiling the code worked too. I additionally checked the generated sources and found that the delimiter is set correctly)
@maxstreese , thanks for testing. Could you do me a favour and check if #1097 or #1098 fixes the problem too? Copilot came up with a cleaner solution.