1package codegen
2
3import (
4 "fmt"
5 "go/types"
6 "strings"
7
8 "github.com/99designs/gqlgen/codegen/config"
9 "github.com/99designs/gqlgen/codegen/templates"
10 "github.com/pkg/errors"
11 "github.com/vektah/gqlparser/ast"
12)
13
14type ArgSet struct {
15 Args []*FieldArgument
16 FuncDecl string
17}
18
19type FieldArgument struct {
20 *ast.ArgumentDefinition
21 TypeReference *config.TypeReference
22 VarName string // The name of the var in go
23 Object *Object // A link back to the parent object
24 Default interface{} // The default value
25 Directives []*Directive
26 Value interface{} // value set in Data
27}
28
29//ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive
30func (f *FieldArgument) ImplDirectives() []*Directive {
31 d := make([]*Directive, 0)
32 for i := range f.Directives {
33 if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) {
34 d = append(d, f.Directives[i])
35 }
36 }
37
38 return d
39}
40
41func (f *FieldArgument) DirectiveObjName() string {
42 return "rawArgs"
43}
44
45func (f *FieldArgument) Stream() bool {
46 return f.Object != nil && f.Object.Stream
47}
48
49func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) {
50 tr, err := b.Binder.TypeReference(arg.Type, nil)
51 if err != nil {
52 return nil, err
53 }
54
55 argDirs, err := b.getDirectives(arg.Directives)
56 if err != nil {
57 return nil, err
58 }
59 newArg := FieldArgument{
60 ArgumentDefinition: arg,
61 TypeReference: tr,
62 Object: obj,
63 VarName: templates.ToGoPrivate(arg.Name),
64 Directives: argDirs,
65 }
66
67 if arg.DefaultValue != nil {
68 newArg.Default, err = arg.DefaultValue.Value(nil)
69 if err != nil {
70 return nil, errors.Errorf("default value is not valid: %s", err.Error())
71 }
72 }
73
74 return &newArg, nil
75}
76
77func (b *builder) bindArgs(field *Field, params *types.Tuple) error {
78 var newArgs []*FieldArgument
79
80nextArg:
81 for j := 0; j < params.Len(); j++ {
82 param := params.At(j)
83 for _, oldArg := range field.Args {
84 if strings.EqualFold(oldArg.Name, param.Name()) {
85 tr, err := b.Binder.TypeReference(oldArg.Type, param.Type())
86 if err != nil {
87 return err
88 }
89 oldArg.TypeReference = tr
90
91 newArgs = append(newArgs, oldArg)
92 continue nextArg
93 }
94 }
95
96 // no matching arg found, abort
97 return fmt.Errorf("arg %s not in schema", param.Name())
98 }
99
100 field.Args = newArgs
101 return nil
102}
103
104func (a *Data) Args() map[string][]*FieldArgument {
105 ret := map[string][]*FieldArgument{}
106 for _, o := range a.Objects {
107 for _, f := range o.Fields {
108 if len(f.Args) > 0 {
109 ret[f.ArgsFunc()] = f.Args
110 }
111 }
112 }
113
114 for _, d := range a.Directives {
115 if len(d.Args) > 0 {
116 ret[d.ArgsFunc()] = d.Args
117 }
118 }
119 return ret
120}