1package generator
2
3import (
4	"github.com/dave/jennifer/jen"
5	"github.com/graphql-go/graphql/language/ast"
6)
7
8//
9// Generates description for scalar type
10//
11// == Example input SDL
12//
13//   "Pets are the bestest family members"
14//   interface Pet {
15//     "name of this fine beast."
16//     name: String!
17//   }
18//
19// == Example output
20//
21//   // PetType - Pets are the bestest family members
22//   var PetType = graphql.NewType("Pet", graphql.InterfaceKind)
23//
24//   // RegisterPet registers Pet interface type with given service.
25//   func RegisterPet(svc graphql.Service, impl graphql.InterfaceTypeResolver) {
26//     svc.RegisterInterface(_InterfaceTypePetDesc, impl)
27//   }
28//
29//   // define configuration thunk
30//   func _InterfaceTypePetConfigFn() graphql.InterfaceConfig {
31//     return graphql.InterfaceConfig{
32//       Name:        "Pet",
33//       Description: "Pets are the bestest family members",
34//       Fields:      // ...
35//       ResolveType: func (_ ResolveTypeParams) string {
36//         panic("Unimplemented; see PetResolver.")
37//       },
38//     }
39//   }
40//
41//   // describe pet's configuration; kept private to avoid unintentional
42//   // tampering at runtime.
43//   var _InterfaceTypePetDesc = graphql.InterfaceDesc{
44//     Config: _InterfaceTypePetConfigFn,
45//   }
46//
47func genInterface(node *ast.InterfaceDefinition) jen.Code {
48	code := newGroup()
49	name := node.GetName().Value
50
51	// Type description
52	desc := getDescription(node)
53
54	// Ids
55	publicRefName := name + "Type"
56	publicRefComment := genTypeComment(publicRefName, desc)
57	privateConfigName := mkPrivateID(node, "Desc")
58	privateConfigThunkName := mkPrivateID(node, "ConfigFn")
59
60	//
61	// Generate public reference to type
62	//
63	// == Example output
64	//
65	//   // PetType - Pets are the bestest family members
66	//   var PetType = graphql.NewType("Pet", graphql.InterfaceKind)
67	//
68	code.Comment(publicRefComment)
69	code.
70		Var().Id(publicRefName).Op("=").
71		Qual(servicePkg, "NewType").
72		Call(jen.Lit(name), jen.Qual(servicePkg, "InterfaceKind"))
73
74	//
75	// Generate public func to register type with service
76	//
77	// == Example output
78	//
79	//   // RegisterPet registers Pet interface type with given service.
80	//   func RegisterPet(svc graphql.Service, impl graphql.InterfaceTypeResolver) {
81	//     svc.RegisterInterface(_InterfaceTypePetDesc, impl)
82	//   }
83	//
84
85	code.Add(
86		genRegisterFn(node, jen.Qual(servicePkg, "InterfaceTypeResolver")),
87	)
88
89	//
90	// Generates type config thunk
91	//
92	// == Example output
93	//
94	//   // define configuration thunk
95	//   func _InterfaceTypePetConfigFn() graphql.InterfaceConfig {
96	//     return graphql.InterfaceConfig{
97	//       Name:        "Pet",
98	//       Description: "Pets are the bestest family members",
99	//       Fields:      // ...
100	//       ResolveType: func (_ ResolveTypeParams) string {
101	//         panic("Unimplemented; see PetResolver.")
102	//       },
103	//     }
104	//   }
105	//
106	code.
107		Func().Id(privateConfigThunkName).
108		Params().Qual(defsPkg, "InterfaceConfig").
109		Block(
110			jen.Return(jen.Qual(defsPkg, "InterfaceConfig").Values(jen.Dict{
111				jen.Id("Name"):        jen.Lit(name),
112				jen.Id("Description"): jen.Lit(desc),
113				jen.Id("Fields"):      genFields(node.Fields),
114				jen.Id("ResolveType"): jen.Func().
115					Params(jen.Id("_").Qual(defsPkg, "ResolveTypeParams")).
116					Op("*").Qual(defsPkg, "Object").
117					Block(
118						jen.Comment(missingResolverNote),
119						jen.Panic(jen.Lit("Unimplemented; see InterfaceTypeResolver.")),
120					),
121			})),
122		)
123
124	//
125	// Generate type description
126	//
127	// == Example output
128	//
129	//   // ...
130	//   var _InterfaceTypePetDesc = graphql.InterfaceDesc{
131	//     Config: _InterfaceTypePetConfigFn,
132	//   }
133	//
134	code.Commentf(
135		`describe %s's configuration; kept private to avoid unintentional tampering of configuration at runtime.`,
136		name,
137	)
138	code.
139		Var().Id(privateConfigName).Op("=").
140		Qual(servicePkg, "InterfaceDesc").
141		Values(jen.Dict{
142			jen.Id("Config"): jen.Id(privateConfigThunkName),
143		})
144
145	return code
146}
147