in plugin/federation/federation.go [233:333]
func (f *Federation) GenerateCode(data *codegen.Data) error {
// requires imports
requiresImports := make(map[string]bool, 0)
requiresImports["context"] = true
requiresImports["fmt"] = true
requiresEntities := make(map[string]*Entity, 0)
// Save package options on f for template use
packageOptions, err := buildPackageOptions(data.Config)
if err != nil {
return fmt.Errorf("invalid federation package options: %w", err)
}
f.PackageOptions = packageOptions
if len(f.Entities) > 0 {
if data.Objects.ByName("Entity") != nil {
data.Objects.ByName("Entity").Root = true
}
for _, e := range f.Entities {
obj := data.Objects.ByName(e.Def.Name)
if e.Def.Kind == ast.Interface {
if len(data.Interfaces[e.Def.Name].Implementors) == 0 {
fmt.Println(
"skipping @key field on interface " + e.Def.Name + " as no types implement it",
)
continue
}
obj = data.Objects.ByName(data.Interfaces[e.Def.Name].Implementors[0].Name)
}
for _, r := range e.Resolvers {
populateKeyFieldTypes(r, obj, data.Objects, e.Def.Name)
}
// fill in types for requires fields
//
for _, reqField := range e.Requires {
if len(reqField.Field) == 0 {
fmt.Println("skipping @requires field " + reqField.Name + " in " + e.Def.Name)
continue
}
// keep track of which entities have requires
requiresEntities[e.Def.Name] = e
// make a proper import path
typeString := strings.Split(obj.Type.String(), ".")
requiresImports[strings.Join(typeString[:len(typeString)-1], ".")] = true
if containsUnionField(reqField) {
continue
}
cgField := reqField.Field.TypeReference(obj, data.Objects)
reqField.Type = cgField.TypeReference
}
// add type info to entity
e.Type = obj.Type
}
}
// fill in types for resolver inputs
//
for _, entity := range f.Entities {
if !entity.Multi {
continue
}
for _, resolver := range entity.Resolvers {
obj := data.Inputs.ByName(resolver.InputTypeName)
if obj == nil {
return fmt.Errorf("input object %s not found", resolver.InputTypeName)
}
resolver.InputType = obj.Type
}
}
if f.PackageOptions.ExplicitRequires && len(requiresEntities) > 0 {
err := f.generateExplicitRequires(
data,
requiresEntities,
requiresImports,
)
if err != nil {
return err
}
}
return templates.Render(templates.Options{
PackageName: data.Config.Federation.Package,
Filename: data.Config.Federation.Filename,
Data: struct {
Federation
UsePointers bool
}{*f, data.Config.ResolversAlwaysReturnPointers},
GeneratedHeader: true,
Packages: data.Config.Packages,
Template: federationTemplate,
})
}