@@ -207,7 +207,7 @@ private void generateEncoder(
207207 out .append (generateEncoderFields (className , fields , indent ));
208208
209209 final StringBuilder sb = new StringBuilder ();
210- generateEncoderGroups (sb , className , groups , indent );
210+ generateEncoderGroups (sb , className , groups , indent , false );
211211 out .append (sb );
212212
213213 out .append (generateEncoderVarData (className , varData , indent ));
@@ -238,7 +238,7 @@ private void generateDecoder(
238238 out .append (generateDecoderFields (fields , indent ));
239239
240240 final StringBuilder sb = new StringBuilder ();
241- generateDecoderGroups (sb , className , groups , indent );
241+ generateDecoderGroups (sb , className , groups , indent , false );
242242 out .append (sb );
243243
244244 out .append (generateDecoderVarData (varData , indent ));
@@ -253,7 +253,8 @@ private void generateDecoderGroups(
253253 final StringBuilder sb ,
254254 final String outerClassName ,
255255 final List <Token > tokens ,
256- final String indent ) throws IOException
256+ final String indent ,
257+ final boolean isSubGroup ) throws IOException
257258 {
258259 for (int i = 0 , size = tokens .size (); i < size ; i ++)
259260 {
@@ -263,26 +264,28 @@ private void generateDecoderGroups(
263264 throw new IllegalStateException ("tokens must begin with BEGIN_GROUP: token=" + groupToken );
264265 }
265266
267+ final int groupIndex = i ;
266268 final String groupName = decoderName (formatClassName (groupToken .name ()));
267- sb .append (generateGroupDecoderProperty (groupName , groupToken , indent ));
268-
269- generateAnnotations (indent + INDENT , groupName , tokens , sb , i + 1 , this ::decoderName );
270- generateGroupDecoderClassHeader (sb , groupName , outerClassName , tokens , i , indent + INDENT );
271269
272270 ++i ;
273271 final int groupHeaderTokenCount = tokens .get (i ).componentTokenCount ();
274272 i += groupHeaderTokenCount ;
275273
276274 final List <Token > fields = new ArrayList <>();
277275 i = collectFields (tokens , i , fields );
278- sb .append (generateDecoderFields (fields , indent + INDENT ));
279276
280277 final List <Token > groups = new ArrayList <>();
281278 i = collectGroups (tokens , i , groups );
282- generateDecoderGroups (sb , outerClassName , groups , indent + INDENT );
283279
284280 final List <Token > varData = new ArrayList <>();
285281 i = collectVarData (tokens , i , varData );
282+
283+ sb .append (generateGroupDecoderProperty (groupName , groupToken , indent , isSubGroup ));
284+ generateAnnotations (indent + INDENT , groupName , tokens , sb , groupIndex + 1 , this ::decoderName );
285+ generateGroupDecoderClassHeader (sb , groupName , outerClassName , tokens , groups , groupIndex , indent + INDENT );
286+
287+ sb .append (generateDecoderFields (fields , indent + INDENT ));
288+ generateDecoderGroups (sb , outerClassName , groups , indent + INDENT , true );
286289 sb .append (generateDecoderVarData (varData , indent + INDENT ));
287290
288291 appendGroupInstanceDecoderDisplay (sb , fields , groups , varData , indent + INDENT );
@@ -295,7 +298,8 @@ private void generateEncoderGroups(
295298 final StringBuilder sb ,
296299 final String outerClassName ,
297300 final List <Token > tokens ,
298- final String indent ) throws IOException
301+ final String indent ,
302+ final boolean isSubGroup ) throws IOException
299303 {
300304 for (int i = 0 , size = tokens .size (); i < size ; i ++)
301305 {
@@ -305,27 +309,29 @@ private void generateEncoderGroups(
305309 throw new IllegalStateException ("tokens must begin with BEGIN_GROUP: token=" + groupToken );
306310 }
307311
312+ final int groupIndex = i ;
308313 final String groupName = groupToken .name ();
309314 final String groupClassName = formatClassName (encoderName (groupName ));
310- sb .append (generateGroupEncoderProperty (groupName , groupToken , indent ));
311-
312- generateAnnotations (indent + INDENT , groupClassName , tokens , sb , i + 1 , this ::encoderName );
313- generateGroupEncoderClassHeader (sb , groupName , outerClassName , tokens , i , indent + INDENT );
314315
315316 ++i ;
316317 final int groupHeaderTokenCount = tokens .get (i ).componentTokenCount ();
317318 i += groupHeaderTokenCount ;
318319
319320 final List <Token > fields = new ArrayList <>();
320321 i = collectFields (tokens , i , fields );
321- sb .append (generateEncoderFields (groupClassName , fields , indent + INDENT ));
322322
323323 final List <Token > groups = new ArrayList <>();
324324 i = collectGroups (tokens , i , groups );
325- generateEncoderGroups (sb , outerClassName , groups , indent + INDENT );
326325
327326 final List <Token > varData = new ArrayList <>();
328327 i = collectVarData (tokens , i , varData );
328+
329+ sb .append (generateGroupEncoderProperty (groupName , groupToken , indent , isSubGroup ));
330+ generateAnnotations (indent + INDENT , groupClassName , tokens , sb , groupIndex + 1 , this ::encoderName );
331+ generateGroupEncoderClassHeader (sb , groupName , outerClassName , tokens , groups , groupIndex , indent + INDENT );
332+
333+ sb .append (generateEncoderFields (groupClassName , fields , indent + INDENT ));
334+ generateEncoderGroups (sb , outerClassName , groups , indent + INDENT , true );
329335 sb .append (generateEncoderVarData (groupClassName , varData , indent + INDENT ));
330336
331337 sb .append (indent ).append (" }\n " );
@@ -337,6 +343,7 @@ private void generateGroupDecoderClassHeader(
337343 final String groupName ,
338344 final String parentMessageClassName ,
339345 final List <Token > tokens ,
346+ final List <Token > subGroupTokens ,
340347 final int index ,
341348 final String indent )
342349 {
@@ -345,13 +352,18 @@ private void generateGroupDecoderClassHeader(
345352 final int dimensionHeaderLen = tokens .get (index + 1 ).encodedLength ();
346353
347354 generateGroupDecoderClassDeclaration (
348- sb , groupToken , groupName , parentMessageClassName , indent , dimensionsClassName , dimensionHeaderLen );
355+ sb ,
356+ groupToken ,
357+ groupName ,
358+ parentMessageClassName ,
359+ findSubGroupNames (subGroupTokens ),
360+ indent ,
361+ dimensionsClassName ,
362+ dimensionHeaderLen );
349363
350364 sb .append (String .format (
351- indent + " public void wrap(\n " +
352- indent + " final %s parentMessage, final %s buffer)\n " +
365+ indent + " public void wrap(final %s buffer)\n " +
353366 indent + " {\n " +
354- indent + " this.parentMessage = parentMessage;\n " +
355367 indent + " if (buffer != this.buffer)\n " +
356368 indent + " {\n " +
357369 indent + " this.buffer = buffer;\n " +
@@ -362,7 +374,6 @@ private void generateGroupDecoderClassHeader(
362374 indent + " index = -1;\n " +
363375 indent + " parentMessage.limit(parentMessage.limit() + HEADER_SIZE);\n " +
364376 indent + " }\n \n " ,
365- parentMessageClassName ,
366377 readOnlyBuffer ));
367378
368379 final int blockLength = tokens .get (index ).encodedLength ();
@@ -422,6 +433,7 @@ private void generateGroupEncoderClassHeader(
422433 final String groupName ,
423434 final String parentMessageClassName ,
424435 final List <Token > tokens ,
436+ final List <Token > subGroupTokens ,
425437 final int index ,
426438 final String ind )
427439 {
@@ -430,7 +442,14 @@ private void generateGroupEncoderClassHeader(
430442 final int dimensionHeaderSize = tokens .get (index + 1 ).encodedLength ();
431443
432444 generateGroupEncoderClassDeclaration (
433- sb , groupToken , groupName , parentMessageClassName , ind , dimensionsClassName , dimensionHeaderSize );
445+ sb ,
446+ groupToken ,
447+ groupName ,
448+ parentMessageClassName ,
449+ findSubGroupNames (subGroupTokens ),
450+ ind ,
451+ dimensionsClassName ,
452+ dimensionHeaderSize );
434453
435454 final int blockLength = tokens .get (index ).encodedLength ();
436455 final Token blockLengthToken = Generators .findFirst ("blockLength" , tokens , index );
@@ -439,18 +458,16 @@ private void generateGroupEncoderClassHeader(
439458 final String javaTypeForNumInGroup = primitiveTypeName (numInGroupToken );
440459
441460 sb .append (String .format (
442- ind + " public void wrap(\n " +
443- ind + " final %1$s parentMessage, final %2$s buffer, final int count)\n " +
461+ ind + " public void wrap(final %2$s buffer, final int count)\n " +
444462 ind + " {\n " +
445463 ind + " if (count < %3$d || count > %4$d)\n " +
446464 ind + " {\n " +
447465 ind + " throw new IllegalArgumentException(\" count outside allowed range: count=\" + count);\n " +
448466 ind + " }\n \n " +
449- ind + " this.parentMessage = parentMessage;\n " +
450467 ind + " if (buffer != this.buffer)\n " +
451468 ind + " {\n " +
452469 ind + " this.buffer = buffer;\n " +
453- ind + " }\n " +
470+ ind + " }\n \n " +
454471 ind + " dimensions.wrap(buffer, parentMessage.limit());\n " +
455472 ind + " dimensions.blockLength((%5$s)%6$d);\n " +
456473 ind + " dimensions.numInGroup((%7$s)count);\n " +
@@ -503,10 +520,13 @@ private void generateGroupDecoderClassDeclaration(
503520 final Token groupToken ,
504521 final String groupName ,
505522 final String parentMessageClassName ,
523+ final List <String > subGroupNames ,
506524 final String indent ,
507525 final String dimensionsClassName ,
508526 final int dimensionHeaderSize )
509527 {
528+ final String className = formatClassName (groupName );
529+
510530 sb .append (String .format ("\n " +
511531 "%1$s" +
512532 indent + "public static class %2$s\n " +
@@ -519,57 +539,111 @@ private void generateGroupDecoderClassDeclaration(
519539 indent + " private int count;\n " +
520540 indent + " private int index;\n " +
521541 indent + " private int offset;\n " +
522- indent + " private int blockLength;\n \n " ,
542+ indent + " private int blockLength;\n " ,
523543 generateTypeJavadoc (indent , groupToken ),
524- formatClassName ( groupName ) ,
544+ className ,
525545 dimensionHeaderSize ,
526546 decoderName (dimensionsClassName ),
527547 parentMessageClassName ,
528548 readOnlyBuffer ));
549+
550+ for (final String subGroupName : subGroupNames )
551+ {
552+ final String type = formatClassName (decoderName (subGroupName ));
553+ final String field = formatPropertyName (subGroupName );
554+ sb .append (indent ).append (" private final " ).append (type ).append (" " ).append (field ).append (";\n " );
555+ }
556+
557+ sb
558+ .append ("\n " )
559+ .append (indent ).append (" " )
560+ .append (className ).append ("(final " ).append (parentMessageClassName ).append (" parentMessage)\n " )
561+ .append (indent ).append (" {\n " )
562+ .append (indent ).append (" this.parentMessage = parentMessage;\n " );
563+
564+ for (final String subGroupName : subGroupNames )
565+ {
566+ final String type = formatClassName (decoderName (subGroupName ));
567+ final String field = formatPropertyName (subGroupName );
568+ sb
569+ .append (indent ).append (" " )
570+ .append (field ).append (" = new " ).append (type ).append ("(parentMessage);\n " );
571+ }
572+
573+ sb .append (indent ).append (" }\n \n " );
529574 }
530575
531576 private void generateGroupEncoderClassDeclaration (
532577 final StringBuilder sb ,
533578 final Token groupToken ,
534579 final String groupName ,
535580 final String parentMessageClassName ,
581+ final List <String > subGroupNames ,
536582 final String indent ,
537583 final String dimensionsClassName ,
538584 final int dimensionHeaderSize )
539585 {
586+ final String className = formatClassName (encoderName (groupName ));
587+
540588 sb .append (String .format ("\n " +
541589 "%1$s" +
542590 indent + "public static class %2$s\n " +
543591 indent + "{\n " +
544592 indent + " public static final int HEADER_SIZE = %3$d;\n " +
545593 indent + " private final %4$s dimensions = new %4$s();\n " +
546- indent + " private %5$s parentMessage;\n " +
594+ indent + " private final %5$s parentMessage;\n " +
547595 indent + " private %6$s buffer;\n " +
548596 indent + " private int count;\n " +
549597 indent + " private int index;\n " +
550- indent + " private int offset;\n \n " ,
598+ indent + " private int offset;\n " ,
551599 generateTypeJavadoc (indent , groupToken ),
552- formatClassName ( encoderName ( groupName )) ,
600+ className ,
553601 dimensionHeaderSize ,
554602 dimensionsClassName ,
555603 parentMessageClassName ,
556604 mutableBuffer ));
605+
606+ for (final String subGroupName : subGroupNames )
607+ {
608+ final String type = formatClassName (encoderName (subGroupName ));
609+ final String field = formatPropertyName (subGroupName );
610+ sb .append (indent ).append (" private final " ).append (type ).append (" " ).append (field ).append (";\n " );
611+ }
612+
613+ sb
614+ .append ("\n " )
615+ .append (indent ).append (" " )
616+ .append (className ).append ("(final " ).append (parentMessageClassName ).append (" parentMessage)\n " )
617+ .append (indent ).append (" {\n " )
618+ .append (indent ).append (" this.parentMessage = parentMessage;\n " );
619+
620+ for (final String subGroupName : subGroupNames )
621+ {
622+ final String type = formatClassName (encoderName (subGroupName ));
623+ final String field = formatPropertyName (subGroupName );
624+ sb
625+ .append (indent ).append (" " )
626+ .append (field ).append (" = new " ).append (type ).append ("(parentMessage);\n " );
627+ }
628+
629+ sb .append (indent ).append (" }\n \n " );
557630 }
558631
559632 private static CharSequence generateGroupDecoderProperty (
560- final String groupName , final Token token , final String indent )
633+ final String groupName , final Token token , final String indent , final boolean isSubGroup )
561634 {
562635 final StringBuilder sb = new StringBuilder ();
563636 final String className = formatClassName (groupName );
564637 final String propertyName = formatPropertyName (token .name ());
565638
566- sb .append (String .format ("\n " +
567- "%s" +
568- indent + " private final %s %s = new %s();\n " ,
569- generateFlyweightPropertyJavadoc (indent + INDENT , token , className ),
570- className ,
571- propertyName ,
572- className ));
639+ if (!isSubGroup )
640+ {
641+ sb .append (String .format ("\n " +
642+ indent + " private final %s %s = new %s(this);\n " ,
643+ className ,
644+ propertyName ,
645+ className ));
646+ }
573647
574648 sb .append (String .format ("\n " +
575649 indent + " public static long %sId()\n " +
@@ -597,30 +671,36 @@ private static CharSequence generateGroupDecoderProperty(
597671 indent + " }\n \n " ;
598672
599673 sb .append (String .format ("\n " +
600- indent + " public %1$s %2$s()\n " +
674+ "%1$s" +
675+ indent + " public %2$s %3$s()\n " +
601676 indent + " {\n " +
602- "%3 $s" +
603- indent + " %2 $s.wrap(parentMessage, buffer);\n " +
604- indent + " return %2 $s;\n " +
677+ "%4 $s" +
678+ indent + " %3 $s.wrap(buffer);\n " +
679+ indent + " return %3 $s;\n " +
605680 indent + " }\n " ,
681+ generateFlyweightPropertyJavadoc (indent + INDENT , token , className ),
606682 className ,
607683 propertyName ,
608684 actingVersionGuard ));
609685
610686 return sb ;
611687 }
612688
613- private CharSequence generateGroupEncoderProperty (final String groupName , final Token token , final String indent )
689+ private CharSequence generateGroupEncoderProperty (
690+ final String groupName , final Token token , final String indent , final boolean isSubGroup )
614691 {
615692 final StringBuilder sb = new StringBuilder ();
616693 final String className = formatClassName (encoderName (groupName ));
617694 final String propertyName = formatPropertyName (groupName );
618695
619- sb .append (String .format ("\n " +
620- indent + " private final %s %s = new %s();\n " ,
621- className ,
622- propertyName ,
623- className ));
696+ if (!isSubGroup )
697+ {
698+ sb .append (String .format ("\n " +
699+ indent + " private final %s %s = new %s(this);\n " ,
700+ className ,
701+ propertyName ,
702+ className ));
703+ }
624704
625705 sb .append (String .format ("\n " +
626706 indent + " public static long %sId()\n " +
@@ -634,7 +714,7 @@ private CharSequence generateGroupEncoderProperty(final String groupName, final
634714 "%1$s" +
635715 indent + " public %2$s %3$sCount(final int count)\n " +
636716 indent + " {\n " +
637- indent + " %3$s.wrap(parentMessage, buffer, count);\n " +
717+ indent + " %3$s.wrap(buffer, count);\n " +
638718 indent + " return %3$s;\n " +
639719 indent + " }\n " ,
640720 generateGroupEncodePropertyJavadoc (indent + INDENT , token , className ),
0 commit comments