@@ -422,16 +422,23 @@ private void generateDecodePrimitive(
422
422
private void generateRangeCheckPrimitive (
423
423
final StringBuilder sb ,
424
424
final String varName ,
425
- final Token token )
425
+ final Token token ,
426
+ final Boolean isOptional )
426
427
{
428
+ // Note that constant encoding is a property of the type
429
+ // and so works on signal/encoding tokens but optionality is
430
+ // a property of the field and so is not set on the encoding token.
431
+ // For this reason we can use the token to check for constancy
432
+ // but pass in optionality as a parameter
433
+
427
434
// Constant values don't need checking
428
435
if (token .isConstantEncoding ())
429
436
{
430
437
return ;
431
438
}
432
439
433
440
// If this field is unknown then we have nothing to check
434
- // Otherwise do a The Min,MaxValue checks (possibly for arrays)
441
+ // Otherwise do the Min,MaxValue checks (possibly for arrays)
435
442
this .imports .add ("fmt" );
436
443
if (token .arrayLength () > 1 )
437
444
{
@@ -449,9 +456,22 @@ private void generateRangeCheckPrimitive(
449
456
}
450
457
else
451
458
{
459
+ // Optional fields can be NullValue which may be outside the
460
+ // range of Min->Max so we need a special case.
461
+ // Structured this way for go fmt sanity on both cases.
462
+ final String check ;
463
+ if (isOptional )
464
+ {
465
+ check = "\t \t if %1$s != %1$sNullValue() && (%1$s < %1$sMinValue() || %1$s > %1$sMaxValue()) {\n " ;
466
+ }
467
+ else
468
+ {
469
+ check = "\t \t if %1$s < %1$sMinValue() || %1$s > %1$sMaxValue() {\n " ;
470
+ }
471
+
452
472
sb .append (String .format (
453
473
"\t if %1$sInActingVersion(actingVersion) {\n " +
454
- " \t \t if %1$s < %1$sMinValue() || %1$s > %1$sMaxValue() { \n " +
474
+ check +
455
475
"\t \t \t return fmt.Errorf(\" Range check failed on %1$s " +
456
476
"(%%d < %%d > %%d)\" , %1$sMinValue(), %1$s, %1$sMaxValue())\n " +
457
477
"\t \t }\n " +
@@ -468,40 +488,56 @@ private void generateRangeCheckPrimitive(
468
488
}
469
489
}
470
490
471
- private void generateInitPrimitive (
491
+ private void generateOptionalInitPrimitive (
472
492
final StringBuilder sb ,
473
493
final String varName ,
474
494
final Token token )
475
495
{
496
+ final Encoding encoding = token .encoding ();
497
+
498
+ // Optional items get initialized to their NullValue
499
+ sb .append (String .format (
500
+ "\t %1$s = %2$s\n " ,
501
+ varName ,
502
+ generateNullValueLiteral (encoding .primitiveType (), encoding )));
503
+ }
504
+
505
+ private void generateConstantInitPrimitive (
506
+ final StringBuilder sb ,
507
+ final String varName ,
508
+ final Token token )
509
+ {
510
+ final Encoding encoding = token .encoding ();
511
+
476
512
// Decode of a constant is simply assignment
477
513
if (token .isConstantEncoding ())
478
514
{
479
515
// if primitiveType="char" this is a character array
480
- if (token . encoding () .primitiveType () == CHAR )
516
+ if (encoding .primitiveType () == CHAR )
481
517
{
482
- if (token . encoding () .constValue ().size () > 1 )
518
+ if (encoding .constValue ().size () > 1 )
483
519
{
484
520
// constValue is a string
485
521
sb .append (String .format (
486
522
"\t copy(%1$s[:], \" %2$s\" )\n " ,
487
523
varName ,
488
- token . encoding () .constValue ()));
524
+ encoding .constValue ()));
489
525
}
490
526
else
491
527
{
492
528
// constValue is a char
493
529
sb .append (String .format (
494
530
"\t %1$s[0] = %2$s\n " ,
495
531
varName ,
496
- token . encoding () .constValue ()));
532
+ encoding .constValue ()));
497
533
}
498
534
}
499
535
else
500
536
{
501
537
sb .append (String .format (
502
538
"\t %1$s = %2$s\n " ,
503
539
varName ,
504
- generateLiteral (token . encoding () .primitiveType (), token . encoding () .constValue ().toString ())));
540
+ generateLiteral (encoding .primitiveType (), encoding .constValue ().toString ())));
505
541
}
506
542
}
507
543
}
@@ -652,17 +688,28 @@ private int generateEncodeDecode(
652
688
encode .append (generateEncodeOffset (gap , "" ));
653
689
decode .append (generateDecodeOffset (gap , "" ));
654
690
currentOffset += signalToken .encodedLength () + gap ;
691
+ final String primitive = Character .toString (varName ) + "." + propertyName ;
655
692
656
- // Encode of a constant is a nullop
657
- if (!signalToken .isConstantEncoding ())
693
+ // Encode of a constant is a nullop and we want to
694
+ // initialize constant values.
695
+ if (signalToken .isConstantEncoding ())
696
+ {
697
+ generateConstantInitPrimitive (init , primitive , signalToken );
698
+ }
699
+ else
658
700
{
659
701
generateEncodePrimitive (encode , varName , formatPropertyName (signalToken .name ()), signalToken );
702
+ }
660
703
704
+ // Optional tokens also get initialized
705
+ if (signalToken .isOptionalEncoding ())
706
+ {
707
+ generateOptionalInitPrimitive (init , primitive , signalToken );
661
708
}
662
- final String primitive = Character . toString ( varName ) + "." + propertyName ;
709
+
663
710
generateDecodePrimitive (decode , primitive , signalToken );
664
- generateRangeCheckPrimitive (rangeCheck , primitive , signalToken );
665
- generateInitPrimitive ( init , primitive , signalToken );
711
+ generateRangeCheckPrimitive (rangeCheck , primitive , signalToken , signalToken . isOptionalEncoding () );
712
+
666
713
break ;
667
714
668
715
case BEGIN_GROUP :
@@ -1004,16 +1051,29 @@ private int generateFieldEncodeDecode(
1004
1051
gap = encodingToken .offset () - currentOffset ;
1005
1052
encode .append (generateEncodeOffset (gap , "" ));
1006
1053
decode .append (generateDecodeOffset (gap , "" ));
1054
+ final String primitive = Character .toString (varName ) + "." + propertyName ;
1007
1055
1008
- // Encode of a constant is a nullop
1009
- if (!encodingToken .isConstantEncoding ())
1056
+ // Encode of a constant is a nullop and we want to
1057
+ // initialize constant values.
1058
+ // (note: constancy is determined by the type's token)
1059
+ if (encodingToken .isConstantEncoding ())
1060
+ {
1061
+ generateConstantInitPrimitive (init , primitive , encodingToken );
1062
+ }
1063
+ else
1010
1064
{
1011
1065
generateEncodePrimitive (encode , varName , formatPropertyName (signalToken .name ()), encodingToken );
1012
1066
}
1013
- final String primitive = Character .toString (varName ) + "." + propertyName ;
1067
+
1068
+ // Optional tokens get initialized to NullValue
1069
+ // (note: optionality is determined by the field's token)
1070
+ if (signalToken .isOptionalEncoding ())
1071
+ {
1072
+ generateOptionalInitPrimitive (init , primitive , encodingToken );
1073
+ }
1074
+
1014
1075
generateDecodePrimitive (decode , primitive , encodingToken );
1015
- generateRangeCheckPrimitive (rc , primitive , encodingToken );
1016
- generateInitPrimitive (init , primitive , encodingToken );
1076
+ generateRangeCheckPrimitive (rc , primitive , encodingToken , signalToken .isOptionalEncoding ());
1017
1077
break ;
1018
1078
}
1019
1079
0 commit comments