@@ -479,7 +479,8 @@ function generateCode() {
479
479
writeLine ( `import (` ) ;
480
480
writeLine ( `\t"fmt"` ) ;
481
481
writeLine ( "" ) ;
482
- writeLine ( `\t"github.com/microsoft/typescript-go/internal/json"` ) ;
482
+ writeLine ( `\t"github.com/go-json-experiment/json"` ) ;
483
+ writeLine ( `\t"github.com/go-json-experiment/json/jsontext"` ) ;
483
484
writeLine ( `)` ) ;
484
485
writeLine ( "" ) ;
485
486
writeLine ( "// Meta model version " + model . metaData . version ) ;
@@ -519,35 +520,64 @@ function generateCode() {
519
520
generateStructFields ( structure . name , true ) ;
520
521
writeLine ( "" ) ;
521
522
522
- // Generate UnmarshalJSON method for structure validation
523
+ // Generate UnmarshalJSONFrom method for structure validation
523
524
const requiredProps = structure . properties ?. filter ( p => ! p . optional ) || [ ] ;
524
525
if ( requiredProps . length > 0 ) {
525
- writeLine ( `func (s *${ structure . name } ) UnmarshalJSON(data []byte) error {` ) ;
526
- writeLine ( `\t// Check required props` ) ;
527
- writeLine ( `\ttype requiredProps struct {` ) ;
526
+ writeLine ( `\tvar _ json.UnmarshalerFrom = (*${ structure . name } )(nil)` ) ;
527
+ writeLine ( "" ) ;
528
+
529
+ writeLine ( `func (s *${ structure . name } ) UnmarshalJSONFrom(dec *jsontext.Decoder) error {` ) ;
530
+ writeLine ( `\tvar (` ) ;
528
531
for ( const prop of requiredProps ) {
529
- writeLine ( `\t\t ${ titleCase ( prop . name ) } requiredProp \`json:" ${ prop . name } "\` ` ) ;
532
+ writeLine ( `\t\tseen ${ titleCase ( prop . name ) } bool ` ) ;
530
533
}
531
- writeLine ( `} ` ) ;
534
+ writeLine ( `\t) ` ) ;
532
535
writeLine ( "" ) ;
533
536
534
- writeLine ( `\tvar keys requiredProps` ) ;
535
- writeLine ( `\tif err := json.Unmarshal(data, &keys); err != nil {` ) ;
537
+ writeLine ( `\tif k := dec.PeekKind(); k != '{' {` ) ;
538
+ writeLine ( `\t\treturn fmt.Errorf("expected object start, but encountered %v", k)` ) ;
539
+ writeLine ( `\t}` ) ;
540
+ writeLine ( `\tif _, err := dec.ReadToken(); err != nil {` ) ;
541
+ writeLine ( `\t\treturn err` ) ;
542
+ writeLine ( `\t}` ) ;
543
+ writeLine ( "" ) ;
544
+
545
+ writeLine ( `\tfor dec.PeekKind() != '}' {` ) ;
546
+ writeLine ( "name, err := dec.ReadValue()" ) ;
547
+ writeLine ( `\t\tif err != nil {` ) ;
548
+ writeLine ( `\t\t\treturn err` ) ;
549
+ writeLine ( `\t\t}` ) ;
550
+ writeLine ( `\t\tswitch string(name) {` ) ;
551
+
552
+ for ( const prop of structure . properties ) {
553
+ writeLine ( `\t\tcase \`"${ prop . name } "\`:` ) ;
554
+ if ( ! prop . optional ) {
555
+ writeLine ( `\t\t\tseen${ titleCase ( prop . name ) } = true` ) ;
556
+ }
557
+ writeLine ( `\t\t\tif err := json.UnmarshalDecode(dec, &s.${ titleCase ( prop . name ) } ); err != nil {` ) ;
558
+ writeLine ( `\t\t\t\treturn err` ) ;
559
+ writeLine ( `\t\t\t}` ) ;
560
+ }
561
+
562
+ writeLine ( `\t\tdefault:` ) ;
563
+ writeLine ( `\t\t// Ignore unknown properties.` ) ;
564
+ writeLine ( `\t\t}` ) ;
565
+ writeLine ( `\t}` ) ;
566
+ writeLine ( "" ) ;
567
+
568
+ writeLine ( `\tif _, err := dec.ReadToken(); err != nil {` ) ;
536
569
writeLine ( `\t\treturn err` ) ;
537
570
writeLine ( `\t}` ) ;
538
571
writeLine ( "" ) ;
539
572
540
- // writeLine(`\t// Check for missing required keys`);
541
573
for ( const prop of requiredProps ) {
542
- writeLine ( `if !keys. ${ titleCase ( prop . name ) } {` ) ;
543
- writeLine ( `\t\treturn fmt.Errorf("required key '${ prop . name } ' is missing")` ) ;
544
- writeLine ( `}` ) ;
574
+ writeLine ( `\tif !seen ${ titleCase ( prop . name ) } {` ) ;
575
+ writeLine ( `\t\treturn fmt.Errorf("required property '${ prop . name } ' is missing")` ) ;
576
+ writeLine ( `\t }` ) ;
545
577
}
546
578
547
- writeLine ( `` ) ;
548
- writeLine ( `\t// Redeclare the struct to prevent infinite recursion` ) ;
549
- generateStructFields ( "temp" , false ) ;
550
- writeLine ( `\treturn json.Unmarshal(data, (*temp)(s))` ) ;
579
+ writeLine ( "" ) ;
580
+ writeLine ( `\treturn nil` ) ;
551
581
writeLine ( `}` ) ;
552
582
writeLine ( "" ) ;
553
583
}
@@ -606,17 +636,6 @@ function generateCode() {
606
636
607
637
writeLine ( ")" ) ;
608
638
writeLine ( "" ) ;
609
-
610
- // Add custom JSON unmarshaling
611
- writeLine ( `func (e *${ enumeration . name } ) UnmarshalJSON(data []byte) error {` ) ;
612
- writeLine ( `\tvar v ${ baseType } ` ) ;
613
- writeLine ( `\tif err := json.Unmarshal(data, &v); err != nil {` ) ;
614
- writeLine ( `\t\treturn err` ) ;
615
- writeLine ( `\t}` ) ;
616
- writeLine ( `\t*e = ${ enumeration . name } (v)` ) ;
617
- writeLine ( `\treturn nil` ) ;
618
- writeLine ( `}` ) ;
619
- writeLine ( "" ) ;
620
639
}
621
640
622
641
const requestsAndNotifications : ( Request | Notification ) [ ] = [ ...model . requests , ...model . notifications ] ;
@@ -736,14 +755,21 @@ function generateCode() {
736
755
const fieldEntries = Array . from ( uniqueTypeFields . entries ( ) ) . map ( ( [ typeName , fieldName ] ) => ( { fieldName, typeName } ) ) ;
737
756
738
757
// Marshal method
739
- writeLine ( `func (o ${ name } ) MarshalJSON() ([]byte, error) {` ) ;
758
+ writeLine ( `var _ json.MarshalerTo = (*${ name } )(nil)` ) ;
759
+ writeLine ( "" ) ;
760
+
761
+ writeLine ( `func (o *${ name } ) MarshalJSONTo(enc *jsontext.Encoder) error {` ) ;
740
762
741
763
// Determine if this union contained null (check if any member has containedNull = true)
742
764
const unionContainedNull = members . some ( member => member . containedNull ) ;
743
- const assertionFunc = unionContainedNull ? "assertAtMostOne" : "assertOnlyOne" ;
765
+ if ( unionContainedNull ) {
766
+ write ( `\tassertAtMostOne("more than one element of ${ name } is set", ` ) ;
767
+ }
768
+ else {
769
+ write ( `\tassertOnlyOne("exactly one element of ${ name } should be set", ` ) ;
770
+ }
744
771
745
772
// Create assertion to ensure at most one field is set at a time
746
- write ( `\t${ assertionFunc } ("more than one element of ${ name } is set", ` ) ;
747
773
748
774
// Write the assertion conditions
749
775
for ( let i = 0 ; i < fieldEntries . length ; i ++ ) {
@@ -755,14 +781,13 @@ function generateCode() {
755
781
756
782
for ( const entry of fieldEntries ) {
757
783
writeLine ( `\tif o.${ entry . fieldName } != nil {` ) ;
758
- writeLine ( `\t\treturn json.Marshal(* o.${ entry . fieldName } )` ) ;
784
+ writeLine ( `\t\treturn json.MarshalEncode(enc, o.${ entry . fieldName } )` ) ;
759
785
writeLine ( `\t}` ) ;
760
786
}
761
787
762
788
// If all fields are nil, marshal as null (only for unions that can contain null)
763
789
if ( unionContainedNull ) {
764
- writeLine ( `\t// All fields are nil, represent as null` ) ;
765
- writeLine ( `\treturn []byte("null"), nil` ) ;
790
+ writeLine ( `\treturn enc.WriteToken(jsontext.Null)` ) ;
766
791
}
767
792
else {
768
793
writeLine ( `\tpanic("unreachable")` ) ;
@@ -771,13 +796,19 @@ function generateCode() {
771
796
writeLine ( "" ) ;
772
797
773
798
// Unmarshal method
774
- writeLine ( `func (o *${ name } ) UnmarshalJSON(data []byte) error {` ) ;
799
+ writeLine ( `var _ json.UnmarshalerFrom = (*${ name } )(nil)` ) ;
800
+ writeLine ( "" ) ;
801
+
802
+ writeLine ( `func (o *${ name } ) UnmarshalJSONFrom(dec *jsontext.Decoder) error {` ) ;
775
803
writeLine ( `\t*o = ${ name } {}` ) ;
776
804
writeLine ( "" ) ;
777
805
778
- // Handle null case only for unions that can contain null
806
+ writeLine ( "\tdata, err := dec.ReadValue()" ) ;
807
+ writeLine ( "\tif err != nil {" ) ;
808
+ writeLine ( "\t\treturn err" ) ;
809
+ writeLine ( "\t}" ) ;
810
+
779
811
if ( unionContainedNull ) {
780
- writeLine ( `\t// Handle null case` ) ;
781
812
writeLine ( `\tif string(data) == "null" {` ) ;
782
813
writeLine ( `\t\treturn nil` ) ;
783
814
writeLine ( `\t}` ) ;
@@ -808,14 +839,24 @@ function generateCode() {
808
839
writeLine ( `type ${ name } struct{}` ) ;
809
840
writeLine ( "" ) ;
810
841
811
- writeLine ( `func (o ${ name } ) MarshalJSON() ([]byte, error) {` ) ;
812
- writeLine ( `\treturn []byte(\`${ jsonValue } \`), nil` ) ;
842
+ writeLine ( `var _ json.MarshalerTo = ${ name } {}` ) ;
843
+ writeLine ( "" ) ;
844
+
845
+ writeLine ( `func (o ${ name } ) MarshalJSONTo(enc *jsontext.Encoder) error {` ) ;
846
+ writeLine ( `\treturn enc.WriteValue(jsontext.Value(\`${ jsonValue } \`))` ) ;
813
847
writeLine ( `}` ) ;
814
848
writeLine ( "" ) ;
815
849
816
- writeLine ( `func (o *${ name } ) UnmarshalJSON(data []byte) error {` ) ;
817
- writeLine ( `\tif string(data) != \`${ jsonValue } \` {` ) ;
818
- writeLine ( `\t\treturn fmt.Errorf("invalid ${ name } : %s", data)` ) ;
850
+ writeLine ( `var _ json.UnmarshalerFrom = &${ name } {}` ) ;
851
+ writeLine ( "" ) ;
852
+
853
+ writeLine ( `func (o *${ name } ) UnmarshalJSONFrom(dec *jsontext.Decoder) error {` ) ;
854
+ writeLine ( `\tv, err := dec.ReadValue();` ) ;
855
+ writeLine ( `\tif err != nil {` ) ;
856
+ writeLine ( `\t\treturn err` ) ;
857
+ writeLine ( `\t}` ) ;
858
+ writeLine ( `\tif string(v) != \`${ jsonValue } \` {` ) ;
859
+ writeLine ( `\t\treturn fmt.Errorf("expected ${ name } value %s, got %s", \`${ jsonValue } \`, v)` ) ;
819
860
writeLine ( `\t}` ) ;
820
861
writeLine ( `\treturn nil` ) ;
821
862
writeLine ( `}` ) ;
0 commit comments