@@ -486,9 +486,9 @@ func (l *ParseTreeListener) ExitEnum_def(ctx *Enum_defContext) {
486486 // Error message
487487 if errmsg , ok := GetAnnotation (enumField .Annotations , "errmsg" ); ok {
488488 if errmsg .Value == nil {
489- panic (errutil .Explain (nil , `annotation "errmsg" value is nil in enum %s field %s` , e .Name , fieldName ))
489+ panic (errutil .Explain (nil , `annotation "errmsg" value is nil in field %s of enum %s` , fieldName , e .Name ))
490490 }
491- s := strings .Trim (* errmsg .Value , `"` )
491+ s := strings .TrimSpace ( strings . Trim (* errmsg .Value , `"` ) )
492492 enumField .ErrorMessage = & s
493493 }
494494
@@ -516,11 +516,10 @@ func (l *ParseTreeListener) ExitType_def(ctx *Type_defContext) {
516516 panic (errutil .Explain (nil , "type name %s is not PascalCase in line %d" , t .Name , t .Position .StartLine ))
517517 }
518518
519- // Distinguish between a full struct definition and a type alias
520- if ctx .LEFT_BRACE () == nil {
521- l .parseInstantiatedType (ctx , & t )
522- } else {
519+ if ctx .LEFT_BRACE () != nil {
523520 l .parseCompleteType (ctx , & t )
521+ } else {
522+ l .parseInstantiatedType (ctx , & t )
524523 }
525524
526525 l .Document .TypeTypes [t .Name ] = len (l .Document .Types )
@@ -536,22 +535,22 @@ func (l *ParseTreeListener) parseValueType(ctx IValue_typeContext, t *Type) Type
536535 }
537536
538537 // Built-in primitive type
539- if b := ctx .Base_type (); b != nil {
538+ if ctx .Base_type () != nil {
540539 return BaseType {
541- Name : b .GetText (),
540+ Name : ctx . Base_type () .GetText (),
542541 }
543542 }
544543
545544 // Reference to a user-defined type
546- if u := ctx .User_type (); u != nil {
547- typ := UserType {
548- Name : u .IDENTIFIER ().GetText (),
545+ if ctx .User_type () != nil {
546+ ut := UserType {
547+ Name : ctx . User_type () .IDENTIFIER ().GetText (),
549548 }
550549 // Track user-defined types
551- if t == nil || t .GenericParam == nil || typ .Name != * t .GenericParam {
552- l .Document .UserTypes [typ .Name ] = struct {}{}
550+ if t == nil || t .GenericParam == nil || ut .Name != * t .GenericParam {
551+ l .Document .UserTypes [ut .Name ] = struct {}{}
553552 }
554- return typ
553+ return ut
555554 }
556555
557556 // Container types (map / list)
@@ -560,7 +559,8 @@ func (l *ParseTreeListener) parseValueType(ctx IValue_typeContext, t *Type) Type
560559 kt := c .Map_type ().Key_type ().GetText ()
561560 vt := l .parseValueType (c .Map_type ().Value_type (), t )
562561 return MapType {Key : kt , Value : vt }
563- } else if c .List_type () != nil {
562+ }
563+ if c .List_type () != nil {
564564 vt := l .parseValueType (c .List_type ().Value_type (), t )
565565 return ListType {Item : vt }
566566 }
@@ -575,7 +575,7 @@ func (l *ParseTreeListener) parseInstantiatedType(ctx *Type_defContext, t *Type)
575575 BaseName : ctx .IDENTIFIER (1 ).GetText (),
576576 }
577577 if ! IsPascal (t .InstType .BaseName ) {
578- panic (errutil .Explain (nil , "instantiated type name %s is not PascalCase in line %d" , t .InstType .BaseName , t .Position .StartLine ))
578+ panic (errutil .Explain (nil , "type name %s is not PascalCase in line %d" , t .InstType .BaseName , t .Position .StartLine ))
579579 }
580580
581581 t .InstType .GenericType = l .parseValueType (ctx .Value_type (), t )
@@ -640,7 +640,7 @@ func (l *ParseTreeListener) parseCommonTypeField(f ICommon_type_fieldContext, ty
640640 if s == "" {
641641 panic (errutil .Explain (nil , "annotation json for field %s is empty in line %d" , typeField .Name , typeField .Position .StartLine ))
642642 }
643- s = strings .Trim (s , "\" " ) // Remove quotes
643+ s = strings .TrimSpace ( strings . Trim (s , "\" " ) ) // Remove quotes
644644 for i , v := range strings .Split (s , "," ) {
645645 v = strings .TrimSpace (v )
646646 if i == 0 {
@@ -668,7 +668,7 @@ func (l *ParseTreeListener) parseCommonTypeField(f ICommon_type_fieldContext, ty
668668 if s == "" {
669669 panic (errutil .Explain (nil , "annotation form for field %s is empty in line %d" , typeField .Name , typeField .Position .StartLine ))
670670 }
671- s = strings .Trim (s , "\" " ) // Remove quotes
671+ s = strings .TrimSpace ( strings . Trim (s , "\" " ) ) // Remove quotes
672672 for i , v := range strings .Split (s , "," ) {
673673 v = strings .TrimSpace (v )
674674 if i == 0 {
@@ -694,7 +694,7 @@ func (l *ParseTreeListener) parseCommonTypeField(f ICommon_type_fieldContext, ty
694694 if s == "" {
695695 panic (errutil .Explain (nil , "annotation %s for field %s is empty in line %d" , opt .Key , typeField .Name , typeField .Position .StartLine ))
696696 }
697- s = strings .Trim (s , "\" " ) // Remove quotes
697+ s = strings .TrimSpace ( strings . Trim (s , "\" " ) ) // Remove quotes
698698 typeField .Binding = & Binding {Source : opt .Key , Field : s }
699699 }
700700
@@ -710,15 +710,14 @@ func (l *ParseTreeListener) parseCommonTypeField(f ICommon_type_fieldContext, ty
710710 if err != nil {
711711 panic (errutil .Explain (nil , `annotation validate for field %s value is not properly quoted in line %d` , typeField .Name , typeField .Position .StartLine ))
712712 }
713- if s == "" {
713+ if s = strings . TrimSpace ( s ); s = = "" {
714714 panic (errutil .Explain (nil , `annotation validate for field %s value is empty in line %d` , typeField .Name , typeField .Position .StartLine ))
715715 }
716- expr , err : = validate .Parse (s )
716+ typeField . ValidateExpr , err = validate .Parse (s )
717717 if err != nil {
718- panic (errutil .Explain (nil , `failed to parse validate expression %s: %w ` , * opt .Value , err ))
718+ panic (errutil .Explain (err , `failed to parse validate expression %s` , * opt .Value ))
719719 }
720- typeField .ValidateExpr = expr
721- collectValidateFuncs (typeField .Type .Text (), typeField .ValidateExpr , l .Funcs )
720+ l .collectValidateFuncs (typeField .Type .Text (), typeField .ValidateExpr )
722721 }
723722}
724723
@@ -745,6 +744,41 @@ func (l *ParseTreeListener) parseFieldAnnotations(ctx IField_annotationsContext)
745744 return ret
746745}
747746
747+ // collectValidateFuncs collects validate functions from the given expression.
748+ func (l * ParseTreeListener ) collectValidateFuncs (fieldType string , expr validate.Expr ) {
749+ switch x := expr .(type ) {
750+ case validate.PrimaryExpr :
751+ if x .Inner != nil {
752+ l .collectValidateFuncs (fieldType , x .Inner )
753+ } else if x .Call != nil {
754+ l .collectValidateFuncs (fieldType , x .Call )
755+ }
756+ case * validate.InnerExpr :
757+ l .collectValidateFuncs (fieldType , x .Expr )
758+ case validate.UnaryExpr :
759+ l .collectValidateFuncs (fieldType , x .Expr )
760+ case validate.BinaryExpr :
761+ l .collectValidateFuncs (fieldType , x .Left )
762+ l .collectValidateFuncs (fieldType , x .Right )
763+ case * validate.FuncCall :
764+ if _ , ok := BuiltinFuncs [x .Name ]; ! ok {
765+ if v , ok := l .Funcs [x .Name ]; ! ok {
766+ l .Funcs [x .Name ] = ValidateFunc {
767+ Name : x .Name ,
768+ Type : fieldType ,
769+ }
770+ } else if v .Type != fieldType {
771+ panic (errutil .Explain (nil , "validate function %s is used with different types" , x .Name ))
772+ }
773+ }
774+ for _ , arg := range x .Args {
775+ l .collectValidateFuncs (fieldType , arg )
776+ }
777+ default :
778+ panic (errutil .Explain (nil , "unexpected validate expression type %T" , x ))
779+ }
780+ }
781+
748782// ExitOneof_def handles "oneof" type definitions.
749783func (l * ParseTreeListener ) ExitOneof_def (ctx * Oneof_defContext ) {
750784 o := Type {
@@ -764,19 +798,19 @@ func (l *ParseTreeListener) ExitOneof_def(ctx *Oneof_defContext) {
764798
765799 e := Enum {Name : o .Name + "Type" , OneOf : true }
766800 o .RawFields = append (o .RawFields , TypeField {
767- Type : UserType {Name : e .Name },
768- Name : "FieldType" ,
769- Required : true ,
801+ Name : "FieldType" ,
802+ Type : UserType {Name : e .Name },
803+ Annotations : []Annotation {
804+ {Key : "enum_as_string" },
805+ },
770806 JSONTag : JSONTag {
771807 Name : "FieldType" ,
772808 },
773809 FormTag : FormTag {
774810 Name : "FieldType" ,
775811 },
812+ Required : true ,
776813 EnumAsString : true ,
777- Annotations : []Annotation {
778- {Key : "enum_as_string" },
779- },
780814 })
781815
782816 for i , f := range ctx .AllUser_type () {
@@ -788,15 +822,8 @@ func (l *ParseTreeListener) ExitOneof_def(ctx *Oneof_defContext) {
788822 })
789823
790824 typeField := TypeField {
791- Type : UserType {
792- Name : f .IDENTIFIER ().GetText (),
793- },
794825 Name : f .IDENTIFIER ().GetText (),
795- JSONTag : JSONTag {
796- Name : f .IDENTIFIER ().GetText (),
797- OmitEmpty : true ,
798- },
799- FormTag : FormTag {
826+ Type : UserType {
800827 Name : f .IDENTIFIER ().GetText (),
801828 },
802829 Position : Position {
@@ -807,7 +834,15 @@ func (l *ParseTreeListener) ExitOneof_def(ctx *Oneof_defContext) {
807834 Above : l .aboveComment (f .GetStart ()),
808835 Right : l .rightComment (f .GetStop ()),
809836 },
837+ JSONTag : JSONTag {
838+ Name : f .IDENTIFIER ().GetText (),
839+ OmitEmpty : true ,
840+ },
841+ FormTag : FormTag {
842+ Name : f .IDENTIFIER ().GetText (),
843+ },
810844 }
845+
811846 o .RawFields = append (o .RawFields , typeField )
812847 }
813848
@@ -818,41 +853,6 @@ func (l *ParseTreeListener) ExitOneof_def(ctx *Oneof_defContext) {
818853 l .Document .Types = append (l .Document .Types , o )
819854}
820855
821- // collectValidateFuncs collects validate functions from the given expression.
822- func collectValidateFuncs (fieldType string , expr validate.Expr , funcs map [string ]ValidateFunc ) {
823- switch x := expr .(type ) {
824- case validate.PrimaryExpr :
825- if x .Inner != nil {
826- collectValidateFuncs (fieldType , x .Inner , funcs )
827- } else if x .Call != nil {
828- collectValidateFuncs (fieldType , x .Call , funcs )
829- }
830- case * validate.InnerExpr :
831- collectValidateFuncs (fieldType , x .Expr , funcs )
832- case validate.UnaryExpr :
833- collectValidateFuncs (fieldType , x .Expr , funcs )
834- case validate.BinaryExpr :
835- collectValidateFuncs (fieldType , x .Left , funcs )
836- collectValidateFuncs (fieldType , x .Right , funcs )
837- case * validate.FuncCall :
838- if _ , ok := BuiltinFuncs [x .Name ]; ! ok {
839- if v , ok := funcs [x .Name ]; ! ok {
840- funcs [x .Name ] = ValidateFunc {
841- Name : x .Name ,
842- Type : fieldType ,
843- }
844- } else if v .Type != fieldType {
845- panic (errutil .Explain (nil , "validate function %s is used with different types" , x .Name ))
846- }
847- }
848- for _ , arg := range x .Args {
849- collectValidateFuncs (fieldType , arg , funcs )
850- }
851- default :
852- panic (errutil .Explain (nil , "unexpected validate expression type %T" , x ))
853- }
854- }
855-
856856// ExitRpc_def handles RPC definitions, including request/response
857857// types and annotations.
858858func (l * ParseTreeListener ) ExitRpc_def (ctx * Rpc_defContext ) {
0 commit comments