diff --git a/generator/go.go b/generator/go.go index 9d6463b..ad04373 100644 --- a/generator/go.go +++ b/generator/go.go @@ -13,25 +13,30 @@ import ( "fmt" "go/format" "io" + "log" "os" "path/filepath" "runtime" + "sort" "strconv" "strings" + "text/template" "github.com/samuel/go-thrift/parser" ) var ( - flagGoBinarystring = flag.Bool("go.binarystring", false, "Always use string for binary instead of []byte") - flagGoImportPrefix = flag.String("go.importprefix", "", "Prefix for Thrift-generated go package imports") - flagGoJSONEnumnum = flag.Bool("go.json.enumnum", false, "For JSON marshal enums by number instead of name") - flagGoPointers = flag.Bool("go.pointers", false, "Make all fields pointers") - flagGoSignedBytes = flag.Bool("go.signedbytes", false, "Interpret Thrift byte as Go signed int8 type") + flagGoBinarystring = flag.Bool("go.binarystring", false, "Always use string for binary instead of []byte") + flagGoJSONEnumnum = flag.Bool("go.json.enumnum", false, "For JSON marshal enums by number instead of name") + flagGoPointers = flag.Bool("go.pointers", false, "Make all fields pointers") + flagGoImportPrefix = flag.String("go.importprefix", "", "Prefix for thrift-generated go package imports") + flagGoGenerateMethods = flag.Bool("go.generate", false, "Add testing/quick compatible Generate methods to enum types") + flagGoSignedBytes = flag.Bool("go.signedbytes", false, "Interpret Thrift byte as Go signed int8 type") + flagGoRPCContext = flag.Bool("go.rpccontext", false, "Add context.Context objects to rpc wrappers") ) var ( - goNamespaceOrder = []string{"go", "perl", "py", "cpp", "rb", "java"} + goNamespaceOrder = []string{"go", "perl", "py", "cpp", "rb", "java", "cpp2"} ) type ErrUnknownType string @@ -60,6 +65,9 @@ type GoGenerator struct { Format bool Pointers bool SignedBytes bool + + // package names imported + packageNames map[string]bool } var goKeywords = map[string]bool{ @@ -88,6 +96,13 @@ var goKeywords = map[string]bool{ "import": true, "return": true, "var": true, + + // request arguments are hardcoded to 'req' and the response to 'res' + "req": true, + "res": true, + // ctx is passed as the first argument, SetContext methods are generated iff flagGoRPCContext is set + "ctx": true, + "SetContext": true, } var basicTypes = map[string]bool{ @@ -187,14 +202,14 @@ func (g *GoGenerator) formatType(pkg string, thrift *parser.Thrift, typ *parser. valueType := g.formatKeyType(pkg, thrift, typ.ValueType) return "map[" + valueType + "]struct{}" case "list": - return "[]" + g.formatType(pkg, thrift, typ.ValueType, 0) + return "[]" + g.formatType(pkg, thrift, typ.ValueType, toNoPointer) case "map": keyType := g.formatKeyType(pkg, thrift, typ.KeyType) return "map[" + keyType + "]" + g.formatType(pkg, thrift, typ.ValueType, toNoPointer) } if t := thrift.Typedefs[typ.Name]; t != nil { - name := typ.Name + name := camelCase(typ.Name) if pkg != g.pkg { name = pkg + "." + name } @@ -212,21 +227,21 @@ func (g *GoGenerator) formatType(pkg string, thrift *parser.Thrift, typ *parser. if pkg != g.pkg { name = pkg + "." + name } - return "*" + name + return ptr + name } if e := thrift.Exceptions[typ.Name]; e != nil { name := e.Name if pkg != g.pkg { name = pkg + "." + name } - return "*" + name + return ptr + name } if u := thrift.Unions[typ.Name]; u != nil { name := u.Name if pkg != g.pkg { name = pkg + "." + name } - return "*" + name + return ptr + name } g.error(ErrUnknownType(typ.Name)) @@ -254,6 +269,10 @@ func (g *GoGenerator) resolveType(typ *parser.Type) string { return typ.Name } +func isContainer(typ *parser.Type) bool { + return typ.Name == "map" || typ.Name == "list" || typ.Name == "set" || (!*flagGoBinarystring && typ.Name == "binary") +} + func (g *GoGenerator) formatField(field *parser.Field) string { tags := "" jsonTags := "" @@ -271,6 +290,50 @@ func (g *GoGenerator) formatField(field *parser.Field) string { camelCase(field.Name), g.formatType(g.pkg, g.thrift, field.Type, opt), field.ID, tags, field.Name, jsonTags) } +var getterTmpl = template.Must(template.New("").Parse(`func ({{ .Receiver }} *{{ .Typ }}) Get{{ .Field }}() (val {{ .FieldTyp }}) { + if {{ .Receiver }} != nil {{ if .Ptr }}&& {{ .Receiver }}.{{ .Field }} != nil{{ end }} { + return {{ if .Ptr }}*{{ end }}{{ .Receiver }}.{{ .Field }} + } + +{{ if .Zero }} + val = {{ .Zero }} +{{ end }} + return +} +`)) + +func (g *GoGenerator) formatFieldGetter(receiver, typ string, field *parser.Field) string { + buf := new(bytes.Buffer) + + zero := "" + if field.Default != nil { + var err error + zero, err = g.formatValue(field.Default, field.Type) + if err != nil { + g.error(err) + } + } + + isPtr := (g.Pointers || field.Optional) && !isContainer(field.Type) + if err := getterTmpl.Execute(buf, struct { + Receiver, Typ string + Field, FieldTyp string + Zero string + Ptr bool + }{ + Receiver: receiver, + Typ: typ, + Field: camelCase(field.Name), + FieldTyp: g.formatType(g.pkg, g.thrift, field.Type, toNoPointer), + Zero: zero, + Ptr: isPtr, + }); err != nil { + g.error(err) + } + + return buf.String() +} + func (g *GoGenerator) formatArguments(arguments []*parser.Field) string { args := make([]string, len(arguments)) for i, arg := range arguments { @@ -302,7 +365,18 @@ func (g *GoGenerator) formatValue(v interface{}, t *parser.Type) (string, error) return strconv.Quote(v2), nil case int: return strconv.Itoa(v2), nil + case bool: + if v2 { + return "true", nil + } + return "false", nil case int64: + if t.Name == "bool" { + if v2 == 0 { + return "false", nil + } + return "true", nil + } return strconv.FormatInt(v2, 10), nil case float64: return strconv.FormatFloat(v2, 'f', -1, 64), nil @@ -326,10 +400,11 @@ func (g *GoGenerator) formatValue(v interface{}, t *parser.Type) (string, error) return buf.String(), nil case []parser.KeyValue: buf := &bytes.Buffer{} - buf.WriteString(g.formatType(g.pkg, g.thrift, t, 0)) + buf.WriteString(g.formatType(g.pkg, g.thrift, t, toNoPointer)) buf.WriteString("{\n") for _, kv := range v2 { buf.WriteString("\t\t") + s, err := g.formatValue(kv.Key, t.KeyType) if err != nil { return "", err @@ -340,19 +415,30 @@ func (g *GoGenerator) formatValue(v interface{}, t *parser.Type) (string, error) if err != nil { return "", err } + + // struct values are pointers + if t.ValueType == nil && *flagGoPointers { + s += ".Ptr()" + } + buf.WriteString(s) buf.WriteString(",\n") } buf.WriteString("\t}") return buf.String(), nil case parser.Identifier: - parts := strings.SplitN(string(v2), ".", 2) - if len(parts) == 1 { - return camelCase(parts[0]), nil + ident := string(v2) + idx := strings.LastIndex(ident, ".") + if idx == -1 { + return camelCase(ident), nil + } + + scope := ident[:idx] + if g.packageNames[scope] { + scope += "." } - resolved := parts[0] + camelCase(parts[1]) - return resolved, nil + return scope + camelCase(ident[idx+1:]), nil } return "", fmt.Errorf("unsupported value type %T", v) } @@ -429,27 +515,72 @@ func (e *%s) UnmarshalJSON(b []byte) error { } `, enumName, enumName, enumName, enumName) + g.write(out, ` +func (e %s) Ptr() *%s { + return &e +} +`, enumName, enumName) + + if *flagGoGenerateMethods { + valueStrings := make([]string, 0, len(enum.Values)) + for _, val := range enum.Values { + valueStrings = append(valueStrings, strconv.FormatInt(int64(val.Value), 10)) + } + sort.Strings(valueStrings) + valueStringsName := strings.ToLower(enumName) + "Values" + + g.write(out, ` +var %s = []int32{%s} + +func (e *%s) Generate(rand *rand.Rand, size int) reflect.Value { + v := %s(%s[rand.Intn(%d)]) + return reflect.ValueOf(&v) +} +`, valueStringsName, strings.Join(valueStrings, ", "), enumName, enumName, valueStringsName, len(valueNames)) + } + return nil } -func (g *GoGenerator) writeStruct(out io.Writer, st *parser.Struct) error { +func (g *GoGenerator) writeStruct(out io.Writer, st *parser.Struct, includeContext bool) error { structName := camelCase(st.Name) g.write(out, "\ntype %s struct {\n", structName) + if includeContext { + g.write(out, "\tctx context.Context\n") + } + for _, field := range st.Fields { g.write(out, "\t%s\n", g.formatField(field)) } - return g.write(out, "}\n") + g.write(out, "}\n") + + receiver := strings.ToLower(structName[:1]) + + // generate Get methods for all fields + for _, field := range st.Fields { + g.write(out, "%s\n", g.formatFieldGetter(receiver, structName, field)) + } + + if includeContext { + g.write(out, ` +func (%s *%s) SetContext(ctx context.Context) { + %s.ctx = ctx +} +`, receiver, structName, receiver) + } + + return g.write(out, "\n") } func (g *GoGenerator) writeException(out io.Writer, ex *parser.Struct) error { - if err := g.writeStruct(out, ex); err != nil { + if err := g.writeStruct(out, ex, false); err != nil { return err } exName := camelCase(ex.Name) - g.write(out, "\nfunc (e *%s) Error() string {\n", exName) + g.write(out, "\nfunc (e %s) Error() string {\n", exName) if len(ex.Fields) == 0 { g.write(out, "\treturn \"%s{}\"\n", exName) } else { @@ -457,7 +588,7 @@ func (g *GoGenerator) writeException(out io.Writer, ex *parser.Struct) error { fieldVars := make([]string, len(ex.Fields)) for i, field := range ex.Fields { fieldNames[i] = camelCase(field.Name) + ": %+v" - fieldVars[i] = "e." + camelCase(field.Name) + fieldVars[i] = "e.Get" + camelCase(field.Name) + "()" } g.write(out, "\treturn fmt.Sprintf(\"%s{%s}\", %s)\n", exName, strings.Join(fieldNames, ", "), strings.Join(fieldVars, ", ")) @@ -472,14 +603,19 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { g.write(out, "\ntype %s interface {\n", svcName) if svc.Extends != "" { - g.write(out, "\t%s\n", camelCase(svc.Extends)) + g.write(out, "\t%s\n", svc.Extends) } methodNames := sortedKeys(svc.Methods) for _, k := range methodNames { method := svc.Methods[k] + args := g.formatArguments(method.Arguments) + if *flagGoRPCContext { + args = "ctx context.Context, " + args + } + g.write(out, "\t%s(%s) %s\n", - camelCase(method.Name), g.formatArguments(method.Arguments), + camelCase(method.Name), args, g.formatReturnType(method.ReturnType, false)) } g.write(out, "}\n") @@ -489,7 +625,7 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { if svc.Extends == "" { g.write(out, "\ntype %sServer struct {\n\tImplementation %s\n}\n", svcName, svcName) } else { - g.write(out, "\ntype %sServer struct {\n\t%sServer\n\tImplementation %s\n}\n", svcName, camelCase(svc.Extends), svcName) + g.write(out, "\ntype %sServer struct {\n\t%sServer\n\tImplementation %s\n}\n", svcName, svc.Extends, svcName) } // Server method wrappers @@ -497,12 +633,21 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { for _, k := range methodNames { method := svc.Methods[k] mName := camelCase(method.Name) + + requestStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Request" + responseStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Response" + resArg := "" if !method.Oneway { - resArg = fmt.Sprintf(", res *%s%sResponse", svcName, mName) + resArg = fmt.Sprintf(", res *%s", responseStructName) } - g.write(out, "\nfunc (s *%sServer) %s(req *%s%sRequest%s) error {\n", svcName, mName, svcName, mName, resArg) + g.write(out, "\nfunc (s *%sServer) %s(req *%s%s) error {\n", svcName, mName, requestStructName, resArg) var args []string + + if *flagGoRPCContext { + args = append(args, "req.ctx") + } + for _, arg := range method.Arguments { aName := camelCase(arg.Name) args = append(args, "req."+aName) @@ -516,12 +661,12 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { if len(method.Exceptions) > 0 { g.write(out, "\tswitch e := err.(type) {\n") for _, ex := range method.Exceptions { - g.write(out, "\tcase %s:\n\t\tres.%s = e\n\t\terr = nil\n", g.formatType(g.pkg, g.thrift, ex.Type, 0), camelCase(ex.Name)) + g.write(out, "\tcase %s:\n\t\tres.%s = e\n\t\terr = nil\n", g.formatType(g.pkg, g.thrift, ex.Type, toOptional), camelCase(ex.Name)) } g.write(out, "\t}\n") } if !isVoid { - if !g.Pointers && basicTypes[g.resolveType(method.ReturnType)] { + if !g.Pointers && !isContainer(method.ReturnType) { g.write(out, "\tres.Value = &val\n") } else { g.write(out, "\tres.Value = val\n") @@ -533,13 +678,16 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { for _, k := range methodNames { // Request struct method := svc.Methods[k] - reqStructName := svcName + camelCase(method.Name) + "Request" - if err := g.writeStruct(out, &parser.Struct{Name: reqStructName, Fields: method.Arguments}); err != nil { + + requestStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Request" + responseStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Response" + + if err := g.writeStruct(out, &parser.Struct{Name: requestStructName, Fields: method.Arguments}, *flagGoRPCContext); err != nil { return err } if method.Oneway { - g.write(out, "\nfunc (r *%s) Oneway() bool {\n\treturn true\n}\n", reqStructName) + g.write(out, "\nfunc (r *%s) Oneway() bool {\n\treturn true\n}\n", requestStructName) } else { // Response struct args := make([]*parser.Field, 0, len(method.Exceptions)) @@ -549,8 +697,8 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { for _, ex := range method.Exceptions { args = append(args, ex) } - res := &parser.Struct{Name: svcName + camelCase(method.Name) + "Response", Fields: args} - if err := g.writeStruct(out, res); err != nil { + res := &parser.Struct{Name: responseStructName, Fields: args} + if err := g.writeStruct(out, res, false); err != nil { return err } } @@ -559,13 +707,17 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { if svc.Extends == "" { g.write(out, "\ntype %sClient struct {\n\tClient RPCClient\n}\n", svcName) } else { - g.write(out, "\ntype %sClient struct {\n\t%sClient\n}\n", svcName, camelCase(svc.Extends)) + g.write(out, "\ntype %sClient struct {\n\t%sClient\n}\n", svcName, svc.Extends) } for _, k := range methodNames { method := svc.Methods[k] + + requestStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Request" + responseStructName := "InternalRPC" + svcName + camelCase(method.Name) + "Response" + methodName := camelCase(method.Name) - returnType := "err error" + returnType := "(err error)" if !method.Oneway { returnType = g.formatReturnType(method.ReturnType, true) } @@ -575,7 +727,7 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { returnType) // Request - g.write(out, "\treq := &%s%sRequest{\n", svcName, methodName) + g.write(out, "\treq := &%s{\n", requestStructName) for _, arg := range method.Arguments { g.write(out, "\t\t%s: %s,\n", camelCase(arg.Name), validGoIdent(lowerCamelCase(arg.Name))) } @@ -586,7 +738,7 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { // g.write(out, "\tvar res *%s%sResponse = nil\n", svcName, methodName) g.write(out, "\tvar res interface{} = nil\n") } else { - g.write(out, "\tres := &%s%sResponse{}\n", svcName, methodName) + g.write(out, "\tres := &%s{}\n", responseStructName) } // Call @@ -603,7 +755,7 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { } if method.ReturnType != nil && method.ReturnType.Name != "void" { - if !g.Pointers && basicTypes[g.resolveType(method.ReturnType)] { + if !g.Pointers && !isContainer(method.ReturnType) { g.write(out, "\tif err == nil && res.Value != nil {\n\t ret = *res.Value\n}\n") } else { g.write(out, "\tif err == nil {\n\tret = res.Value\n}\n") @@ -616,6 +768,26 @@ func (g *GoGenerator) writeService(out io.Writer, svc *parser.Service) error { return nil } +var validMapKeys = map[string]bool{ + "string": true, + "i32": true, + "i64": true, + "bool": true, + "double": true, +} + +func (g *GoGenerator) isValidGoType(typ *parser.Type) bool { + if typ.KeyType == nil { + return true + } + + if _, ok := g.thrift.Enums[g.resolveType(typ.KeyType)]; ok { + return true + } + + return validMapKeys[g.resolveType(typ.KeyType)] +} + func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *parser.Thrift) { packageName := g.Packages[thriftPath].Name g.thrift = thrift @@ -628,7 +800,16 @@ func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *p imports := []string{"fmt"} if len(thrift.Enums) > 0 { imports = append(imports, "strconv") + + if *flagGoGenerateMethods { + imports = append(imports, "math/rand", "reflect") + } } + + if len(thrift.Services) > 0 && *flagGoRPCContext { + imports = append(imports, "golang.org/x/net/context") + } + if len(thrift.Includes) > 0 { for _, path := range thrift.Includes { pkg := g.Packages[path].Name @@ -656,12 +837,19 @@ func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *p for _, k := range sortedKeys(thrift.Typedefs) { t := thrift.Typedefs[k] g.write(out, "type %s %s\n", camelCase(k), g.formatType(g.pkg, g.thrift, t.Type, toNoPointer)) + g.write(out, fmt.Sprintf("func (e %s) Ptr() *%s { return &e }\n", camelCase(k), camelCase(k))) } } if len(thrift.Constants) > 0 { for _, k := range sortedKeys(thrift.Constants) { c := thrift.Constants[k] + + if !g.isValidGoType(c.Type) { + log.Printf("Skipping generation for constant %s - type is not a valid go type (%s)\n", c.Name, g.resolveType(c.Type.KeyType)) + continue + } + v, err := g.formatValue(c.Value, c.Type) if err != nil { g.error(err) @@ -685,7 +873,7 @@ func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *p for _, k := range sortedKeys(thrift.Structs) { st := thrift.Structs[k] - if err := g.writeStruct(out, st); err != nil { + if err := g.writeStruct(out, st, false); err != nil { g.error(err) } } @@ -699,7 +887,7 @@ func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *p for _, k := range sortedKeys(thrift.Unions) { un := thrift.Unions[k] - if err := g.writeStruct(out, un); err != nil { + if err := g.writeStruct(out, un, false); err != nil { g.error(err) } } @@ -724,7 +912,8 @@ func (g *GoGenerator) Generate(outPath string) (err error) { // Generate package namespace mapping if necessary if g.Packages == nil { - g.Packages = make(map[string]GoPackage) + g.Packages = map[string]GoPackage{} + g.packageNames = map[string]bool{} } for path, th := range g.ThriftFiles { if pkg, ok := g.Packages[path]; !ok || pkg.Name == "" { @@ -745,6 +934,7 @@ func (g *GoGenerator) Generate(outPath string) (err error) { } pkg.Name = validIdentifier(strings.ToLower(pkg.Name), "_") g.Packages[path] = pkg + g.packageNames[pkg.Name] = true } } @@ -758,6 +948,10 @@ func (g *GoGenerator) Generate(outPath string) (err error) { filename = filename[:i] } } + if strings.HasSuffix(filename, "_test") { + filename = filename[:len(filename)-len("_test")] + } + filename += ".go" pkgpath := filepath.Join(outPath, pkg.Path, pkg.Name) outfile := filepath.Join(pkgpath, filename) diff --git a/generator/main.go b/generator/main.go index 4fbda76..1670000 100644 --- a/generator/main.go +++ b/generator/main.go @@ -89,6 +89,7 @@ func main() { generator := &GoGenerator{ ThriftFiles: parsedThrift, Format: true, + Pointers: *flagGoPointers, SignedBytes: *flagGoSignedBytes, } err = generator.Generate(outpath) diff --git a/parser/grammar.peg b/parser/grammar.peg index 0bcc963..e4afb21 100644 --- a/parser/grammar.peg +++ b/parser/grammar.peg @@ -107,7 +107,7 @@ Include ← "include" _ file:Literal EOS { Statement ← Include / Namespace / Const / Enum / TypeDef / Struct / Exception / Union / Service -Namespace ← "namespace" _ scope:[*a-z.-]+ _ ns:Identifier EOS { +Namespace ← "namespace" _ scope:[*a-z0-9.-]+ _ ns:Identifier EOS { return &namespace{ scope: ifaceSliceToString(scope), namespace: string(ns.(Identifier)), @@ -135,7 +135,7 @@ Enum ← "enum" _ name:Identifier __ '{' __ values:(EnumValue __)* '}' _ annotat next := 0 for _, v := range vs { ev := v.([]interface{})[0].(*EnumValue) - if ev.Value < 0 { + if !ev.Set { ev.Value = next } if ev.Value >= next { @@ -149,11 +149,11 @@ Enum ← "enum" _ name:Identifier __ '{' __ values:(EnumValue __)* '}' _ annotat EnumValue ← name:Identifier _ value:('=' _ IntConstant)? _ annotations:TypeAnnotations? ListSeparator? { ev := &EnumValue{ Name: string(name.(Identifier)), - Value: -1, Annotations: toAnnotations(annotations), } if value != nil { ev.Value = int(value.([]interface{})[2].(int64)) + ev.Set = true } return ev, nil } @@ -183,15 +183,31 @@ StructLike ← name:Identifier __ '{' __ fields:FieldList '}' _ annotations:Type FieldList ← fields:(Field __)* { fs := fields.([]interface{}) flds := make([]*Field, len(fs)) + ids := make(map[int]bool, len(fs)) for i, f := range fs { flds[i] = f.([]interface{})[0].(*Field) + + if ids[flds[i].ID] { + return nil, fmt.Errorf("multiple fields with the same identifier: %d", flds[i].ID) + } + + ids[flds[i].ID] = true } return flds, nil } -Field ← id:IntConstant _ ':' _ req:FieldReq? _ typ:FieldType _ name:Identifier __ def:('=' _ ConstValue)? _ annotations:TypeAnnotations? ListSeparator? { +FieldID ← id:IntConstant _ ':' { + return int(id.(int64)), nil +} + +Field ← id:FieldID? _ req:FieldReq? _ typ:FieldType __ name:Identifier __ def:('=' _ ConstValue)? _ annotations:TypeAnnotations? ListSeparator? { + parsedID := -1 + if id != nil { + parsedID = id.(int) + } + f := &Field{ - ID : int(id.(int64)), + ID : parsedID, Name : string(name.(Identifier)), Type : typ.(*Type), Annotations: toAnnotations(annotations), @@ -290,7 +306,7 @@ ContainerType ← typ:(MapType / SetType / ListType) { return typ, nil } -MapType ← CppType? "map" WS "<" WS key:FieldType WS "," WS value:FieldType WS ">" _ annotations:TypeAnnotations? { +MapType ← CppType? "map" WS "<" WS key:FieldType WS "," __ value:FieldType WS ">" _ annotations:TypeAnnotations? { return &Type{ Name: "map", KeyType: key.(*Type), @@ -319,7 +335,7 @@ CppType ← "cpp_type" cppType:Literal { return cppType, nil } -ConstValue ← Literal / DoubleConstant / IntConstant / ConstMap / ConstList / Identifier +ConstValue ← Literal / DoubleConstant / IntConstant / BoolConstant / ConstMap / ConstList / Identifier TypeAnnotations ← '(' __ annotations:TypeAnnotation* ')' { var anns []*Annotation @@ -340,6 +356,10 @@ TypeAnnotation ← name:Identifier _ value:('=' __ value:Literal { return value, }, nil } +BoolConstant ← ("true" / "false") { + return string(c.text) == "true", nil +} + IntConstant ← [-+]? Digit+ { return strconv.ParseInt(string(c.text), 10, 64) } @@ -357,7 +377,7 @@ ConstList ← '[' __ values:(ConstValue __ ListSeparator? __)* __ ']' { return vs, nil } -ConstMap ← '{' __ values:(ConstValue __ ':' __ ConstValue __ (',' / &'}') __)* '}' { +ConstMap ← '{' __ values:(ConstValue __ ':' __ ConstValue __ (','? / &'}') __)* '}' { if values == nil { return nil, nil } diff --git a/parser/grammar.peg.go b/parser/grammar.peg.go index 8ae00a6..81f2c97 100644 --- a/parser/grammar.peg.go +++ b/parser/grammar.peg.go @@ -226,28 +226,28 @@ var g = &grammar{ pos: position{line: 110, col: 33, offset: 2367}, expr: &charClassMatcher{ pos: position{line: 110, col: 33, offset: 2367}, - val: "[*a-z.-]", + val: "[*a-z0-9.-]", chars: []rune{'*', '.', '-'}, - ranges: []rune{'a', 'z'}, + ranges: []rune{'a', 'z', '0', '9'}, ignoreCase: false, inverted: false, }, }, }, &ruleRefExpr{ - pos: position{line: 110, col: 43, offset: 2377}, + pos: position{line: 110, col: 46, offset: 2380}, name: "_", }, &labeledExpr{ - pos: position{line: 110, col: 45, offset: 2379}, + pos: position{line: 110, col: 48, offset: 2382}, label: "ns", expr: &ruleRefExpr{ - pos: position{line: 110, col: 48, offset: 2382}, + pos: position{line: 110, col: 51, offset: 2385}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 110, col: 59, offset: 2393}, + pos: position{line: 110, col: 62, offset: 2396}, name: "EOS", }, }, @@ -256,65 +256,65 @@ var g = &grammar{ }, { name: "Const", - pos: position{line: 117, col: 1, offset: 2504}, + pos: position{line: 117, col: 1, offset: 2507}, expr: &actionExpr{ - pos: position{line: 117, col: 9, offset: 2514}, + pos: position{line: 117, col: 9, offset: 2517}, run: (*parser).callonConst1, expr: &seqExpr{ - pos: position{line: 117, col: 9, offset: 2514}, + pos: position{line: 117, col: 9, offset: 2517}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 117, col: 9, offset: 2514}, + pos: position{line: 117, col: 9, offset: 2517}, val: "const", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 117, col: 17, offset: 2522}, + pos: position{line: 117, col: 17, offset: 2525}, name: "_", }, &labeledExpr{ - pos: position{line: 117, col: 19, offset: 2524}, + pos: position{line: 117, col: 19, offset: 2527}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 117, col: 23, offset: 2528}, + pos: position{line: 117, col: 23, offset: 2531}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 117, col: 33, offset: 2538}, + pos: position{line: 117, col: 33, offset: 2541}, name: "_", }, &labeledExpr{ - pos: position{line: 117, col: 35, offset: 2540}, + pos: position{line: 117, col: 35, offset: 2543}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 117, col: 40, offset: 2545}, + pos: position{line: 117, col: 40, offset: 2548}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 117, col: 51, offset: 2556}, + pos: position{line: 117, col: 51, offset: 2559}, name: "__", }, &litMatcher{ - pos: position{line: 117, col: 54, offset: 2559}, + pos: position{line: 117, col: 54, offset: 2562}, val: "=", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 117, col: 58, offset: 2563}, + pos: position{line: 117, col: 58, offset: 2566}, name: "__", }, &labeledExpr{ - pos: position{line: 117, col: 61, offset: 2566}, + pos: position{line: 117, col: 61, offset: 2569}, label: "value", expr: &ruleRefExpr{ - pos: position{line: 117, col: 67, offset: 2572}, + pos: position{line: 117, col: 67, offset: 2575}, name: "ConstValue", }, }, &ruleRefExpr{ - pos: position{line: 117, col: 78, offset: 2583}, + pos: position{line: 117, col: 78, offset: 2586}, name: "EOS", }, }, @@ -323,57 +323,57 @@ var g = &grammar{ }, { name: "Enum", - pos: position{line: 125, col: 1, offset: 2691}, + pos: position{line: 125, col: 1, offset: 2694}, expr: &actionExpr{ - pos: position{line: 125, col: 8, offset: 2700}, + pos: position{line: 125, col: 8, offset: 2703}, run: (*parser).callonEnum1, expr: &seqExpr{ - pos: position{line: 125, col: 8, offset: 2700}, + pos: position{line: 125, col: 8, offset: 2703}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 125, col: 8, offset: 2700}, + pos: position{line: 125, col: 8, offset: 2703}, val: "enum", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 125, col: 15, offset: 2707}, + pos: position{line: 125, col: 15, offset: 2710}, name: "_", }, &labeledExpr{ - pos: position{line: 125, col: 17, offset: 2709}, + pos: position{line: 125, col: 17, offset: 2712}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 125, col: 22, offset: 2714}, + pos: position{line: 125, col: 22, offset: 2717}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 125, col: 33, offset: 2725}, + pos: position{line: 125, col: 33, offset: 2728}, name: "__", }, &litMatcher{ - pos: position{line: 125, col: 36, offset: 2728}, + pos: position{line: 125, col: 36, offset: 2731}, val: "{", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 125, col: 40, offset: 2732}, + pos: position{line: 125, col: 40, offset: 2735}, name: "__", }, &labeledExpr{ - pos: position{line: 125, col: 43, offset: 2735}, + pos: position{line: 125, col: 43, offset: 2738}, label: "values", expr: &zeroOrMoreExpr{ - pos: position{line: 125, col: 50, offset: 2742}, + pos: position{line: 125, col: 50, offset: 2745}, expr: &seqExpr{ - pos: position{line: 125, col: 51, offset: 2743}, + pos: position{line: 125, col: 51, offset: 2746}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 125, col: 51, offset: 2743}, + pos: position{line: 125, col: 51, offset: 2746}, name: "EnumValue", }, &ruleRefExpr{ - pos: position{line: 125, col: 61, offset: 2753}, + pos: position{line: 125, col: 61, offset: 2756}, name: "__", }, }, @@ -381,27 +381,27 @@ var g = &grammar{ }, }, &litMatcher{ - pos: position{line: 125, col: 66, offset: 2758}, + pos: position{line: 125, col: 66, offset: 2761}, val: "}", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 125, col: 70, offset: 2762}, + pos: position{line: 125, col: 70, offset: 2765}, name: "_", }, &labeledExpr{ - pos: position{line: 125, col: 72, offset: 2764}, + pos: position{line: 125, col: 72, offset: 2767}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 125, col: 84, offset: 2776}, + pos: position{line: 125, col: 84, offset: 2779}, expr: &ruleRefExpr{ - pos: position{line: 125, col: 84, offset: 2776}, + pos: position{line: 125, col: 84, offset: 2779}, name: "TypeAnnotations", }, }, }, &ruleRefExpr{ - pos: position{line: 125, col: 101, offset: 2793}, + pos: position{line: 125, col: 101, offset: 2796}, name: "EOS", }, }, @@ -410,44 +410,44 @@ var g = &grammar{ }, { name: "EnumValue", - pos: position{line: 149, col: 1, offset: 3352}, + pos: position{line: 149, col: 1, offset: 3350}, expr: &actionExpr{ - pos: position{line: 149, col: 13, offset: 3366}, + pos: position{line: 149, col: 13, offset: 3364}, run: (*parser).callonEnumValue1, expr: &seqExpr{ - pos: position{line: 149, col: 13, offset: 3366}, + pos: position{line: 149, col: 13, offset: 3364}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 149, col: 13, offset: 3366}, + pos: position{line: 149, col: 13, offset: 3364}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 149, col: 18, offset: 3371}, + pos: position{line: 149, col: 18, offset: 3369}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 149, col: 29, offset: 3382}, + pos: position{line: 149, col: 29, offset: 3380}, name: "_", }, &labeledExpr{ - pos: position{line: 149, col: 31, offset: 3384}, + pos: position{line: 149, col: 31, offset: 3382}, label: "value", expr: &zeroOrOneExpr{ - pos: position{line: 149, col: 37, offset: 3390}, + pos: position{line: 149, col: 37, offset: 3388}, expr: &seqExpr{ - pos: position{line: 149, col: 38, offset: 3391}, + pos: position{line: 149, col: 38, offset: 3389}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 149, col: 38, offset: 3391}, + pos: position{line: 149, col: 38, offset: 3389}, val: "=", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 149, col: 42, offset: 3395}, + pos: position{line: 149, col: 42, offset: 3393}, name: "_", }, &ruleRefExpr{ - pos: position{line: 149, col: 44, offset: 3397}, + pos: position{line: 149, col: 44, offset: 3395}, name: "IntConstant", }, }, @@ -455,24 +455,24 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 149, col: 58, offset: 3411}, + pos: position{line: 149, col: 58, offset: 3409}, name: "_", }, &labeledExpr{ - pos: position{line: 149, col: 60, offset: 3413}, + pos: position{line: 149, col: 60, offset: 3411}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 149, col: 72, offset: 3425}, + pos: position{line: 149, col: 72, offset: 3423}, expr: &ruleRefExpr{ - pos: position{line: 149, col: 72, offset: 3425}, + pos: position{line: 149, col: 72, offset: 3423}, name: "TypeAnnotations", }, }, }, &zeroOrOneExpr{ - pos: position{line: 149, col: 89, offset: 3442}, + pos: position{line: 149, col: 89, offset: 3440}, expr: &ruleRefExpr{ - pos: position{line: 149, col: 89, offset: 3442}, + pos: position{line: 149, col: 89, offset: 3440}, name: "ListSeparator", }, }, @@ -482,59 +482,59 @@ var g = &grammar{ }, { name: "TypeDef", - pos: position{line: 161, col: 1, offset: 3664}, + pos: position{line: 161, col: 1, offset: 3665}, expr: &actionExpr{ - pos: position{line: 161, col: 11, offset: 3676}, + pos: position{line: 161, col: 11, offset: 3677}, run: (*parser).callonTypeDef1, expr: &seqExpr{ - pos: position{line: 161, col: 11, offset: 3676}, + pos: position{line: 161, col: 11, offset: 3677}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 161, col: 11, offset: 3676}, + pos: position{line: 161, col: 11, offset: 3677}, val: "typedef", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 161, col: 21, offset: 3686}, + pos: position{line: 161, col: 21, offset: 3687}, name: "_", }, &labeledExpr{ - pos: position{line: 161, col: 23, offset: 3688}, + pos: position{line: 161, col: 23, offset: 3689}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 161, col: 27, offset: 3692}, + pos: position{line: 161, col: 27, offset: 3693}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 161, col: 37, offset: 3702}, + pos: position{line: 161, col: 37, offset: 3703}, name: "_", }, &labeledExpr{ - pos: position{line: 161, col: 39, offset: 3704}, + pos: position{line: 161, col: 39, offset: 3705}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 161, col: 44, offset: 3709}, + pos: position{line: 161, col: 44, offset: 3710}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 161, col: 55, offset: 3720}, + pos: position{line: 161, col: 55, offset: 3721}, name: "_", }, &labeledExpr{ - pos: position{line: 161, col: 57, offset: 3722}, + pos: position{line: 161, col: 57, offset: 3723}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 161, col: 69, offset: 3734}, + pos: position{line: 161, col: 69, offset: 3735}, expr: &ruleRefExpr{ - pos: position{line: 161, col: 69, offset: 3734}, + pos: position{line: 161, col: 69, offset: 3735}, name: "TypeAnnotations", }, }, }, &ruleRefExpr{ - pos: position{line: 161, col: 86, offset: 3751}, + pos: position{line: 161, col: 86, offset: 3752}, name: "EOS", }, }, @@ -543,27 +543,27 @@ var g = &grammar{ }, { name: "Struct", - pos: position{line: 169, col: 1, offset: 3886}, + pos: position{line: 169, col: 1, offset: 3887}, expr: &actionExpr{ - pos: position{line: 169, col: 10, offset: 3897}, + pos: position{line: 169, col: 10, offset: 3898}, run: (*parser).callonStruct1, expr: &seqExpr{ - pos: position{line: 169, col: 10, offset: 3897}, + pos: position{line: 169, col: 10, offset: 3898}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 169, col: 10, offset: 3897}, + pos: position{line: 169, col: 10, offset: 3898}, val: "struct", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 169, col: 19, offset: 3906}, + pos: position{line: 169, col: 19, offset: 3907}, name: "_", }, &labeledExpr{ - pos: position{line: 169, col: 21, offset: 3908}, + pos: position{line: 169, col: 21, offset: 3909}, label: "st", expr: &ruleRefExpr{ - pos: position{line: 169, col: 24, offset: 3911}, + pos: position{line: 169, col: 24, offset: 3912}, name: "StructLike", }, }, @@ -573,27 +573,27 @@ var g = &grammar{ }, { name: "Exception", - pos: position{line: 170, col: 1, offset: 3951}, + pos: position{line: 170, col: 1, offset: 3952}, expr: &actionExpr{ - pos: position{line: 170, col: 13, offset: 3965}, + pos: position{line: 170, col: 13, offset: 3966}, run: (*parser).callonException1, expr: &seqExpr{ - pos: position{line: 170, col: 13, offset: 3965}, + pos: position{line: 170, col: 13, offset: 3966}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 170, col: 13, offset: 3965}, + pos: position{line: 170, col: 13, offset: 3966}, val: "exception", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 170, col: 25, offset: 3977}, + pos: position{line: 170, col: 25, offset: 3978}, name: "_", }, &labeledExpr{ - pos: position{line: 170, col: 27, offset: 3979}, + pos: position{line: 170, col: 27, offset: 3980}, label: "st", expr: &ruleRefExpr{ - pos: position{line: 170, col: 30, offset: 3982}, + pos: position{line: 170, col: 30, offset: 3983}, name: "StructLike", }, }, @@ -603,27 +603,27 @@ var g = &grammar{ }, { name: "Union", - pos: position{line: 171, col: 1, offset: 4033}, + pos: position{line: 171, col: 1, offset: 4034}, expr: &actionExpr{ - pos: position{line: 171, col: 9, offset: 4043}, + pos: position{line: 171, col: 9, offset: 4044}, run: (*parser).callonUnion1, expr: &seqExpr{ - pos: position{line: 171, col: 9, offset: 4043}, + pos: position{line: 171, col: 9, offset: 4044}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 171, col: 9, offset: 4043}, + pos: position{line: 171, col: 9, offset: 4044}, val: "union", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 171, col: 17, offset: 4051}, + pos: position{line: 171, col: 17, offset: 4052}, name: "_", }, &labeledExpr{ - pos: position{line: 171, col: 19, offset: 4053}, + pos: position{line: 171, col: 19, offset: 4054}, label: "st", expr: &ruleRefExpr{ - pos: position{line: 171, col: 22, offset: 4056}, + pos: position{line: 171, col: 22, offset: 4057}, name: "StructLike", }, }, @@ -633,64 +633,64 @@ var g = &grammar{ }, { name: "StructLike", - pos: position{line: 172, col: 1, offset: 4103}, + pos: position{line: 172, col: 1, offset: 4104}, expr: &actionExpr{ - pos: position{line: 172, col: 14, offset: 4118}, + pos: position{line: 172, col: 14, offset: 4119}, run: (*parser).callonStructLike1, expr: &seqExpr{ - pos: position{line: 172, col: 14, offset: 4118}, + pos: position{line: 172, col: 14, offset: 4119}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 172, col: 14, offset: 4118}, + pos: position{line: 172, col: 14, offset: 4119}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 172, col: 19, offset: 4123}, + pos: position{line: 172, col: 19, offset: 4124}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 172, col: 30, offset: 4134}, + pos: position{line: 172, col: 30, offset: 4135}, name: "__", }, &litMatcher{ - pos: position{line: 172, col: 33, offset: 4137}, + pos: position{line: 172, col: 33, offset: 4138}, val: "{", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 172, col: 37, offset: 4141}, + pos: position{line: 172, col: 37, offset: 4142}, name: "__", }, &labeledExpr{ - pos: position{line: 172, col: 40, offset: 4144}, + pos: position{line: 172, col: 40, offset: 4145}, label: "fields", expr: &ruleRefExpr{ - pos: position{line: 172, col: 47, offset: 4151}, + pos: position{line: 172, col: 47, offset: 4152}, name: "FieldList", }, }, &litMatcher{ - pos: position{line: 172, col: 57, offset: 4161}, + pos: position{line: 172, col: 57, offset: 4162}, val: "}", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 172, col: 61, offset: 4165}, + pos: position{line: 172, col: 61, offset: 4166}, name: "_", }, &labeledExpr{ - pos: position{line: 172, col: 63, offset: 4167}, + pos: position{line: 172, col: 63, offset: 4168}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 172, col: 75, offset: 4179}, + pos: position{line: 172, col: 75, offset: 4180}, expr: &ruleRefExpr{ - pos: position{line: 172, col: 75, offset: 4179}, + pos: position{line: 172, col: 75, offset: 4180}, name: "TypeAnnotations", }, }, }, &ruleRefExpr{ - pos: position{line: 172, col: 92, offset: 4196}, + pos: position{line: 172, col: 92, offset: 4197}, name: "EOS", }, }, @@ -699,24 +699,24 @@ var g = &grammar{ }, { name: "FieldList", - pos: position{line: 183, col: 1, offset: 4373}, + pos: position{line: 183, col: 1, offset: 4374}, expr: &actionExpr{ - pos: position{line: 183, col: 13, offset: 4387}, + pos: position{line: 183, col: 13, offset: 4388}, run: (*parser).callonFieldList1, expr: &labeledExpr{ - pos: position{line: 183, col: 13, offset: 4387}, + pos: position{line: 183, col: 13, offset: 4388}, label: "fields", expr: &zeroOrMoreExpr{ - pos: position{line: 183, col: 20, offset: 4394}, + pos: position{line: 183, col: 20, offset: 4395}, expr: &seqExpr{ - pos: position{line: 183, col: 21, offset: 4395}, + pos: position{line: 183, col: 21, offset: 4396}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 183, col: 21, offset: 4395}, + pos: position{line: 183, col: 21, offset: 4396}, name: "Field", }, &ruleRefExpr{ - pos: position{line: 183, col: 27, offset: 4401}, + pos: position{line: 183, col: 27, offset: 4402}, name: "__", }, }, @@ -726,93 +726,117 @@ var g = &grammar{ }, }, { - name: "Field", - pos: position{line: 192, col: 1, offset: 4561}, + name: "FieldID", + pos: position{line: 199, col: 1, offset: 4738}, expr: &actionExpr{ - pos: position{line: 192, col: 9, offset: 4571}, - run: (*parser).callonField1, + pos: position{line: 199, col: 11, offset: 4750}, + run: (*parser).callonFieldID1, expr: &seqExpr{ - pos: position{line: 192, col: 9, offset: 4571}, + pos: position{line: 199, col: 11, offset: 4750}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 192, col: 9, offset: 4571}, + pos: position{line: 199, col: 11, offset: 4750}, label: "id", expr: &ruleRefExpr{ - pos: position{line: 192, col: 12, offset: 4574}, + pos: position{line: 199, col: 14, offset: 4753}, name: "IntConstant", }, }, &ruleRefExpr{ - pos: position{line: 192, col: 24, offset: 4586}, + pos: position{line: 199, col: 26, offset: 4765}, name: "_", }, &litMatcher{ - pos: position{line: 192, col: 26, offset: 4588}, + pos: position{line: 199, col: 28, offset: 4767}, val: ":", ignoreCase: false, }, + }, + }, + }, + }, + { + name: "Field", + pos: position{line: 203, col: 1, offset: 4805}, + expr: &actionExpr{ + pos: position{line: 203, col: 9, offset: 4815}, + run: (*parser).callonField1, + expr: &seqExpr{ + pos: position{line: 203, col: 9, offset: 4815}, + exprs: []interface{}{ + &labeledExpr{ + pos: position{line: 203, col: 9, offset: 4815}, + label: "id", + expr: &zeroOrOneExpr{ + pos: position{line: 203, col: 12, offset: 4818}, + expr: &ruleRefExpr{ + pos: position{line: 203, col: 12, offset: 4818}, + name: "FieldID", + }, + }, + }, &ruleRefExpr{ - pos: position{line: 192, col: 30, offset: 4592}, + pos: position{line: 203, col: 21, offset: 4827}, name: "_", }, &labeledExpr{ - pos: position{line: 192, col: 32, offset: 4594}, + pos: position{line: 203, col: 23, offset: 4829}, label: "req", expr: &zeroOrOneExpr{ - pos: position{line: 192, col: 36, offset: 4598}, + pos: position{line: 203, col: 27, offset: 4833}, expr: &ruleRefExpr{ - pos: position{line: 192, col: 36, offset: 4598}, + pos: position{line: 203, col: 27, offset: 4833}, name: "FieldReq", }, }, }, &ruleRefExpr{ - pos: position{line: 192, col: 46, offset: 4608}, + pos: position{line: 203, col: 37, offset: 4843}, name: "_", }, &labeledExpr{ - pos: position{line: 192, col: 48, offset: 4610}, + pos: position{line: 203, col: 39, offset: 4845}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 192, col: 52, offset: 4614}, + pos: position{line: 203, col: 43, offset: 4849}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 192, col: 62, offset: 4624}, - name: "_", + pos: position{line: 203, col: 53, offset: 4859}, + name: "__", }, &labeledExpr{ - pos: position{line: 192, col: 64, offset: 4626}, + pos: position{line: 203, col: 56, offset: 4862}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 192, col: 69, offset: 4631}, + pos: position{line: 203, col: 61, offset: 4867}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 192, col: 80, offset: 4642}, + pos: position{line: 203, col: 72, offset: 4878}, name: "__", }, &labeledExpr{ - pos: position{line: 192, col: 83, offset: 4645}, + pos: position{line: 203, col: 75, offset: 4881}, label: "def", expr: &zeroOrOneExpr{ - pos: position{line: 192, col: 87, offset: 4649}, + pos: position{line: 203, col: 79, offset: 4885}, expr: &seqExpr{ - pos: position{line: 192, col: 88, offset: 4650}, + pos: position{line: 203, col: 80, offset: 4886}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 192, col: 88, offset: 4650}, + pos: position{line: 203, col: 80, offset: 4886}, val: "=", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 192, col: 92, offset: 4654}, + pos: position{line: 203, col: 84, offset: 4890}, name: "_", }, &ruleRefExpr{ - pos: position{line: 192, col: 94, offset: 4656}, + pos: position{line: 203, col: 86, offset: 4892}, name: "ConstValue", }, }, @@ -820,24 +844,24 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 192, col: 107, offset: 4669}, + pos: position{line: 203, col: 99, offset: 4905}, name: "_", }, &labeledExpr{ - pos: position{line: 192, col: 109, offset: 4671}, + pos: position{line: 203, col: 101, offset: 4907}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 192, col: 121, offset: 4683}, + pos: position{line: 203, col: 113, offset: 4919}, expr: &ruleRefExpr{ - pos: position{line: 192, col: 121, offset: 4683}, + pos: position{line: 203, col: 113, offset: 4919}, name: "TypeAnnotations", }, }, }, &zeroOrOneExpr{ - pos: position{line: 192, col: 138, offset: 4700}, + pos: position{line: 203, col: 130, offset: 4936}, expr: &ruleRefExpr{ - pos: position{line: 192, col: 138, offset: 4700}, + pos: position{line: 203, col: 130, offset: 4936}, name: "ListSeparator", }, }, @@ -847,20 +871,20 @@ var g = &grammar{ }, { name: "FieldReq", - pos: position{line: 208, col: 1, offset: 5003}, + pos: position{line: 224, col: 1, offset: 5290}, expr: &actionExpr{ - pos: position{line: 208, col: 12, offset: 5016}, + pos: position{line: 224, col: 12, offset: 5303}, run: (*parser).callonFieldReq1, expr: &choiceExpr{ - pos: position{line: 208, col: 13, offset: 5017}, + pos: position{line: 224, col: 13, offset: 5304}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 208, col: 13, offset: 5017}, + pos: position{line: 224, col: 13, offset: 5304}, val: "required", ignoreCase: false, }, &litMatcher{ - pos: position{line: 208, col: 26, offset: 5030}, + pos: position{line: 224, col: 26, offset: 5317}, val: "optional", ignoreCase: false, }, @@ -870,57 +894,57 @@ var g = &grammar{ }, { name: "Service", - pos: position{line: 212, col: 1, offset: 5101}, + pos: position{line: 228, col: 1, offset: 5388}, expr: &actionExpr{ - pos: position{line: 212, col: 11, offset: 5113}, + pos: position{line: 228, col: 11, offset: 5400}, run: (*parser).callonService1, expr: &seqExpr{ - pos: position{line: 212, col: 11, offset: 5113}, + pos: position{line: 228, col: 11, offset: 5400}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 212, col: 11, offset: 5113}, + pos: position{line: 228, col: 11, offset: 5400}, val: "service", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 212, col: 21, offset: 5123}, + pos: position{line: 228, col: 21, offset: 5410}, name: "_", }, &labeledExpr{ - pos: position{line: 212, col: 23, offset: 5125}, + pos: position{line: 228, col: 23, offset: 5412}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 212, col: 28, offset: 5130}, + pos: position{line: 228, col: 28, offset: 5417}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 212, col: 39, offset: 5141}, + pos: position{line: 228, col: 39, offset: 5428}, name: "_", }, &labeledExpr{ - pos: position{line: 212, col: 41, offset: 5143}, + pos: position{line: 228, col: 41, offset: 5430}, label: "extends", expr: &zeroOrOneExpr{ - pos: position{line: 212, col: 49, offset: 5151}, + pos: position{line: 228, col: 49, offset: 5438}, expr: &seqExpr{ - pos: position{line: 212, col: 50, offset: 5152}, + pos: position{line: 228, col: 50, offset: 5439}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 212, col: 50, offset: 5152}, + pos: position{line: 228, col: 50, offset: 5439}, val: "extends", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 212, col: 60, offset: 5162}, + pos: position{line: 228, col: 60, offset: 5449}, name: "__", }, &ruleRefExpr{ - pos: position{line: 212, col: 63, offset: 5165}, + pos: position{line: 228, col: 63, offset: 5452}, name: "Identifier", }, &ruleRefExpr{ - pos: position{line: 212, col: 74, offset: 5176}, + pos: position{line: 228, col: 74, offset: 5463}, name: "__", }, }, @@ -928,32 +952,32 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 212, col: 79, offset: 5181}, + pos: position{line: 228, col: 79, offset: 5468}, name: "__", }, &litMatcher{ - pos: position{line: 212, col: 82, offset: 5184}, + pos: position{line: 228, col: 82, offset: 5471}, val: "{", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 212, col: 86, offset: 5188}, + pos: position{line: 228, col: 86, offset: 5475}, name: "__", }, &labeledExpr{ - pos: position{line: 212, col: 89, offset: 5191}, + pos: position{line: 228, col: 89, offset: 5478}, label: "methods", expr: &zeroOrMoreExpr{ - pos: position{line: 212, col: 97, offset: 5199}, + pos: position{line: 228, col: 97, offset: 5486}, expr: &seqExpr{ - pos: position{line: 212, col: 98, offset: 5200}, + pos: position{line: 228, col: 98, offset: 5487}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 212, col: 98, offset: 5200}, + pos: position{line: 228, col: 98, offset: 5487}, name: "Function", }, &ruleRefExpr{ - pos: position{line: 212, col: 107, offset: 5209}, + pos: position{line: 228, col: 107, offset: 5496}, name: "__", }, }, @@ -961,36 +985,36 @@ var g = &grammar{ }, }, &choiceExpr{ - pos: position{line: 212, col: 113, offset: 5215}, + pos: position{line: 228, col: 113, offset: 5502}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 212, col: 113, offset: 5215}, + pos: position{line: 228, col: 113, offset: 5502}, val: "}", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 212, col: 119, offset: 5221}, + pos: position{line: 228, col: 119, offset: 5508}, name: "EndOfServiceError", }, }, }, &ruleRefExpr{ - pos: position{line: 212, col: 138, offset: 5240}, + pos: position{line: 228, col: 138, offset: 5527}, name: "_", }, &labeledExpr{ - pos: position{line: 212, col: 140, offset: 5242}, + pos: position{line: 228, col: 140, offset: 5529}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 212, col: 152, offset: 5254}, + pos: position{line: 228, col: 152, offset: 5541}, expr: &ruleRefExpr{ - pos: position{line: 212, col: 152, offset: 5254}, + pos: position{line: 228, col: 152, offset: 5541}, name: "TypeAnnotations", }, }, }, &ruleRefExpr{ - pos: position{line: 212, col: 170, offset: 5272}, + pos: position{line: 228, col: 170, offset: 5559}, name: "EOS", }, }, @@ -999,39 +1023,39 @@ var g = &grammar{ }, { name: "EndOfServiceError", - pos: position{line: 228, col: 1, offset: 5656}, + pos: position{line: 244, col: 1, offset: 5943}, expr: &actionExpr{ - pos: position{line: 228, col: 21, offset: 5678}, + pos: position{line: 244, col: 21, offset: 5965}, run: (*parser).callonEndOfServiceError1, expr: &anyMatcher{ - line: 228, col: 21, offset: 5678, + line: 244, col: 21, offset: 5965, }, }, }, { name: "Function", - pos: position{line: 232, col: 1, offset: 5744}, + pos: position{line: 248, col: 1, offset: 6031}, expr: &actionExpr{ - pos: position{line: 232, col: 12, offset: 5757}, + pos: position{line: 248, col: 12, offset: 6044}, run: (*parser).callonFunction1, expr: &seqExpr{ - pos: position{line: 232, col: 12, offset: 5757}, + pos: position{line: 248, col: 12, offset: 6044}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 232, col: 12, offset: 5757}, + pos: position{line: 248, col: 12, offset: 6044}, label: "oneway", expr: &zeroOrOneExpr{ - pos: position{line: 232, col: 19, offset: 5764}, + pos: position{line: 248, col: 19, offset: 6051}, expr: &seqExpr{ - pos: position{line: 232, col: 20, offset: 5765}, + pos: position{line: 248, col: 20, offset: 6052}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 232, col: 20, offset: 5765}, + pos: position{line: 248, col: 20, offset: 6052}, val: "oneway", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 232, col: 29, offset: 5774}, + pos: position{line: 248, col: 29, offset: 6061}, name: "__", }, }, @@ -1039,85 +1063,85 @@ var g = &grammar{ }, }, &labeledExpr{ - pos: position{line: 232, col: 34, offset: 5779}, + pos: position{line: 248, col: 34, offset: 6066}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 232, col: 38, offset: 5783}, + pos: position{line: 248, col: 38, offset: 6070}, name: "FunctionType", }, }, &ruleRefExpr{ - pos: position{line: 232, col: 51, offset: 5796}, + pos: position{line: 248, col: 51, offset: 6083}, name: "__", }, &labeledExpr{ - pos: position{line: 232, col: 54, offset: 5799}, + pos: position{line: 248, col: 54, offset: 6086}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 232, col: 59, offset: 5804}, + pos: position{line: 248, col: 59, offset: 6091}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 232, col: 70, offset: 5815}, + pos: position{line: 248, col: 70, offset: 6102}, name: "_", }, &litMatcher{ - pos: position{line: 232, col: 72, offset: 5817}, + pos: position{line: 248, col: 72, offset: 6104}, val: "(", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 232, col: 76, offset: 5821}, + pos: position{line: 248, col: 76, offset: 6108}, name: "__", }, &labeledExpr{ - pos: position{line: 232, col: 79, offset: 5824}, + pos: position{line: 248, col: 79, offset: 6111}, label: "arguments", expr: &ruleRefExpr{ - pos: position{line: 232, col: 89, offset: 5834}, + pos: position{line: 248, col: 89, offset: 6121}, name: "FieldList", }, }, &litMatcher{ - pos: position{line: 232, col: 99, offset: 5844}, + pos: position{line: 248, col: 99, offset: 6131}, val: ")", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 232, col: 103, offset: 5848}, + pos: position{line: 248, col: 103, offset: 6135}, name: "__", }, &labeledExpr{ - pos: position{line: 232, col: 106, offset: 5851}, + pos: position{line: 248, col: 106, offset: 6138}, label: "exceptions", expr: &zeroOrOneExpr{ - pos: position{line: 232, col: 117, offset: 5862}, + pos: position{line: 248, col: 117, offset: 6149}, expr: &ruleRefExpr{ - pos: position{line: 232, col: 117, offset: 5862}, + pos: position{line: 248, col: 117, offset: 6149}, name: "Throws", }, }, }, &ruleRefExpr{ - pos: position{line: 232, col: 125, offset: 5870}, + pos: position{line: 248, col: 125, offset: 6157}, name: "_", }, &labeledExpr{ - pos: position{line: 232, col: 127, offset: 5872}, + pos: position{line: 248, col: 127, offset: 6159}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 232, col: 139, offset: 5884}, + pos: position{line: 248, col: 139, offset: 6171}, expr: &ruleRefExpr{ - pos: position{line: 232, col: 139, offset: 5884}, + pos: position{line: 248, col: 139, offset: 6171}, name: "TypeAnnotations", }, }, }, &zeroOrOneExpr{ - pos: position{line: 232, col: 156, offset: 5901}, + pos: position{line: 248, col: 156, offset: 6188}, expr: &ruleRefExpr{ - pos: position{line: 232, col: 156, offset: 5901}, + pos: position{line: 248, col: 156, offset: 6188}, name: "ListSeparator", }, }, @@ -1127,23 +1151,23 @@ var g = &grammar{ }, { name: "FunctionType", - pos: position{line: 256, col: 1, offset: 6325}, + pos: position{line: 272, col: 1, offset: 6612}, expr: &actionExpr{ - pos: position{line: 256, col: 16, offset: 6342}, + pos: position{line: 272, col: 16, offset: 6629}, run: (*parser).callonFunctionType1, expr: &labeledExpr{ - pos: position{line: 256, col: 16, offset: 6342}, + pos: position{line: 272, col: 16, offset: 6629}, label: "typ", expr: &choiceExpr{ - pos: position{line: 256, col: 21, offset: 6347}, + pos: position{line: 272, col: 21, offset: 6634}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 256, col: 21, offset: 6347}, + pos: position{line: 272, col: 21, offset: 6634}, val: "void", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 256, col: 30, offset: 6356}, + pos: position{line: 272, col: 30, offset: 6643}, name: "FieldType", }, }, @@ -1153,41 +1177,41 @@ var g = &grammar{ }, { name: "Throws", - pos: position{line: 263, col: 1, offset: 6463}, + pos: position{line: 279, col: 1, offset: 6750}, expr: &actionExpr{ - pos: position{line: 263, col: 10, offset: 6474}, + pos: position{line: 279, col: 10, offset: 6761}, run: (*parser).callonThrows1, expr: &seqExpr{ - pos: position{line: 263, col: 10, offset: 6474}, + pos: position{line: 279, col: 10, offset: 6761}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 263, col: 10, offset: 6474}, + pos: position{line: 279, col: 10, offset: 6761}, val: "throws", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 263, col: 19, offset: 6483}, + pos: position{line: 279, col: 19, offset: 6770}, name: "__", }, &litMatcher{ - pos: position{line: 263, col: 22, offset: 6486}, + pos: position{line: 279, col: 22, offset: 6773}, val: "(", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 263, col: 26, offset: 6490}, + pos: position{line: 279, col: 26, offset: 6777}, name: "__", }, &labeledExpr{ - pos: position{line: 263, col: 29, offset: 6493}, + pos: position{line: 279, col: 29, offset: 6780}, label: "exceptions", expr: &ruleRefExpr{ - pos: position{line: 263, col: 40, offset: 6504}, + pos: position{line: 279, col: 40, offset: 6791}, name: "FieldList", }, }, &litMatcher{ - pos: position{line: 263, col: 50, offset: 6514}, + pos: position{line: 279, col: 50, offset: 6801}, val: ")", ignoreCase: false, }, @@ -1197,26 +1221,26 @@ var g = &grammar{ }, { name: "FieldType", - pos: position{line: 267, col: 1, offset: 6547}, + pos: position{line: 283, col: 1, offset: 6834}, expr: &actionExpr{ - pos: position{line: 267, col: 13, offset: 6561}, + pos: position{line: 283, col: 13, offset: 6848}, run: (*parser).callonFieldType1, expr: &labeledExpr{ - pos: position{line: 267, col: 13, offset: 6561}, + pos: position{line: 283, col: 13, offset: 6848}, label: "typ", expr: &choiceExpr{ - pos: position{line: 267, col: 18, offset: 6566}, + pos: position{line: 283, col: 18, offset: 6853}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 267, col: 18, offset: 6566}, + pos: position{line: 283, col: 18, offset: 6853}, name: "BaseType", }, &ruleRefExpr{ - pos: position{line: 267, col: 29, offset: 6577}, + pos: position{line: 283, col: 29, offset: 6864}, name: "ContainerType", }, &ruleRefExpr{ - pos: position{line: 267, col: 45, offset: 6593}, + pos: position{line: 283, col: 45, offset: 6880}, name: "Identifier", }, }, @@ -1226,22 +1250,22 @@ var g = &grammar{ }, { name: "DefinitionType", - pos: position{line: 274, col: 1, offset: 6703}, + pos: position{line: 290, col: 1, offset: 6990}, expr: &actionExpr{ - pos: position{line: 274, col: 18, offset: 6722}, + pos: position{line: 290, col: 18, offset: 7009}, run: (*parser).callonDefinitionType1, expr: &labeledExpr{ - pos: position{line: 274, col: 18, offset: 6722}, + pos: position{line: 290, col: 18, offset: 7009}, label: "typ", expr: &choiceExpr{ - pos: position{line: 274, col: 23, offset: 6727}, + pos: position{line: 290, col: 23, offset: 7014}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 274, col: 23, offset: 6727}, + pos: position{line: 290, col: 23, offset: 7014}, name: "BaseType", }, &ruleRefExpr{ - pos: position{line: 274, col: 34, offset: 6738}, + pos: position{line: 290, col: 34, offset: 7025}, name: "ContainerType", }, }, @@ -1251,32 +1275,32 @@ var g = &grammar{ }, { name: "BaseType", - pos: position{line: 278, col: 1, offset: 6775}, + pos: position{line: 294, col: 1, offset: 7062}, expr: &actionExpr{ - pos: position{line: 278, col: 12, offset: 6788}, + pos: position{line: 294, col: 12, offset: 7075}, run: (*parser).callonBaseType1, expr: &seqExpr{ - pos: position{line: 278, col: 12, offset: 6788}, + pos: position{line: 294, col: 12, offset: 7075}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 278, col: 12, offset: 6788}, + pos: position{line: 294, col: 12, offset: 7075}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 278, col: 17, offset: 6793}, + pos: position{line: 294, col: 17, offset: 7080}, name: "BaseTypeName", }, }, &ruleRefExpr{ - pos: position{line: 278, col: 30, offset: 6806}, + pos: position{line: 294, col: 30, offset: 7093}, name: "_", }, &labeledExpr{ - pos: position{line: 278, col: 32, offset: 6808}, + pos: position{line: 294, col: 32, offset: 7095}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 278, col: 44, offset: 6820}, + pos: position{line: 294, col: 44, offset: 7107}, expr: &ruleRefExpr{ - pos: position{line: 278, col: 44, offset: 6820}, + pos: position{line: 294, col: 44, offset: 7107}, name: "TypeAnnotations", }, }, @@ -1287,50 +1311,50 @@ var g = &grammar{ }, { name: "BaseTypeName", - pos: position{line: 285, col: 1, offset: 6931}, + pos: position{line: 301, col: 1, offset: 7218}, expr: &actionExpr{ - pos: position{line: 285, col: 16, offset: 6948}, + pos: position{line: 301, col: 16, offset: 7235}, run: (*parser).callonBaseTypeName1, expr: &choiceExpr{ - pos: position{line: 285, col: 17, offset: 6949}, + pos: position{line: 301, col: 17, offset: 7236}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 285, col: 17, offset: 6949}, + pos: position{line: 301, col: 17, offset: 7236}, val: "bool", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 26, offset: 6958}, + pos: position{line: 301, col: 26, offset: 7245}, val: "byte", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 35, offset: 6967}, + pos: position{line: 301, col: 35, offset: 7254}, val: "i16", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 43, offset: 6975}, + pos: position{line: 301, col: 43, offset: 7262}, val: "i32", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 51, offset: 6983}, + pos: position{line: 301, col: 51, offset: 7270}, val: "i64", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 59, offset: 6991}, + pos: position{line: 301, col: 59, offset: 7278}, val: "double", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 70, offset: 7002}, + pos: position{line: 301, col: 70, offset: 7289}, val: "string", ignoreCase: false, }, &litMatcher{ - pos: position{line: 285, col: 81, offset: 7013}, + pos: position{line: 301, col: 81, offset: 7300}, val: "binary", ignoreCase: false, }, @@ -1340,26 +1364,26 @@ var g = &grammar{ }, { name: "ContainerType", - pos: position{line: 289, col: 1, offset: 7057}, + pos: position{line: 305, col: 1, offset: 7344}, expr: &actionExpr{ - pos: position{line: 289, col: 17, offset: 7075}, + pos: position{line: 305, col: 17, offset: 7362}, run: (*parser).callonContainerType1, expr: &labeledExpr{ - pos: position{line: 289, col: 17, offset: 7075}, + pos: position{line: 305, col: 17, offset: 7362}, label: "typ", expr: &choiceExpr{ - pos: position{line: 289, col: 22, offset: 7080}, + pos: position{line: 305, col: 22, offset: 7367}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 289, col: 22, offset: 7080}, + pos: position{line: 305, col: 22, offset: 7367}, name: "MapType", }, &ruleRefExpr{ - pos: position{line: 289, col: 32, offset: 7090}, + pos: position{line: 305, col: 32, offset: 7377}, name: "SetType", }, &ruleRefExpr{ - pos: position{line: 289, col: 42, offset: 7100}, + pos: position{line: 305, col: 42, offset: 7387}, name: "ListType", }, }, @@ -1369,87 +1393,87 @@ var g = &grammar{ }, { name: "MapType", - pos: position{line: 293, col: 1, offset: 7132}, + pos: position{line: 309, col: 1, offset: 7419}, expr: &actionExpr{ - pos: position{line: 293, col: 11, offset: 7144}, + pos: position{line: 309, col: 11, offset: 7431}, run: (*parser).callonMapType1, expr: &seqExpr{ - pos: position{line: 293, col: 11, offset: 7144}, + pos: position{line: 309, col: 11, offset: 7431}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 293, col: 11, offset: 7144}, + pos: position{line: 309, col: 11, offset: 7431}, expr: &ruleRefExpr{ - pos: position{line: 293, col: 11, offset: 7144}, + pos: position{line: 309, col: 11, offset: 7431}, name: "CppType", }, }, &litMatcher{ - pos: position{line: 293, col: 20, offset: 7153}, + pos: position{line: 309, col: 20, offset: 7440}, val: "map", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 293, col: 26, offset: 7159}, + pos: position{line: 309, col: 26, offset: 7446}, name: "WS", }, &litMatcher{ - pos: position{line: 293, col: 29, offset: 7162}, + pos: position{line: 309, col: 29, offset: 7449}, val: "<", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 293, col: 33, offset: 7166}, + pos: position{line: 309, col: 33, offset: 7453}, name: "WS", }, &labeledExpr{ - pos: position{line: 293, col: 36, offset: 7169}, + pos: position{line: 309, col: 36, offset: 7456}, label: "key", expr: &ruleRefExpr{ - pos: position{line: 293, col: 40, offset: 7173}, + pos: position{line: 309, col: 40, offset: 7460}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 293, col: 50, offset: 7183}, + pos: position{line: 309, col: 50, offset: 7470}, name: "WS", }, &litMatcher{ - pos: position{line: 293, col: 53, offset: 7186}, + pos: position{line: 309, col: 53, offset: 7473}, val: ",", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 293, col: 57, offset: 7190}, - name: "WS", + pos: position{line: 309, col: 57, offset: 7477}, + name: "__", }, &labeledExpr{ - pos: position{line: 293, col: 60, offset: 7193}, + pos: position{line: 309, col: 60, offset: 7480}, label: "value", expr: &ruleRefExpr{ - pos: position{line: 293, col: 66, offset: 7199}, + pos: position{line: 309, col: 66, offset: 7486}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 293, col: 76, offset: 7209}, + pos: position{line: 309, col: 76, offset: 7496}, name: "WS", }, &litMatcher{ - pos: position{line: 293, col: 79, offset: 7212}, + pos: position{line: 309, col: 79, offset: 7499}, val: ">", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 293, col: 83, offset: 7216}, + pos: position{line: 309, col: 83, offset: 7503}, name: "_", }, &labeledExpr{ - pos: position{line: 293, col: 85, offset: 7218}, + pos: position{line: 309, col: 85, offset: 7505}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 293, col: 97, offset: 7230}, + pos: position{line: 309, col: 97, offset: 7517}, expr: &ruleRefExpr{ - pos: position{line: 293, col: 97, offset: 7230}, + pos: position{line: 309, col: 97, offset: 7517}, name: "TypeAnnotations", }, }, @@ -1460,66 +1484,66 @@ var g = &grammar{ }, { name: "SetType", - pos: position{line: 302, col: 1, offset: 7385}, + pos: position{line: 318, col: 1, offset: 7672}, expr: &actionExpr{ - pos: position{line: 302, col: 11, offset: 7397}, + pos: position{line: 318, col: 11, offset: 7684}, run: (*parser).callonSetType1, expr: &seqExpr{ - pos: position{line: 302, col: 11, offset: 7397}, + pos: position{line: 318, col: 11, offset: 7684}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 302, col: 11, offset: 7397}, + pos: position{line: 318, col: 11, offset: 7684}, expr: &ruleRefExpr{ - pos: position{line: 302, col: 11, offset: 7397}, + pos: position{line: 318, col: 11, offset: 7684}, name: "CppType", }, }, &litMatcher{ - pos: position{line: 302, col: 20, offset: 7406}, + pos: position{line: 318, col: 20, offset: 7693}, val: "set", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 302, col: 26, offset: 7412}, + pos: position{line: 318, col: 26, offset: 7699}, name: "WS", }, &litMatcher{ - pos: position{line: 302, col: 29, offset: 7415}, + pos: position{line: 318, col: 29, offset: 7702}, val: "<", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 302, col: 33, offset: 7419}, + pos: position{line: 318, col: 33, offset: 7706}, name: "WS", }, &labeledExpr{ - pos: position{line: 302, col: 36, offset: 7422}, + pos: position{line: 318, col: 36, offset: 7709}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 302, col: 40, offset: 7426}, + pos: position{line: 318, col: 40, offset: 7713}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 302, col: 50, offset: 7436}, + pos: position{line: 318, col: 50, offset: 7723}, name: "WS", }, &litMatcher{ - pos: position{line: 302, col: 53, offset: 7439}, + pos: position{line: 318, col: 53, offset: 7726}, val: ">", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 302, col: 57, offset: 7443}, + pos: position{line: 318, col: 57, offset: 7730}, name: "_", }, &labeledExpr{ - pos: position{line: 302, col: 59, offset: 7445}, + pos: position{line: 318, col: 59, offset: 7732}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 302, col: 71, offset: 7457}, + pos: position{line: 318, col: 71, offset: 7744}, expr: &ruleRefExpr{ - pos: position{line: 302, col: 71, offset: 7457}, + pos: position{line: 318, col: 71, offset: 7744}, name: "TypeAnnotations", }, }, @@ -1530,59 +1554,59 @@ var g = &grammar{ }, { name: "ListType", - pos: position{line: 310, col: 1, offset: 7586}, + pos: position{line: 326, col: 1, offset: 7873}, expr: &actionExpr{ - pos: position{line: 310, col: 12, offset: 7599}, + pos: position{line: 326, col: 12, offset: 7886}, run: (*parser).callonListType1, expr: &seqExpr{ - pos: position{line: 310, col: 12, offset: 7599}, + pos: position{line: 326, col: 12, offset: 7886}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 310, col: 12, offset: 7599}, + pos: position{line: 326, col: 12, offset: 7886}, val: "list", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 310, col: 19, offset: 7606}, + pos: position{line: 326, col: 19, offset: 7893}, name: "WS", }, &litMatcher{ - pos: position{line: 310, col: 22, offset: 7609}, + pos: position{line: 326, col: 22, offset: 7896}, val: "<", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 310, col: 26, offset: 7613}, + pos: position{line: 326, col: 26, offset: 7900}, name: "WS", }, &labeledExpr{ - pos: position{line: 310, col: 29, offset: 7616}, + pos: position{line: 326, col: 29, offset: 7903}, label: "typ", expr: &ruleRefExpr{ - pos: position{line: 310, col: 33, offset: 7620}, + pos: position{line: 326, col: 33, offset: 7907}, name: "FieldType", }, }, &ruleRefExpr{ - pos: position{line: 310, col: 43, offset: 7630}, + pos: position{line: 326, col: 43, offset: 7917}, name: "WS", }, &litMatcher{ - pos: position{line: 310, col: 46, offset: 7633}, + pos: position{line: 326, col: 46, offset: 7920}, val: ">", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 310, col: 50, offset: 7637}, + pos: position{line: 326, col: 50, offset: 7924}, name: "_", }, &labeledExpr{ - pos: position{line: 310, col: 52, offset: 7639}, + pos: position{line: 326, col: 52, offset: 7926}, label: "annotations", expr: &zeroOrOneExpr{ - pos: position{line: 310, col: 64, offset: 7651}, + pos: position{line: 326, col: 64, offset: 7938}, expr: &ruleRefExpr{ - pos: position{line: 310, col: 64, offset: 7651}, + pos: position{line: 326, col: 64, offset: 7938}, name: "TypeAnnotations", }, }, @@ -1593,23 +1617,23 @@ var g = &grammar{ }, { name: "CppType", - pos: position{line: 318, col: 1, offset: 7781}, + pos: position{line: 334, col: 1, offset: 8068}, expr: &actionExpr{ - pos: position{line: 318, col: 11, offset: 7793}, + pos: position{line: 334, col: 11, offset: 8080}, run: (*parser).callonCppType1, expr: &seqExpr{ - pos: position{line: 318, col: 11, offset: 7793}, + pos: position{line: 334, col: 11, offset: 8080}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 318, col: 11, offset: 7793}, + pos: position{line: 334, col: 11, offset: 8080}, val: "cpp_type", ignoreCase: false, }, &labeledExpr{ - pos: position{line: 318, col: 22, offset: 7804}, + pos: position{line: 334, col: 22, offset: 8091}, label: "cppType", expr: &ruleRefExpr{ - pos: position{line: 318, col: 30, offset: 7812}, + pos: position{line: 334, col: 30, offset: 8099}, name: "Literal", }, }, @@ -1619,32 +1643,36 @@ var g = &grammar{ }, { name: "ConstValue", - pos: position{line: 322, col: 1, offset: 7846}, + pos: position{line: 338, col: 1, offset: 8133}, expr: &choiceExpr{ - pos: position{line: 322, col: 14, offset: 7861}, + pos: position{line: 338, col: 14, offset: 8148}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 322, col: 14, offset: 7861}, + pos: position{line: 338, col: 14, offset: 8148}, name: "Literal", }, &ruleRefExpr{ - pos: position{line: 322, col: 24, offset: 7871}, + pos: position{line: 338, col: 24, offset: 8158}, name: "DoubleConstant", }, &ruleRefExpr{ - pos: position{line: 322, col: 41, offset: 7888}, + pos: position{line: 338, col: 41, offset: 8175}, name: "IntConstant", }, &ruleRefExpr{ - pos: position{line: 322, col: 55, offset: 7902}, + pos: position{line: 338, col: 55, offset: 8189}, + name: "BoolConstant", + }, + &ruleRefExpr{ + pos: position{line: 338, col: 70, offset: 8204}, name: "ConstMap", }, &ruleRefExpr{ - pos: position{line: 322, col: 66, offset: 7913}, + pos: position{line: 338, col: 81, offset: 8215}, name: "ConstList", }, &ruleRefExpr{ - pos: position{line: 322, col: 78, offset: 7925}, + pos: position{line: 338, col: 93, offset: 8227}, name: "Identifier", }, }, @@ -1652,35 +1680,35 @@ var g = &grammar{ }, { name: "TypeAnnotations", - pos: position{line: 324, col: 1, offset: 7937}, + pos: position{line: 340, col: 1, offset: 8239}, expr: &actionExpr{ - pos: position{line: 324, col: 19, offset: 7957}, + pos: position{line: 340, col: 19, offset: 8259}, run: (*parser).callonTypeAnnotations1, expr: &seqExpr{ - pos: position{line: 324, col: 19, offset: 7957}, + pos: position{line: 340, col: 19, offset: 8259}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 324, col: 19, offset: 7957}, + pos: position{line: 340, col: 19, offset: 8259}, val: "(", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 324, col: 23, offset: 7961}, + pos: position{line: 340, col: 23, offset: 8263}, name: "__", }, &labeledExpr{ - pos: position{line: 324, col: 26, offset: 7964}, + pos: position{line: 340, col: 26, offset: 8266}, label: "annotations", expr: &zeroOrMoreExpr{ - pos: position{line: 324, col: 38, offset: 7976}, + pos: position{line: 340, col: 38, offset: 8278}, expr: &ruleRefExpr{ - pos: position{line: 324, col: 38, offset: 7976}, + pos: position{line: 340, col: 38, offset: 8278}, name: "TypeAnnotation", }, }, }, &litMatcher{ - pos: position{line: 324, col: 54, offset: 7992}, + pos: position{line: 340, col: 54, offset: 8294}, val: ")", ignoreCase: false, }, @@ -1690,50 +1718,50 @@ var g = &grammar{ }, { name: "TypeAnnotation", - pos: position{line: 332, col: 1, offset: 8138}, + pos: position{line: 348, col: 1, offset: 8440}, expr: &actionExpr{ - pos: position{line: 332, col: 18, offset: 8157}, + pos: position{line: 348, col: 18, offset: 8459}, run: (*parser).callonTypeAnnotation1, expr: &seqExpr{ - pos: position{line: 332, col: 18, offset: 8157}, + pos: position{line: 348, col: 18, offset: 8459}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 332, col: 18, offset: 8157}, + pos: position{line: 348, col: 18, offset: 8459}, label: "name", expr: &ruleRefExpr{ - pos: position{line: 332, col: 23, offset: 8162}, + pos: position{line: 348, col: 23, offset: 8464}, name: "Identifier", }, }, &ruleRefExpr{ - pos: position{line: 332, col: 34, offset: 8173}, + pos: position{line: 348, col: 34, offset: 8475}, name: "_", }, &labeledExpr{ - pos: position{line: 332, col: 36, offset: 8175}, + pos: position{line: 348, col: 36, offset: 8477}, label: "value", expr: &zeroOrOneExpr{ - pos: position{line: 332, col: 42, offset: 8181}, + pos: position{line: 348, col: 42, offset: 8483}, expr: &actionExpr{ - pos: position{line: 332, col: 43, offset: 8182}, + pos: position{line: 348, col: 43, offset: 8484}, run: (*parser).callonTypeAnnotation8, expr: &seqExpr{ - pos: position{line: 332, col: 43, offset: 8182}, + pos: position{line: 348, col: 43, offset: 8484}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 332, col: 43, offset: 8182}, + pos: position{line: 348, col: 43, offset: 8484}, val: "=", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 332, col: 47, offset: 8186}, + pos: position{line: 348, col: 47, offset: 8488}, name: "__", }, &labeledExpr{ - pos: position{line: 332, col: 50, offset: 8189}, + pos: position{line: 348, col: 50, offset: 8491}, label: "value", expr: &ruleRefExpr{ - pos: position{line: 332, col: 56, offset: 8195}, + pos: position{line: 348, col: 56, offset: 8497}, name: "Literal", }, }, @@ -1743,33 +1771,56 @@ var g = &grammar{ }, }, &zeroOrOneExpr{ - pos: position{line: 332, col: 88, offset: 8227}, + pos: position{line: 348, col: 88, offset: 8529}, expr: &ruleRefExpr{ - pos: position{line: 332, col: 88, offset: 8227}, + pos: position{line: 348, col: 88, offset: 8529}, name: "ListSeparator", }, }, &ruleRefExpr{ - pos: position{line: 332, col: 103, offset: 8242}, + pos: position{line: 348, col: 103, offset: 8544}, name: "__", }, }, }, }, }, + { + name: "BoolConstant", + pos: position{line: 359, col: 1, offset: 8707}, + expr: &actionExpr{ + pos: position{line: 359, col: 16, offset: 8724}, + run: (*parser).callonBoolConstant1, + expr: &choiceExpr{ + pos: position{line: 359, col: 17, offset: 8725}, + alternatives: []interface{}{ + &litMatcher{ + pos: position{line: 359, col: 17, offset: 8725}, + val: "true", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 359, col: 26, offset: 8734}, + val: "false", + ignoreCase: false, + }, + }, + }, + }, + }, { name: "IntConstant", - pos: position{line: 343, col: 1, offset: 8405}, + pos: position{line: 363, col: 1, offset: 8786}, expr: &actionExpr{ - pos: position{line: 343, col: 15, offset: 8421}, + pos: position{line: 363, col: 15, offset: 8802}, run: (*parser).callonIntConstant1, expr: &seqExpr{ - pos: position{line: 343, col: 15, offset: 8421}, + pos: position{line: 363, col: 15, offset: 8802}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 343, col: 15, offset: 8421}, + pos: position{line: 363, col: 15, offset: 8802}, expr: &charClassMatcher{ - pos: position{line: 343, col: 15, offset: 8421}, + pos: position{line: 363, col: 15, offset: 8802}, val: "[-+]", chars: []rune{'-', '+'}, ignoreCase: false, @@ -1777,9 +1828,9 @@ var g = &grammar{ }, }, &oneOrMoreExpr{ - pos: position{line: 343, col: 21, offset: 8427}, + pos: position{line: 363, col: 21, offset: 8808}, expr: &ruleRefExpr{ - pos: position{line: 343, col: 21, offset: 8427}, + pos: position{line: 363, col: 21, offset: 8808}, name: "Digit", }, }, @@ -1789,17 +1840,17 @@ var g = &grammar{ }, { name: "DoubleConstant", - pos: position{line: 347, col: 1, offset: 8488}, + pos: position{line: 367, col: 1, offset: 8869}, expr: &actionExpr{ - pos: position{line: 347, col: 18, offset: 8507}, + pos: position{line: 367, col: 18, offset: 8888}, run: (*parser).callonDoubleConstant1, expr: &seqExpr{ - pos: position{line: 347, col: 18, offset: 8507}, + pos: position{line: 367, col: 18, offset: 8888}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 347, col: 18, offset: 8507}, + pos: position{line: 367, col: 18, offset: 8888}, expr: &charClassMatcher{ - pos: position{line: 347, col: 18, offset: 8507}, + pos: position{line: 367, col: 18, offset: 8888}, val: "[+-]", chars: []rune{'+', '-'}, ignoreCase: false, @@ -1807,38 +1858,38 @@ var g = &grammar{ }, }, &zeroOrMoreExpr{ - pos: position{line: 347, col: 24, offset: 8513}, + pos: position{line: 367, col: 24, offset: 8894}, expr: &ruleRefExpr{ - pos: position{line: 347, col: 24, offset: 8513}, + pos: position{line: 367, col: 24, offset: 8894}, name: "Digit", }, }, &litMatcher{ - pos: position{line: 347, col: 31, offset: 8520}, + pos: position{line: 367, col: 31, offset: 8901}, val: ".", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 347, col: 35, offset: 8524}, + pos: position{line: 367, col: 35, offset: 8905}, expr: &ruleRefExpr{ - pos: position{line: 347, col: 35, offset: 8524}, + pos: position{line: 367, col: 35, offset: 8905}, name: "Digit", }, }, &zeroOrOneExpr{ - pos: position{line: 347, col: 42, offset: 8531}, + pos: position{line: 367, col: 42, offset: 8912}, expr: &seqExpr{ - pos: position{line: 347, col: 44, offset: 8533}, + pos: position{line: 367, col: 44, offset: 8914}, exprs: []interface{}{ &charClassMatcher{ - pos: position{line: 347, col: 44, offset: 8533}, + pos: position{line: 367, col: 44, offset: 8914}, val: "['Ee']", chars: []rune{'\'', 'E', 'e', '\''}, ignoreCase: false, inverted: false, }, &ruleRefExpr{ - pos: position{line: 347, col: 51, offset: 8540}, + pos: position{line: 367, col: 51, offset: 8921}, name: "IntConstant", }, }, @@ -1850,47 +1901,47 @@ var g = &grammar{ }, { name: "ConstList", - pos: position{line: 351, col: 1, offset: 8607}, + pos: position{line: 371, col: 1, offset: 8988}, expr: &actionExpr{ - pos: position{line: 351, col: 13, offset: 8621}, + pos: position{line: 371, col: 13, offset: 9002}, run: (*parser).callonConstList1, expr: &seqExpr{ - pos: position{line: 351, col: 13, offset: 8621}, + pos: position{line: 371, col: 13, offset: 9002}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 351, col: 13, offset: 8621}, + pos: position{line: 371, col: 13, offset: 9002}, val: "[", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 351, col: 17, offset: 8625}, + pos: position{line: 371, col: 17, offset: 9006}, name: "__", }, &labeledExpr{ - pos: position{line: 351, col: 20, offset: 8628}, + pos: position{line: 371, col: 20, offset: 9009}, label: "values", expr: &zeroOrMoreExpr{ - pos: position{line: 351, col: 27, offset: 8635}, + pos: position{line: 371, col: 27, offset: 9016}, expr: &seqExpr{ - pos: position{line: 351, col: 28, offset: 8636}, + pos: position{line: 371, col: 28, offset: 9017}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 351, col: 28, offset: 8636}, + pos: position{line: 371, col: 28, offset: 9017}, name: "ConstValue", }, &ruleRefExpr{ - pos: position{line: 351, col: 39, offset: 8647}, + pos: position{line: 371, col: 39, offset: 9028}, name: "__", }, &zeroOrOneExpr{ - pos: position{line: 351, col: 42, offset: 8650}, + pos: position{line: 371, col: 42, offset: 9031}, expr: &ruleRefExpr{ - pos: position{line: 351, col: 42, offset: 8650}, + pos: position{line: 371, col: 42, offset: 9031}, name: "ListSeparator", }, }, &ruleRefExpr{ - pos: position{line: 351, col: 57, offset: 8665}, + pos: position{line: 371, col: 57, offset: 9046}, name: "__", }, }, @@ -1898,11 +1949,11 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 351, col: 62, offset: 8670}, + pos: position{line: 371, col: 62, offset: 9051}, name: "__", }, &litMatcher{ - pos: position{line: 351, col: 65, offset: 8673}, + pos: position{line: 371, col: 65, offset: 9054}, val: "]", ignoreCase: false, }, @@ -1912,67 +1963,70 @@ var g = &grammar{ }, { name: "ConstMap", - pos: position{line: 360, col: 1, offset: 8846}, + pos: position{line: 380, col: 1, offset: 9227}, expr: &actionExpr{ - pos: position{line: 360, col: 12, offset: 8859}, + pos: position{line: 380, col: 12, offset: 9240}, run: (*parser).callonConstMap1, expr: &seqExpr{ - pos: position{line: 360, col: 12, offset: 8859}, + pos: position{line: 380, col: 12, offset: 9240}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 360, col: 12, offset: 8859}, + pos: position{line: 380, col: 12, offset: 9240}, val: "{", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 360, col: 16, offset: 8863}, + pos: position{line: 380, col: 16, offset: 9244}, name: "__", }, &labeledExpr{ - pos: position{line: 360, col: 19, offset: 8866}, + pos: position{line: 380, col: 19, offset: 9247}, label: "values", expr: &zeroOrMoreExpr{ - pos: position{line: 360, col: 26, offset: 8873}, + pos: position{line: 380, col: 26, offset: 9254}, expr: &seqExpr{ - pos: position{line: 360, col: 27, offset: 8874}, + pos: position{line: 380, col: 27, offset: 9255}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 360, col: 27, offset: 8874}, + pos: position{line: 380, col: 27, offset: 9255}, name: "ConstValue", }, &ruleRefExpr{ - pos: position{line: 360, col: 38, offset: 8885}, + pos: position{line: 380, col: 38, offset: 9266}, name: "__", }, &litMatcher{ - pos: position{line: 360, col: 41, offset: 8888}, + pos: position{line: 380, col: 41, offset: 9269}, val: ":", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 360, col: 45, offset: 8892}, + pos: position{line: 380, col: 45, offset: 9273}, name: "__", }, &ruleRefExpr{ - pos: position{line: 360, col: 48, offset: 8895}, + pos: position{line: 380, col: 48, offset: 9276}, name: "ConstValue", }, &ruleRefExpr{ - pos: position{line: 360, col: 59, offset: 8906}, + pos: position{line: 380, col: 59, offset: 9287}, name: "__", }, &choiceExpr{ - pos: position{line: 360, col: 63, offset: 8910}, + pos: position{line: 380, col: 63, offset: 9291}, alternatives: []interface{}{ - &litMatcher{ - pos: position{line: 360, col: 63, offset: 8910}, - val: ",", - ignoreCase: false, + &zeroOrOneExpr{ + pos: position{line: 380, col: 63, offset: 9291}, + expr: &litMatcher{ + pos: position{line: 380, col: 63, offset: 9291}, + val: ",", + ignoreCase: false, + }, }, &andExpr{ - pos: position{line: 360, col: 69, offset: 8916}, + pos: position{line: 380, col: 70, offset: 9298}, expr: &litMatcher{ - pos: position{line: 360, col: 70, offset: 8917}, + pos: position{line: 380, col: 71, offset: 9299}, val: "}", ignoreCase: false, }, @@ -1980,7 +2034,7 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 360, col: 75, offset: 8922}, + pos: position{line: 380, col: 76, offset: 9304}, name: "__", }, }, @@ -1988,7 +2042,7 @@ var g = &grammar{ }, }, &litMatcher{ - pos: position{line: 360, col: 80, offset: 8927}, + pos: position{line: 380, col: 81, offset: 9309}, val: "}", ignoreCase: false, }, @@ -1998,33 +2052,33 @@ var g = &grammar{ }, { name: "Literal", - pos: position{line: 376, col: 1, offset: 9173}, + pos: position{line: 396, col: 1, offset: 9555}, expr: &actionExpr{ - pos: position{line: 376, col: 11, offset: 9185}, + pos: position{line: 396, col: 11, offset: 9567}, run: (*parser).callonLiteral1, expr: &choiceExpr{ - pos: position{line: 376, col: 12, offset: 9186}, + pos: position{line: 396, col: 12, offset: 9568}, alternatives: []interface{}{ &seqExpr{ - pos: position{line: 376, col: 13, offset: 9187}, + pos: position{line: 396, col: 13, offset: 9569}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 376, col: 13, offset: 9187}, + pos: position{line: 396, col: 13, offset: 9569}, val: "\"", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 376, col: 17, offset: 9191}, + pos: position{line: 396, col: 17, offset: 9573}, expr: &choiceExpr{ - pos: position{line: 376, col: 18, offset: 9192}, + pos: position{line: 396, col: 18, offset: 9574}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 376, col: 18, offset: 9192}, + pos: position{line: 396, col: 18, offset: 9574}, val: "\\\"", ignoreCase: false, }, &charClassMatcher{ - pos: position{line: 376, col: 25, offset: 9199}, + pos: position{line: 396, col: 25, offset: 9581}, val: "[^\"]", chars: []rune{'"'}, ignoreCase: false, @@ -2034,32 +2088,32 @@ var g = &grammar{ }, }, &litMatcher{ - pos: position{line: 376, col: 32, offset: 9206}, + pos: position{line: 396, col: 32, offset: 9588}, val: "\"", ignoreCase: false, }, }, }, &seqExpr{ - pos: position{line: 376, col: 40, offset: 9214}, + pos: position{line: 396, col: 40, offset: 9596}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 376, col: 40, offset: 9214}, + pos: position{line: 396, col: 40, offset: 9596}, val: "'", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 376, col: 45, offset: 9219}, + pos: position{line: 396, col: 45, offset: 9601}, expr: &choiceExpr{ - pos: position{line: 376, col: 46, offset: 9220}, + pos: position{line: 396, col: 46, offset: 9602}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 376, col: 46, offset: 9220}, + pos: position{line: 396, col: 46, offset: 9602}, val: "\\'", ignoreCase: false, }, &charClassMatcher{ - pos: position{line: 376, col: 53, offset: 9227}, + pos: position{line: 396, col: 53, offset: 9609}, val: "[^']", chars: []rune{'\''}, ignoreCase: false, @@ -2069,7 +2123,7 @@ var g = &grammar{ }, }, &litMatcher{ - pos: position{line: 376, col: 60, offset: 9234}, + pos: position{line: 396, col: 60, offset: 9616}, val: "'", ignoreCase: false, }, @@ -2081,24 +2135,24 @@ var g = &grammar{ }, { name: "Identifier", - pos: position{line: 383, col: 1, offset: 9435}, + pos: position{line: 403, col: 1, offset: 9817}, expr: &actionExpr{ - pos: position{line: 383, col: 14, offset: 9450}, + pos: position{line: 403, col: 14, offset: 9832}, run: (*parser).callonIdentifier1, expr: &seqExpr{ - pos: position{line: 383, col: 14, offset: 9450}, + pos: position{line: 403, col: 14, offset: 9832}, exprs: []interface{}{ &oneOrMoreExpr{ - pos: position{line: 383, col: 14, offset: 9450}, + pos: position{line: 403, col: 14, offset: 9832}, expr: &choiceExpr{ - pos: position{line: 383, col: 15, offset: 9451}, + pos: position{line: 403, col: 15, offset: 9833}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 383, col: 15, offset: 9451}, + pos: position{line: 403, col: 15, offset: 9833}, name: "Letter", }, &litMatcher{ - pos: position{line: 383, col: 24, offset: 9460}, + pos: position{line: 403, col: 24, offset: 9842}, val: "_", ignoreCase: false, }, @@ -2106,20 +2160,20 @@ var g = &grammar{ }, }, &zeroOrMoreExpr{ - pos: position{line: 383, col: 30, offset: 9466}, + pos: position{line: 403, col: 30, offset: 9848}, expr: &choiceExpr{ - pos: position{line: 383, col: 31, offset: 9467}, + pos: position{line: 403, col: 31, offset: 9849}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 383, col: 31, offset: 9467}, + pos: position{line: 403, col: 31, offset: 9849}, name: "Letter", }, &ruleRefExpr{ - pos: position{line: 383, col: 40, offset: 9476}, + pos: position{line: 403, col: 40, offset: 9858}, name: "Digit", }, &charClassMatcher{ - pos: position{line: 383, col: 48, offset: 9484}, + pos: position{line: 403, col: 48, offset: 9866}, val: "[._]", chars: []rune{'.', '_'}, ignoreCase: false, @@ -2134,9 +2188,9 @@ var g = &grammar{ }, { name: "ListSeparator", - pos: position{line: 387, col: 1, offset: 9536}, + pos: position{line: 407, col: 1, offset: 9918}, expr: &charClassMatcher{ - pos: position{line: 387, col: 17, offset: 9554}, + pos: position{line: 407, col: 17, offset: 9936}, val: "[,;]", chars: []rune{',', ';'}, ignoreCase: false, @@ -2145,9 +2199,9 @@ var g = &grammar{ }, { name: "Letter", - pos: position{line: 388, col: 1, offset: 9559}, + pos: position{line: 408, col: 1, offset: 9941}, expr: &charClassMatcher{ - pos: position{line: 388, col: 10, offset: 9570}, + pos: position{line: 408, col: 10, offset: 9952}, val: "[A-Za-z]", ranges: []rune{'A', 'Z', 'a', 'z'}, ignoreCase: false, @@ -2156,9 +2210,9 @@ var g = &grammar{ }, { name: "Digit", - pos: position{line: 389, col: 1, offset: 9579}, + pos: position{line: 409, col: 1, offset: 9961}, expr: &charClassMatcher{ - pos: position{line: 389, col: 9, offset: 9589}, + pos: position{line: 409, col: 9, offset: 9971}, val: "[0-9]", ranges: []rune{'0', '9'}, ignoreCase: false, @@ -2167,23 +2221,23 @@ var g = &grammar{ }, { name: "SourceChar", - pos: position{line: 393, col: 1, offset: 9600}, + pos: position{line: 413, col: 1, offset: 9982}, expr: &anyMatcher{ - line: 393, col: 14, offset: 9615, + line: 413, col: 14, offset: 9997, }, }, { name: "Comment", - pos: position{line: 394, col: 1, offset: 9617}, + pos: position{line: 414, col: 1, offset: 9999}, expr: &choiceExpr{ - pos: position{line: 394, col: 11, offset: 9629}, + pos: position{line: 414, col: 11, offset: 10011}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 394, col: 11, offset: 9629}, + pos: position{line: 414, col: 11, offset: 10011}, name: "MultiLineComment", }, &ruleRefExpr{ - pos: position{line: 394, col: 30, offset: 9648}, + pos: position{line: 414, col: 30, offset: 10030}, name: "SingleLineComment", }, }, @@ -2191,37 +2245,37 @@ var g = &grammar{ }, { name: "MultiLineComment", - pos: position{line: 395, col: 1, offset: 9666}, + pos: position{line: 415, col: 1, offset: 10048}, expr: &seqExpr{ - pos: position{line: 395, col: 20, offset: 9687}, + pos: position{line: 415, col: 20, offset: 10069}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 395, col: 20, offset: 9687}, + pos: position{line: 415, col: 20, offset: 10069}, val: "/*", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 395, col: 25, offset: 9692}, + pos: position{line: 415, col: 25, offset: 10074}, expr: &seqExpr{ - pos: position{line: 395, col: 27, offset: 9694}, + pos: position{line: 415, col: 27, offset: 10076}, exprs: []interface{}{ ¬Expr{ - pos: position{line: 395, col: 27, offset: 9694}, + pos: position{line: 415, col: 27, offset: 10076}, expr: &litMatcher{ - pos: position{line: 395, col: 28, offset: 9695}, + pos: position{line: 415, col: 28, offset: 10077}, val: "*/", ignoreCase: false, }, }, &ruleRefExpr{ - pos: position{line: 395, col: 33, offset: 9700}, + pos: position{line: 415, col: 33, offset: 10082}, name: "SourceChar", }, }, }, }, &litMatcher{ - pos: position{line: 395, col: 47, offset: 9714}, + pos: position{line: 415, col: 47, offset: 10096}, val: "*/", ignoreCase: false, }, @@ -2230,46 +2284,46 @@ var g = &grammar{ }, { name: "MultiLineCommentNoLineTerminator", - pos: position{line: 396, col: 1, offset: 9719}, + pos: position{line: 416, col: 1, offset: 10101}, expr: &seqExpr{ - pos: position{line: 396, col: 36, offset: 9756}, + pos: position{line: 416, col: 36, offset: 10138}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 396, col: 36, offset: 9756}, + pos: position{line: 416, col: 36, offset: 10138}, val: "/*", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 396, col: 41, offset: 9761}, + pos: position{line: 416, col: 41, offset: 10143}, expr: &seqExpr{ - pos: position{line: 396, col: 43, offset: 9763}, + pos: position{line: 416, col: 43, offset: 10145}, exprs: []interface{}{ ¬Expr{ - pos: position{line: 396, col: 43, offset: 9763}, + pos: position{line: 416, col: 43, offset: 10145}, expr: &choiceExpr{ - pos: position{line: 396, col: 46, offset: 9766}, + pos: position{line: 416, col: 46, offset: 10148}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 396, col: 46, offset: 9766}, + pos: position{line: 416, col: 46, offset: 10148}, val: "*/", ignoreCase: false, }, &ruleRefExpr{ - pos: position{line: 396, col: 53, offset: 9773}, + pos: position{line: 416, col: 53, offset: 10155}, name: "EOL", }, }, }, }, &ruleRefExpr{ - pos: position{line: 396, col: 59, offset: 9779}, + pos: position{line: 416, col: 59, offset: 10161}, name: "SourceChar", }, }, }, }, &litMatcher{ - pos: position{line: 396, col: 73, offset: 9793}, + pos: position{line: 416, col: 73, offset: 10175}, val: "*/", ignoreCase: false, }, @@ -2278,32 +2332,32 @@ var g = &grammar{ }, { name: "SingleLineComment", - pos: position{line: 397, col: 1, offset: 9798}, + pos: position{line: 417, col: 1, offset: 10180}, expr: &choiceExpr{ - pos: position{line: 397, col: 21, offset: 9820}, + pos: position{line: 417, col: 21, offset: 10202}, alternatives: []interface{}{ &seqExpr{ - pos: position{line: 397, col: 22, offset: 9821}, + pos: position{line: 417, col: 22, offset: 10203}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 397, col: 22, offset: 9821}, + pos: position{line: 417, col: 22, offset: 10203}, val: "//", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 397, col: 27, offset: 9826}, + pos: position{line: 417, col: 27, offset: 10208}, expr: &seqExpr{ - pos: position{line: 397, col: 29, offset: 9828}, + pos: position{line: 417, col: 29, offset: 10210}, exprs: []interface{}{ ¬Expr{ - pos: position{line: 397, col: 29, offset: 9828}, + pos: position{line: 417, col: 29, offset: 10210}, expr: &ruleRefExpr{ - pos: position{line: 397, col: 30, offset: 9829}, + pos: position{line: 417, col: 30, offset: 10211}, name: "EOL", }, }, &ruleRefExpr{ - pos: position{line: 397, col: 34, offset: 9833}, + pos: position{line: 417, col: 34, offset: 10215}, name: "SourceChar", }, }, @@ -2312,27 +2366,27 @@ var g = &grammar{ }, }, &seqExpr{ - pos: position{line: 397, col: 52, offset: 9851}, + pos: position{line: 417, col: 52, offset: 10233}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 397, col: 52, offset: 9851}, + pos: position{line: 417, col: 52, offset: 10233}, val: "#", ignoreCase: false, }, &zeroOrMoreExpr{ - pos: position{line: 397, col: 56, offset: 9855}, + pos: position{line: 417, col: 56, offset: 10237}, expr: &seqExpr{ - pos: position{line: 397, col: 58, offset: 9857}, + pos: position{line: 417, col: 58, offset: 10239}, exprs: []interface{}{ ¬Expr{ - pos: position{line: 397, col: 58, offset: 9857}, + pos: position{line: 417, col: 58, offset: 10239}, expr: &ruleRefExpr{ - pos: position{line: 397, col: 59, offset: 9858}, + pos: position{line: 417, col: 59, offset: 10240}, name: "EOL", }, }, &ruleRefExpr{ - pos: position{line: 397, col: 63, offset: 9862}, + pos: position{line: 417, col: 63, offset: 10244}, name: "SourceChar", }, }, @@ -2345,22 +2399,22 @@ var g = &grammar{ }, { name: "__", - pos: position{line: 399, col: 1, offset: 9878}, + pos: position{line: 419, col: 1, offset: 10260}, expr: &zeroOrMoreExpr{ - pos: position{line: 399, col: 6, offset: 9885}, + pos: position{line: 419, col: 6, offset: 10267}, expr: &choiceExpr{ - pos: position{line: 399, col: 8, offset: 9887}, + pos: position{line: 419, col: 8, offset: 10269}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 399, col: 8, offset: 9887}, + pos: position{line: 419, col: 8, offset: 10269}, name: "Whitespace", }, &ruleRefExpr{ - pos: position{line: 399, col: 21, offset: 9900}, + pos: position{line: 419, col: 21, offset: 10282}, name: "EOL", }, &ruleRefExpr{ - pos: position{line: 399, col: 27, offset: 9906}, + pos: position{line: 419, col: 27, offset: 10288}, name: "Comment", }, }, @@ -2369,18 +2423,18 @@ var g = &grammar{ }, { name: "_", - pos: position{line: 400, col: 1, offset: 9917}, + pos: position{line: 420, col: 1, offset: 10299}, expr: &zeroOrMoreExpr{ - pos: position{line: 400, col: 5, offset: 9923}, + pos: position{line: 420, col: 5, offset: 10305}, expr: &choiceExpr{ - pos: position{line: 400, col: 7, offset: 9925}, + pos: position{line: 420, col: 7, offset: 10307}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 400, col: 7, offset: 9925}, + pos: position{line: 420, col: 7, offset: 10307}, name: "Whitespace", }, &ruleRefExpr{ - pos: position{line: 400, col: 20, offset: 9938}, + pos: position{line: 420, col: 20, offset: 10320}, name: "MultiLineCommentNoLineTerminator", }, }, @@ -2389,20 +2443,20 @@ var g = &grammar{ }, { name: "WS", - pos: position{line: 401, col: 1, offset: 9974}, + pos: position{line: 421, col: 1, offset: 10356}, expr: &zeroOrMoreExpr{ - pos: position{line: 401, col: 6, offset: 9981}, + pos: position{line: 421, col: 6, offset: 10363}, expr: &ruleRefExpr{ - pos: position{line: 401, col: 6, offset: 9981}, + pos: position{line: 421, col: 6, offset: 10363}, name: "Whitespace", }, }, }, { name: "Whitespace", - pos: position{line: 403, col: 1, offset: 9994}, + pos: position{line: 423, col: 1, offset: 10376}, expr: &charClassMatcher{ - pos: position{line: 403, col: 14, offset: 10009}, + pos: position{line: 423, col: 14, offset: 10391}, val: "[ \\t\\r]", chars: []rune{' ', '\t', '\r'}, ignoreCase: false, @@ -2411,62 +2465,62 @@ var g = &grammar{ }, { name: "EOL", - pos: position{line: 404, col: 1, offset: 10017}, + pos: position{line: 424, col: 1, offset: 10399}, expr: &litMatcher{ - pos: position{line: 404, col: 7, offset: 10025}, + pos: position{line: 424, col: 7, offset: 10407}, val: "\n", ignoreCase: false, }, }, { name: "EOS", - pos: position{line: 405, col: 1, offset: 10030}, + pos: position{line: 425, col: 1, offset: 10412}, expr: &choiceExpr{ - pos: position{line: 405, col: 7, offset: 10038}, + pos: position{line: 425, col: 7, offset: 10420}, alternatives: []interface{}{ &seqExpr{ - pos: position{line: 405, col: 7, offset: 10038}, + pos: position{line: 425, col: 7, offset: 10420}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 405, col: 7, offset: 10038}, + pos: position{line: 425, col: 7, offset: 10420}, name: "__", }, &litMatcher{ - pos: position{line: 405, col: 10, offset: 10041}, + pos: position{line: 425, col: 10, offset: 10423}, val: ";", ignoreCase: false, }, }, }, &seqExpr{ - pos: position{line: 405, col: 16, offset: 10047}, + pos: position{line: 425, col: 16, offset: 10429}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 405, col: 16, offset: 10047}, + pos: position{line: 425, col: 16, offset: 10429}, name: "_", }, &zeroOrOneExpr{ - pos: position{line: 405, col: 18, offset: 10049}, + pos: position{line: 425, col: 18, offset: 10431}, expr: &ruleRefExpr{ - pos: position{line: 405, col: 18, offset: 10049}, + pos: position{line: 425, col: 18, offset: 10431}, name: "SingleLineComment", }, }, &ruleRefExpr{ - pos: position{line: 405, col: 37, offset: 10068}, + pos: position{line: 425, col: 37, offset: 10450}, name: "EOL", }, }, }, &seqExpr{ - pos: position{line: 405, col: 43, offset: 10074}, + pos: position{line: 425, col: 43, offset: 10456}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 405, col: 43, offset: 10074}, + pos: position{line: 425, col: 43, offset: 10456}, name: "__", }, &ruleRefExpr{ - pos: position{line: 405, col: 46, offset: 10077}, + pos: position{line: 425, col: 46, offset: 10459}, name: "EOF", }, }, @@ -2476,11 +2530,11 @@ var g = &grammar{ }, { name: "EOF", - pos: position{line: 407, col: 1, offset: 10082}, + pos: position{line: 427, col: 1, offset: 10464}, expr: ¬Expr{ - pos: position{line: 407, col: 7, offset: 10090}, + pos: position{line: 427, col: 7, offset: 10472}, expr: &anyMatcher{ - line: 407, col: 8, offset: 10091, + line: 427, col: 8, offset: 10473, }, }, }, @@ -2597,7 +2651,7 @@ func (c *current) onEnum1(name, values, annotations interface{}) (interface{}, e next := 0 for _, v := range vs { ev := v.([]interface{})[0].(*EnumValue) - if ev.Value < 0 { + if !ev.Set { ev.Value = next } if ev.Value >= next { @@ -2617,11 +2671,11 @@ func (p *parser) callonEnum1() (interface{}, error) { func (c *current) onEnumValue1(name, value, annotations interface{}) (interface{}, error) { ev := &EnumValue{ Name: string(name.(Identifier)), - Value: -1, Annotations: toAnnotations(annotations), } if value != nil { ev.Value = int(value.([]interface{})[2].(int64)) + ev.Set = true } return ev, nil } @@ -2696,8 +2750,15 @@ func (p *parser) callonStructLike1() (interface{}, error) { func (c *current) onFieldList1(fields interface{}) (interface{}, error) { fs := fields.([]interface{}) flds := make([]*Field, len(fs)) + ids := make(map[int]bool, len(fs)) for i, f := range fs { flds[i] = f.([]interface{})[0].(*Field) + + if ids[flds[i].ID] { + return nil, fmt.Errorf("multiple fields with the same identifier: %d", flds[i].ID) + } + + ids[flds[i].ID] = true } return flds, nil } @@ -2708,9 +2769,24 @@ func (p *parser) callonFieldList1() (interface{}, error) { return p.cur.onFieldList1(stack["fields"]) } +func (c *current) onFieldID1(id interface{}) (interface{}, error) { + return int(id.(int64)), nil +} + +func (p *parser) callonFieldID1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onFieldID1(stack["id"]) +} + func (c *current) onField1(id, req, typ, name, def, annotations interface{}) (interface{}, error) { + parsedID := -1 + if id != nil { + parsedID = id.(int) + } + f := &Field{ - ID: int(id.(int64)), + ID: parsedID, Name: string(name.(Identifier)), Type: typ.(*Type), Annotations: toAnnotations(annotations), @@ -2976,6 +3052,16 @@ func (p *parser) callonTypeAnnotation1() (interface{}, error) { return p.cur.onTypeAnnotation1(stack["name"], stack["value"]) } +func (c *current) onBoolConstant1() (interface{}, error) { + return string(c.text) == "true", nil +} + +func (p *parser) callonBoolConstant1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onBoolConstant1() +} + func (c *current) onIntConstant1() (interface{}, error) { return strconv.ParseInt(string(c.text), 10, 64) } diff --git a/parser/parser.go b/parser/parser.go index 5c86920..9572862 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -53,7 +53,10 @@ func (p *Parser) ParseFile(filename string) (map[string]*Thrift, string, error) if err != nil { return nil, "", err } - thrift, err := p.Parse(rd) + thrift, err := p.Parse(rd, func(pp *parser) Option { + pp.filename = path + return nil + }) if err != nil { return nil, "", err } diff --git a/parser/parser_test.go b/parser/parser_test.go index 1cd2859..bd735b6 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -191,10 +191,12 @@ func TestServiceParsing(t *testing.T) { "ADD": &EnumValue{ Name: "ADD", Value: 1, + Set: true, }, "SUBTRACT": &EnumValue{ Name: "SUBTRACT", Value: 2, + Set: true, }, }, } @@ -348,6 +350,7 @@ func TestParseEnumAnnotations(t *testing.T) { "TWO": &EnumValue{ Name: "TWO", Value: 2, + Set: true, Annotations: []*Annotation{{"a2", "v2"}}, }, "THREE": &EnumValue{ diff --git a/parser/types.go b/parser/types.go index e5d7937..4346ea8 100644 --- a/parser/types.go +++ b/parser/types.go @@ -23,6 +23,7 @@ type Typedef struct { type EnumValue struct { Name string Value int + Set bool Annotations []*Annotation } diff --git a/testfiles/generator/constantandenum.go b/testfiles/generator/constantandenum.go index 711b07d..a113057 100644 --- a/testfiles/generator/constantandenum.go +++ b/testfiles/generator/constantandenum.go @@ -9,6 +9,8 @@ import ( var _ = fmt.Sprintf +const Bf = false +const Bt = true const Fst = MyEnumFirst var Stringy = map[MyEnum]string{ @@ -60,3 +62,7 @@ func (e *MyEnum) UnmarshalJSON(b []byte) error { *e = MyEnum(i) return err } + +func (e MyEnum) Ptr() *MyEnum { + return &e +} diff --git a/testfiles/generator/constantandenum.thrift b/testfiles/generator/constantandenum.thrift index 9013729..dd41091 100644 --- a/testfiles/generator/constantandenum.thrift +++ b/testfiles/generator/constantandenum.thrift @@ -6,8 +6,11 @@ enum MyEnum { } const map STRINGY = { - MyEnum.FIRST: "1st", + MyEnum.FIRST: "1st" MyEnum.SECOND: "2nd", } const i32 Fst = MyEnum.FIRST; + +const bool Bt = true; +const bool Bf = false; diff --git a/testfiles/generator/nestedstruct.go b/testfiles/generator/nestedstruct.go index f8c0e6d..521aea7 100644 --- a/testfiles/generator/nestedstruct.go +++ b/testfiles/generator/nestedstruct.go @@ -12,8 +12,40 @@ type NestedColor struct { Rgb *Rgb `thrift:"1,required" json:"rgb"` } +func (n *NestedColor) GetRgb() (val Rgb) { + if n != nil && n.Rgb != nil { + return *n.Rgb + } + + return +} + type Rgb struct { Red *int32 `thrift:"1,required" json:"red"` Green *int32 `thrift:"2,required" json:"green"` Blue *int32 `thrift:"3,required" json:"blue"` } + +func (r *Rgb) GetRed() (val int32) { + if r != nil && r.Red != nil { + return *r.Red + } + + return +} + +func (r *Rgb) GetGreen() (val int32) { + if r != nil && r.Green != nil { + return *r.Green + } + + return +} + +func (r *Rgb) GetBlue() (val int32) { + if r != nil && r.Blue != nil { + return *r.Blue + } + + return +} diff --git a/testfiles/generator/rpc_stub.go b/testfiles/generator/rpc_stub.go new file mode 100644 index 0000000..bf1c0b4 --- /dev/null +++ b/testfiles/generator/rpc_stub.go @@ -0,0 +1,5 @@ +package gentest + +type RPCClient interface { + Call(method string, request interface{}, response interface{}) error +} diff --git a/testfiles/generator/scribe.go b/testfiles/generator/scribe.go new file mode 100644 index 0000000..b162f82 --- /dev/null +++ b/testfiles/generator/scribe.go @@ -0,0 +1,233 @@ +// This file is automatically generated. Do not modify. + +package gentest + +import ( + "fmt" + "strconv" +) + +var _ = fmt.Sprintf + +type ResultCode int32 + +const ( + ResultCodeOk ResultCode = 0 + ResultCodeTryLater ResultCode = 1 +) + +var ( + ResultCodeByName = map[string]ResultCode{ + "ResultCode.OK": ResultCodeOk, + "ResultCode.TRY_LATER": ResultCodeTryLater, + } + ResultCodeByValue = map[ResultCode]string{ + ResultCodeOk: "ResultCode.OK", + ResultCodeTryLater: "ResultCode.TRY_LATER", + } +) + +func (e ResultCode) String() string { + name := ResultCodeByValue[e] + if name == "" { + name = fmt.Sprintf("Unknown enum value ResultCode(%d)", e) + } + return name +} + +func (e ResultCode) MarshalJSON() ([]byte, error) { + name := ResultCodeByValue[e] + if name == "" { + name = strconv.Itoa(int(e)) + } + return []byte("\"" + name + "\""), nil +} + +func (e *ResultCode) UnmarshalJSON(b []byte) error { + st := string(b) + if st[0] == '"' { + *e = ResultCode(ResultCodeByName[st[1:len(st)-1]]) + return nil + } + i, err := strconv.Atoi(st) + *e = ResultCode(i) + return err +} + +func (e ResultCode) Ptr() *ResultCode { + return &e +} + +type LogEntry struct { + Category *string `thrift:"1,required" json:"category"` + Message *string `thrift:"2,required" json:"message"` +} + +func (l *LogEntry) GetCategory() (val string) { + if l != nil && l.Category != nil { + return *l.Category + } + + return +} + +func (l *LogEntry) GetMessage() (val string) { + if l != nil && l.Message != nil { + return *l.Message + } + + return +} + +type FailedException struct { + Reason *string `thrift:"1,required" json:"reason"` +} + +func (f *FailedException) GetReason() (val string) { + if f != nil && f.Reason != nil { + return *f.Reason + } + + return +} + +func (e FailedException) Error() string { + return fmt.Sprintf("FailedException{Reason: %+v}", e.GetReason()) +} + +type Scribe interface { + Echo(messages *LogEntry) (*LogEntry, error) + Log(messages []LogEntry) (*ResultCode, error) +} + +type ScribeServer struct { + Implementation Scribe +} + +func (s *ScribeServer) Echo(req *InternalRPCScribeEchoRequest, res *InternalRPCScribeEchoResponse) error { + val, err := s.Implementation.Echo(req.Messages) + switch e := err.(type) { + case *FailedException: + res.F = e + err = nil + } + res.Value = val + return err +} + +func (s *ScribeServer) Log(req *InternalRPCScribeLogRequest, res *InternalRPCScribeLogResponse) error { + val, err := s.Implementation.Log(req.Messages) + switch e := err.(type) { + case *FailedException: + res.F = e + err = nil + } + res.Value = val + return err +} + +type InternalRPCScribeEchoRequest struct { + Messages *LogEntry `thrift:"1,required" json:"messages"` +} + +func (i *InternalRPCScribeEchoRequest) GetMessages() (val LogEntry) { + if i != nil && i.Messages != nil { + return *i.Messages + } + + return +} + +type InternalRPCScribeEchoResponse struct { + Value *LogEntry `thrift:"0" json:"value,omitempty"` + F *FailedException `thrift:"1" json:"f,omitempty"` +} + +func (i *InternalRPCScribeEchoResponse) GetValue() (val LogEntry) { + if i != nil && i.Value != nil { + return *i.Value + } + + return +} + +func (i *InternalRPCScribeEchoResponse) GetF() (val FailedException) { + if i != nil && i.F != nil { + return *i.F + } + + return +} + +type InternalRPCScribeLogRequest struct { + Messages []LogEntry `thrift:"1,required" json:"messages"` +} + +func (i *InternalRPCScribeLogRequest) GetMessages() (val []LogEntry) { + if i != nil { + return i.Messages + } + + return +} + +type InternalRPCScribeLogResponse struct { + Value *ResultCode `thrift:"0" json:"value,omitempty"` + F *FailedException `thrift:"1" json:"f,omitempty"` +} + +func (i *InternalRPCScribeLogResponse) GetValue() (val ResultCode) { + if i != nil && i.Value != nil { + return *i.Value + } + + return +} + +func (i *InternalRPCScribeLogResponse) GetF() (val FailedException) { + if i != nil && i.F != nil { + return *i.F + } + + return +} + +type ScribeClient struct { + Client RPCClient +} + +func (s *ScribeClient) Echo(messages *LogEntry) (ret *LogEntry, err error) { + req := &InternalRPCScribeEchoRequest{ + Messages: messages, + } + res := &InternalRPCScribeEchoResponse{} + err = s.Client.Call("Echo", req, res) + if err == nil { + switch { + case res.F != nil: + err = res.F + } + } + if err == nil { + ret = res.Value + } + return +} + +func (s *ScribeClient) Log(messages []LogEntry) (ret *ResultCode, err error) { + req := &InternalRPCScribeLogRequest{ + Messages: messages, + } + res := &InternalRPCScribeLogResponse{} + err = s.Client.Call("Log", req, res) + if err == nil { + switch { + case res.F != nil: + err = res.F + } + } + if err == nil { + ret = res.Value + } + return +} diff --git a/testfiles/generator/scribe.thrift b/testfiles/generator/scribe.thrift new file mode 100644 index 0000000..bcf1e60 --- /dev/null +++ b/testfiles/generator/scribe.thrift @@ -0,0 +1,25 @@ +// super-stripped down scribe binary + +namespace go gentest + +enum ResultCode +{ + OK, + TRY_LATER +} + +struct LogEntry +{ + 1: string category, + 2: string message +} + +exception FailedException +{ + 1: string reason +} + +service scribe { + ResultCode Log(1: list messages) throws (1: FailedException f) + LogEntry Echo(1: LogEntry messages) throws (1: FailedException f) +} diff --git a/testfiles/generator/set.go b/testfiles/generator/set.go index 8cd8c02..fb53015 100644 --- a/testfiles/generator/set.go +++ b/testfiles/generator/set.go @@ -13,3 +13,27 @@ type StSet struct { I32Set map[int32]struct{} `thrift:"2,required" json:"i32_set"` BinarySet map[string]struct{} `thrift:"3,required" json:"binary_set"` } + +func (s *StSet) GetStringSet() (val map[string]struct{}) { + if s != nil { + return s.StringSet + } + + return +} + +func (s *StSet) GetI32Set() (val map[int32]struct{}) { + if s != nil { + return s.I32Set + } + + return +} + +func (s *StSet) GetBinarySet() (val map[string]struct{}) { + if s != nil { + return s.BinarySet + } + + return +} diff --git a/testfiles/generator/typedefs.go b/testfiles/generator/typedefs.go index d550b9f..86105ac 100644 --- a/testfiles/generator/typedefs.go +++ b/testfiles/generator/typedefs.go @@ -9,11 +9,43 @@ import ( var _ = fmt.Sprintf type Binary []byte + +func (e Binary) Ptr() *Binary { return &e } + type Int32 int32 + +func (e Int32) Ptr() *Int32 { return &e } + type String string +func (e String) Ptr() *String { return &e } + type St struct { B *Binary `thrift:"1,required" json:"b"` S *String `thrift:"2,required" json:"s"` I *Int32 `thrift:"3,required" json:"i"` } + +func (s *St) GetB() (val Binary) { + if s != nil && s.B != nil { + return *s.B + } + + return +} + +func (s *St) GetS() (val String) { + if s != nil && s.S != nil { + return *s.S + } + + return +} + +func (s *St) GetI() (val Int32) { + if s != nil && s.I != nil { + return *s.I + } + + return +} diff --git a/testfiles/generator/withFlags/go.signedbytes/bytes.go b/testfiles/generator/withFlags/go.signedbytes/bytes.go index 45f22cd..f9c9487 100644 --- a/testfiles/generator/withFlags/go.signedbytes/bytes.go +++ b/testfiles/generator/withFlags/go.signedbytes/bytes.go @@ -12,3 +12,19 @@ type ByteAndListByte struct { AByte int8 `thrift:"1,required" json:"a_byte"` AListByte []int8 `thrift:"2,required" json:"a_list_byte"` } + +func (b *ByteAndListByte) GetAByte() (val int8) { + if b != nil { + return b.AByte + } + + return +} + +func (b *ByteAndListByte) GetAListByte() (val []int8) { + if b != nil { + return b.AListByte + } + + return +} diff --git a/testfiles/generator/withFlags/go.signedbytes/rpc_stub.go b/testfiles/generator/withFlags/go.signedbytes/rpc_stub.go new file mode 100644 index 0000000..bf1c0b4 --- /dev/null +++ b/testfiles/generator/withFlags/go.signedbytes/rpc_stub.go @@ -0,0 +1,5 @@ +package gentest + +type RPCClient interface { + Call(method string, request interface{}, response interface{}) error +} diff --git a/testfiles/generator/withFlags/go.signedbytes/scribe.go b/testfiles/generator/withFlags/go.signedbytes/scribe.go new file mode 100644 index 0000000..b076889 --- /dev/null +++ b/testfiles/generator/withFlags/go.signedbytes/scribe.go @@ -0,0 +1,233 @@ +// This file is automatically generated. Do not modify. + +package gentest + +import ( + "fmt" + "strconv" +) + +var _ = fmt.Sprintf + +type ResultCode int32 + +const ( + ResultCodeOk ResultCode = 0 + ResultCodeTryLater ResultCode = 1 +) + +var ( + ResultCodeByName = map[string]ResultCode{ + "ResultCode.OK": ResultCodeOk, + "ResultCode.TRY_LATER": ResultCodeTryLater, + } + ResultCodeByValue = map[ResultCode]string{ + ResultCodeOk: "ResultCode.OK", + ResultCodeTryLater: "ResultCode.TRY_LATER", + } +) + +func (e ResultCode) String() string { + name := ResultCodeByValue[e] + if name == "" { + name = fmt.Sprintf("Unknown enum value ResultCode(%d)", e) + } + return name +} + +func (e ResultCode) MarshalJSON() ([]byte, error) { + name := ResultCodeByValue[e] + if name == "" { + name = strconv.Itoa(int(e)) + } + return []byte("\"" + name + "\""), nil +} + +func (e *ResultCode) UnmarshalJSON(b []byte) error { + st := string(b) + if st[0] == '"' { + *e = ResultCode(ResultCodeByName[st[1:len(st)-1]]) + return nil + } + i, err := strconv.Atoi(st) + *e = ResultCode(i) + return err +} + +func (e ResultCode) Ptr() *ResultCode { + return &e +} + +type LogEntry struct { + Category string `thrift:"1,required" json:"category"` + Message string `thrift:"2,required" json:"message"` +} + +func (l *LogEntry) GetCategory() (val string) { + if l != nil { + return l.Category + } + + return +} + +func (l *LogEntry) GetMessage() (val string) { + if l != nil { + return l.Message + } + + return +} + +type FailedException struct { + Reason string `thrift:"1,required" json:"reason"` +} + +func (f *FailedException) GetReason() (val string) { + if f != nil { + return f.Reason + } + + return +} + +func (e FailedException) Error() string { + return fmt.Sprintf("FailedException{Reason: %+v}", e.GetReason()) +} + +type Scribe interface { + Echo(messages LogEntry) (LogEntry, error) + Log(messages []LogEntry) (ResultCode, error) +} + +type ScribeServer struct { + Implementation Scribe +} + +func (s *ScribeServer) Echo(req *InternalRPCScribeEchoRequest, res *InternalRPCScribeEchoResponse) error { + val, err := s.Implementation.Echo(req.Messages) + switch e := err.(type) { + case *FailedException: + res.F = e + err = nil + } + res.Value = &val + return err +} + +func (s *ScribeServer) Log(req *InternalRPCScribeLogRequest, res *InternalRPCScribeLogResponse) error { + val, err := s.Implementation.Log(req.Messages) + switch e := err.(type) { + case *FailedException: + res.F = e + err = nil + } + res.Value = &val + return err +} + +type InternalRPCScribeEchoRequest struct { + Messages LogEntry `thrift:"1,required" json:"messages"` +} + +func (i *InternalRPCScribeEchoRequest) GetMessages() (val LogEntry) { + if i != nil { + return i.Messages + } + + return +} + +type InternalRPCScribeEchoResponse struct { + Value *LogEntry `thrift:"0" json:"value,omitempty"` + F *FailedException `thrift:"1" json:"f,omitempty"` +} + +func (i *InternalRPCScribeEchoResponse) GetValue() (val LogEntry) { + if i != nil && i.Value != nil { + return *i.Value + } + + return +} + +func (i *InternalRPCScribeEchoResponse) GetF() (val FailedException) { + if i != nil && i.F != nil { + return *i.F + } + + return +} + +type InternalRPCScribeLogRequest struct { + Messages []LogEntry `thrift:"1,required" json:"messages"` +} + +func (i *InternalRPCScribeLogRequest) GetMessages() (val []LogEntry) { + if i != nil { + return i.Messages + } + + return +} + +type InternalRPCScribeLogResponse struct { + Value *ResultCode `thrift:"0" json:"value,omitempty"` + F *FailedException `thrift:"1" json:"f,omitempty"` +} + +func (i *InternalRPCScribeLogResponse) GetValue() (val ResultCode) { + if i != nil && i.Value != nil { + return *i.Value + } + + return +} + +func (i *InternalRPCScribeLogResponse) GetF() (val FailedException) { + if i != nil && i.F != nil { + return *i.F + } + + return +} + +type ScribeClient struct { + Client RPCClient +} + +func (s *ScribeClient) Echo(messages LogEntry) (ret LogEntry, err error) { + req := &InternalRPCScribeEchoRequest{ + Messages: messages, + } + res := &InternalRPCScribeEchoResponse{} + err = s.Client.Call("Echo", req, res) + if err == nil { + switch { + case res.F != nil: + err = res.F + } + } + if err == nil && res.Value != nil { + ret = *res.Value + } + return +} + +func (s *ScribeClient) Log(messages []LogEntry) (ret ResultCode, err error) { + req := &InternalRPCScribeLogRequest{ + Messages: messages, + } + res := &InternalRPCScribeLogResponse{} + err = s.Client.Call("Log", req, res) + if err == nil { + switch { + case res.F != nil: + err = res.F + } + } + if err == nil && res.Value != nil { + ret = *res.Value + } + return +} diff --git a/testfiles/generator/withFlags/go.signedbytes/scribe.thrift b/testfiles/generator/withFlags/go.signedbytes/scribe.thrift new file mode 100644 index 0000000..bcf1e60 --- /dev/null +++ b/testfiles/generator/withFlags/go.signedbytes/scribe.thrift @@ -0,0 +1,25 @@ +// super-stripped down scribe binary + +namespace go gentest + +enum ResultCode +{ + OK, + TRY_LATER +} + +struct LogEntry +{ + 1: string category, + 2: string message +} + +exception FailedException +{ + 1: string reason +} + +service scribe { + ResultCode Log(1: list messages) throws (1: FailedException f) + LogEntry Echo(1: LogEntry messages) throws (1: FailedException f) +} diff --git a/testfiles/include/a/shared.thrift b/testfiles/include/a/shared.thrift index 4a188ce..a773268 100644 --- a/testfiles/include/a/shared.thrift +++ b/testfiles/include/a/shared.thrift @@ -1,5 +1,7 @@ include "../b/shared.thrift" +const string EXAMPLE_CONSTANT = "0" + struct AStruct { 1: shared.String s } diff --git a/testfiles/include_test.thrift b/testfiles/include_test.thrift index 0047d64..a1d14aa 100644 --- a/testfiles/include_test.thrift +++ b/testfiles/include_test.thrift @@ -2,5 +2,6 @@ include "./a/shared.thrift" struct S { 1: shared.AStruct s + 2: string c = shared.EXAMPLE_CONSTANT } diff --git a/thrift/decoder.go b/thrift/decoder.go index 3ccd88e..cab5b76 100644 --- a/thrift/decoder.go +++ b/thrift/decoder.go @@ -15,11 +15,16 @@ type Decoder interface { } type decoder struct { - r ProtocolReader + r ProtocolReader + enforceRequired bool } // DecodeStruct tries to deserialize a struct from a Thrift stream func DecodeStruct(r ProtocolReader, v interface{}) (err error) { + return DecodeStructWithStrictness(r, true, v) +} + +func DecodeStructWithStrictness(r ProtocolReader, enforceRequired bool, v interface{}) (err error) { if de, ok := v.(Decoder); ok { return de.DecodeThrift(r) } @@ -32,7 +37,7 @@ func DecodeStruct(r ProtocolReader, v interface{}) (err error) { err = r.(error) } }() - d := &decoder{r} + d := &decoder{r: r, enforceRequired: enforceRequired} vo := reflect.ValueOf(v) for vo.Kind() != reflect.Ptr { d.error(&UnsupportedValueError{Value: vo, Str: "pointer to struct expected"}) @@ -173,13 +178,15 @@ func (d *decoder) readValue(thriftType byte, rf reflect.Value) { d.error(err) } - if req != 0 { - for i := 0; req != 0; i, req = i+1, req>>1 { - if req&1 != 0 { - d.error(&MissingRequiredField{ - StructName: v.Type().Name(), - FieldName: meta.fields[i].name, - }) + if d.enforceRequired { + if req != 0 { + for i := 0; req != 0; i, req = i+1, req>>1 { + if req&1 != 0 { + d.error(&MissingRequiredField{ + StructName: v.Type().Name(), + FieldName: meta.fields[i].name, + }) + } } } } diff --git a/thrift/framed.go b/thrift/framed.go index 1a8997a..06e7cb4 100644 --- a/thrift/framed.go +++ b/thrift/framed.go @@ -78,6 +78,7 @@ func (f *FramedReadWriteCloser) fillBuffer() error { } frameSize := int64(binary.BigEndian.Uint32(f.rtmp)) if frameSize > f.maxFrameSize { + f.wbuf.Reset() return ErrFrameTooBig{frameSize, f.maxFrameSize} } f.limitedReader.N = frameSize @@ -97,6 +98,7 @@ func (f *FramedReadWriteCloser) Write(p []byte) (int, error) { return n, err } if ln := int64(f.wbuf.Len()); ln > f.maxFrameSize { + f.wbuf.Reset() return n, &ErrFrameTooBig{ln, f.maxFrameSize} } return n, nil diff --git a/thrift/protocol_binary.go b/thrift/protocol_binary.go index 5ba908e..bbd777b 100644 --- a/thrift/protocol_binary.go +++ b/thrift/protocol_binary.go @@ -6,6 +6,7 @@ package thrift import ( "encoding/binary" + "errors" "io" "math" ) @@ -277,6 +278,14 @@ func (p *binaryProtocolReader) ReadFieldEnd() error { return nil } +func (p *binaryProtocolReader) validateSize(sz int) bool { + if fr, ok := p.r.(*FramedReadWriteCloser); ok { + return sz <= fr.rbuf.Len() + } + + return true +} + func (p *binaryProtocolReader) ReadMapBegin() (keyType byte, valueType byte, size int, err error) { if keyType, err = p.ReadByte(); err != nil { return @@ -287,6 +296,10 @@ func (p *binaryProtocolReader) ReadMapBegin() (keyType byte, valueType byte, siz var sz int32 sz, err = p.ReadI32() size = int(sz) + + if !p.validateSize(size) { + err = errors.New("map is too large") + } return } @@ -301,6 +314,10 @@ func (p *binaryProtocolReader) ReadListBegin() (elementType byte, size int, err var sz int32 sz, err = p.ReadI32() size = int(sz) + + if !p.validateSize(size) { + err = errors.New("list is too large") + } return } diff --git a/thrift/server.go b/thrift/server.go index dc29d46..05ed18c 100644 --- a/thrift/server.go +++ b/thrift/server.go @@ -7,6 +7,7 @@ package thrift import ( "errors" "io" + "log" "net/rpc" "strings" "sync" @@ -78,7 +79,13 @@ func (c *serverCodec) ReadRequestBody(thriftStruct interface{}) error { return c.conn.ReadMessageEnd() } -func (c *serverCodec) WriteResponse(response *rpc.Response, thriftStruct interface{}) error { +func (c *serverCodec) WriteResponse(response *rpc.Response, thriftStruct interface{}) (err error) { + defer func() { + if err != nil { + log.Printf("thrift server error: %v", err) + } + }() + c.mu.Lock() methodName := c.methodName[response.Seq] delete(c.methodName, response.Seq) diff --git a/thrift/thrift.go b/thrift/thrift.go index 8a15f93..675693d 100644 --- a/thrift/thrift.go +++ b/thrift/thrift.go @@ -252,14 +252,15 @@ func encodeFields(t reflect.Type) structMeta { continue } id, opts := parseTag(tv) - if id >= 64 { - // TODO: figure out a better way to deal with this - panic("thrift: field id must be < 64") - } ef.id = id ef.name = f.Name ef.required = opts.Contains("required") if ef.required { + if id >= 64 { + // TODO: figure out a better way to deal with this + panic("thrift: field id must be < 64") + } + m.required |= 1 << byte(id) } ef.keepEmpty = opts.Contains("keepempty")