From b3ce8f58cf02441e3f9cb739bc538731b9831437 Mon Sep 17 00:00:00 2001 From: lleadbetter Date: Fri, 22 Apr 2022 13:41:03 -0400 Subject: [PATCH 1/9] fed2 rough support --- api/generate.go | 2 +- api/option_test.go | 8 ++-- codegen/config/package.go | 1 + plugin/federation/federation.go | 57 +++++++++++++++++++------ plugin/federation/fedruntime/runtime.go | 3 ++ 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/api/generate.go b/api/generate.go index 6a85cd941ac..e82cecee811 100644 --- a/api/generate.go +++ b/api/generate.go @@ -24,7 +24,7 @@ func Generate(cfg *config.Config, option ...Option) error { } plugins = append(plugins, resolvergen.New()) if cfg.Federation.IsDefined() { - plugins = append([]plugin.Plugin{federation.New()}, plugins...) + plugins = append([]plugin.Plugin{federation.New(cfg.Federation.Version)}, plugins...) } for _, o := range option { diff --git a/api/option_test.go b/api/option_test.go index 11b13f30118..5819c4bdd07 100644 --- a/api/option_test.go +++ b/api/option_test.go @@ -26,7 +26,7 @@ func (t *testPlugin) MutateConfig(_ *config.Config) error { func TestReplacePlugin(t *testing.T) { t.Run("replace plugin if exists", func(t *testing.T) { pg := []plugin.Plugin{ - federation.New(), + federation.New(1), modelgen.New(), resolvergen.New(), } @@ -34,21 +34,21 @@ func TestReplacePlugin(t *testing.T) { expectedPlugin := &testPlugin{} ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) - require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, federation.New(1), pg[0]) require.EqualValues(t, expectedPlugin, pg[1]) require.EqualValues(t, resolvergen.New(), pg[2]) }) t.Run("add plugin if doesn't exist", func(t *testing.T) { pg := []plugin.Plugin{ - federation.New(), + federation.New(1), resolvergen.New(), } expectedPlugin := &testPlugin{} ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) - require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, federation.New(1), pg[0]) require.EqualValues(t, resolvergen.New(), pg[1]) require.EqualValues(t, expectedPlugin, pg[2]) }) diff --git a/codegen/config/package.go b/codegen/config/package.go index a9645938190..faacd1496f5 100644 --- a/codegen/config/package.go +++ b/codegen/config/package.go @@ -12,6 +12,7 @@ import ( type PackageConfig struct { Filename string `yaml:"filename,omitempty"` Package string `yaml:"package,omitempty"` + Version int `yaml:"version,omitempty"` } func (c *PackageConfig) ImportPath() string { diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index 55160bac512..c1f40e8f032 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -16,12 +16,17 @@ import ( type federation struct { Entities []*Entity + Version int } // New returns a federation plugin that injects // federated directives and types into the schema -func New() plugin.Plugin { - return &federation{} +func New(version int) plugin.Plugin { + if version == 0 { + version = 1 + } + + return &federation{Version: version} } // Name returns the plugin name @@ -51,6 +56,7 @@ func (f *federation) MutateConfig(cfg *config.Config) error { Model: config.StringList{"github.com/99designs/gqlgen/graphql.Map"}, }, } + for typeName, entry := range builtins { if cfg.Models.Exists(typeName) { return fmt.Errorf("%v already exists which must be reserved when Federation is enabled", typeName) @@ -63,22 +69,47 @@ func (f *federation) MutateConfig(cfg *config.Config) error { cfg.Directives["key"] = config.DirectiveConfig{SkipRuntime: true} cfg.Directives["extends"] = config.DirectiveConfig{SkipRuntime: true} + // Federation 2 specific directives + if f.Version == 2 { + cfg.Directives["shareable"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["link"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["tag"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["override"] = config.DirectiveConfig{SkipRuntime: true} + cfg.Directives["inaccessible"] = config.DirectiveConfig{SkipRuntime: true} + } + return nil } func (f *federation) InjectSourceEarly() *ast.Source { + input := ` + scalar _Any + scalar _FieldSet + + directive @external on FIELD_DEFINITION + directive @requires(fields: _FieldSet!) on FIELD_DEFINITION + directive @provides(fields: _FieldSet!) on FIELD_DEFINITION + directive @extends on OBJECT | INTERFACE +` + // add version-specific changes on key directive, as well as adding the new directives for federation 2 + if f.Version == 1 { + input += ` + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +` + } else if f.Version == 2 { + input += ` + scalar link__Import + directive @key(fields: _FieldSet!, resolvable: Boolean) repeatable on OBJECT | INTERFACE + directive @link(import: [link__Import], url: String!) repeatable on SCHEMA + directive @shareable on OBJECT | FIELD_DEFINITION + directive @tag repeatable on OBJECT | FIELD_DEFINITION | INTERFACE | UNION + directive @override(from: String!) on FIELD_DEFINITION + directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION +` + } return &ast.Source{ - Name: "federation/directives.graphql", - Input: ` -scalar _Any -scalar _FieldSet - -directive @external on FIELD_DEFINITION -directive @requires(fields: _FieldSet!) on FIELD_DEFINITION -directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE -directive @extends on OBJECT | INTERFACE -`, + Name: "federation/directives.graphql", + Input: input, BuiltIn: true, } } diff --git a/plugin/federation/fedruntime/runtime.go b/plugin/federation/fedruntime/runtime.go index 807bdf365be..e5e94001df5 100644 --- a/plugin/federation/fedruntime/runtime.go +++ b/plugin/federation/fedruntime/runtime.go @@ -11,3 +11,6 @@ type Service struct { type Entity interface { IsEntity() } + +// Used for the Link directive +type Link interface{} From 709a4ffe3c70643cd7b09f853b8420cf6019db46 Mon Sep 17 00:00:00 2001 From: lleadbetter Date: Fri, 22 Apr 2022 15:21:54 -0400 Subject: [PATCH 2/9] autodetection of fed2 --- api/generate.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/api/generate.go b/api/generate.go index e82cecee811..6619dd5cd2b 100644 --- a/api/generate.go +++ b/api/generate.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "regexp" "syscall" "github.com/99designs/gqlgen/codegen" @@ -24,6 +25,19 @@ func Generate(cfg *config.Config, option ...Option) error { } plugins = append(plugins, resolvergen.New()) if cfg.Federation.IsDefined() { + if cfg.Federation.Version == 0 { // default to using the user's choice of version, but if unset, try to sort out which federation version to use + urlRegex := regexp.MustCompile(`(?s)@link.*\(.*url:.*?"(.*?)"[^)]+\)`) // regex to grab the url of a link directive, should it exist + + // check the sources, and if one is marked as federation v2, we mark the entirety to be generated using that format + for _, v := range cfg.Sources { + cfg.Federation.Version = 1 + urlString := urlRegex.FindStringSubmatch(v.Input) + if urlString != nil && urlString[1] == "https://specs.apollo.dev/federation/v2.0" { + cfg.Federation.Version = 2 + break + } + } + } plugins = append([]plugin.Plugin{federation.New(cfg.Federation.Version)}, plugins...) } From 78255ed305458c1fe1c3b46ac29d955f439c73c8 Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Fri, 22 Apr 2022 15:56:20 -0400 Subject: [PATCH 3/9] adding basic tests for changes --- api/generate_test.go | 7 + api/testdata/federation2/gqlgen.yml | 56 ++++++ api/testdata/federation2/graph/model/doc.go | 1 + .../federation2/graph/schema.graphqls | 31 +++ plugin/federation/federation.go | 23 ++- plugin/federation/federation_test.go | 19 +- .../testdata/federation2/federation2.graphql | 16 ++ .../testdata/federation2/federation2.yml | 10 + .../federation2/generated/federation.go | 187 ++++++++++++++++++ 9 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 api/testdata/federation2/gqlgen.yml create mode 100644 api/testdata/federation2/graph/model/doc.go create mode 100644 api/testdata/federation2/graph/schema.graphqls create mode 100644 plugin/federation/testdata/federation2/federation2.graphql create mode 100644 plugin/federation/testdata/federation2/federation2.yml create mode 100644 plugin/federation/testdata/federation2/generated/federation.go diff --git a/api/generate_test.go b/api/generate_test.go index b23d981f127..417e6f3060c 100644 --- a/api/generate_test.go +++ b/api/generate_test.go @@ -34,6 +34,13 @@ func TestGenerate(t *testing.T) { }, wantErr: false, }, + { + name: "federation2", + args: args{ + workDir: path.Join(wd, "testdata", "federation2"), + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/api/testdata/federation2/gqlgen.yml b/api/testdata/federation2/gqlgen.yml new file mode 100644 index 00000000000..8dc5d538636 --- /dev/null +++ b/api/testdata/federation2/gqlgen.yml @@ -0,0 +1,56 @@ +# Where are all the schema files located? globs are supported eg src/**/*.graphqls +schema: + - graph/*.graphqls + +# Where should the generated server code go? +exec: + filename: graph/generated/generated.go + package: generated + +# Uncomment to enable federation +federation: + filename: graph/generated/federation.go + package: generated + +# Where should any generated models go? +model: + filename: graph/model/models_gen.go + package: model + +# Where should the resolver implementations go? +resolver: + layout: follow-schema + dir: graph + package: graph + +# Optional: turn on use `gqlgen:"fieldName"` tags in your models +# struct_tag: json + +# Optional: turn on to use []Thing instead of []*Thing +# omit_slice_element_pointers: false + +# Optional: set to speed up generation time by not performing a final validation pass. +# skip_validation: true + +# gqlgen will search for any type names in the schema in these go packages +# if they match it will use them, otherwise it will generate them. +autobind: + - "github.com/99designs/gqlgen/api/testdata/default/graph/model" + +# This section declares type mapping between the GraphQL and go type systems +# +# The first line in each type will be used as defaults for resolver arguments and +# modelgen, the others will be allowed when binding to fields. Configure them to +# your liking +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/api/testdata/federation2/graph/model/doc.go b/api/testdata/federation2/graph/model/doc.go new file mode 100644 index 00000000000..8b537907051 --- /dev/null +++ b/api/testdata/federation2/graph/model/doc.go @@ -0,0 +1 @@ +package model diff --git a/api/testdata/federation2/graph/schema.graphqls b/api/testdata/federation2/graph/schema.graphqls new file mode 100644 index 00000000000..8ecdde81c13 --- /dev/null +++ b/api/testdata/federation2/graph/schema.graphqls @@ -0,0 +1,31 @@ +# GraphQL schema example +# +# https://gqlgen.com/getting-started/ +extend schema + @link(url: "https://specs.apollo.dev/federation/v2.0", + import: ["@key", "@shareable", "@provides", "@external", "@tag", "@extends", "@override", "@inaccessible"]) + +type Todo { + id: ID! + text: String! + done: Boolean! + user: User! +} + +type User { + id: ID! + name: String! +} + +type Query { + todos: [Todo!]! +} + +input NewTodo { + text: String! + userId: String! +} + +type Mutation { + createTodo(input: NewTodo!): Todo! +} diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index c1f40e8f032..64f3361d5d5 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -57,6 +57,12 @@ func (f *federation) MutateConfig(cfg *config.Config) error { }, } + if f.Version == 2 { + builtins["link__Import"] = config.TypeMapEntry{ + Model: config.StringList{"github.com/99designs/gqlgen/fedruntime.Link"}, + } + } + for typeName, entry := range builtins { if cfg.Models.Exists(typeName) { return fmt.Errorf("%v already exists which must be reserved when Federation is enabled", typeName) @@ -321,10 +327,21 @@ func (f *federation) setEntities(schema *ast.Schema) { // } if !e.allFieldsAreExternal() { for _, dir := range keys { - if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" { - panic("Exactly one `fields` argument needed for @key declaration.") + if len(dir.Arguments) > 2 { + panic("More than two arguments provided for @key declaration.") + } + var arg *ast.Argument + + // since keys are able to now have multiple arguments, we need to check both possible for a possible @key(fields="" fields="") + for _, a := range dir.Arguments { + if a.Name == "fields" { + if arg != nil { + panic("More than one `fields` provided for @key declaration.") + } + arg = a + } } - arg := dir.Arguments[0] + keyFieldSet := fieldset.New(arg.Value.Raw, nil) keyFields := make([]*KeyField, len(keyFieldSet)) diff --git a/plugin/federation/federation_test.go b/plugin/federation/federation_test.go index ceb10b2322d..75fb462b8ca 100644 --- a/plugin/federation/federation_test.go +++ b/plugin/federation/federation_test.go @@ -116,6 +116,19 @@ func TestCodeGeneration(t *testing.T) { require.NoError(t, f.GenerateCode(data)) } +func TestCodeGenerationFederation2(t *testing.T) { + f, cfg := load(t, "testdata/federation2/federation2.yml") + err := f.MutateConfig(cfg) + + require.NoError(t, err) + + data, err := codegen.BuildData(cfg) + if err != nil { + panic(err) + } + require.NoError(t, f.GenerateCode(data)) +} + func TestInjectSourceLate(t *testing.T) { _, cfg := load(t, "testdata/allthethings/gqlgen.yml") entityGraphqlGenerated := false @@ -162,7 +175,11 @@ func load(t *testing.T, name string) (*federation, *config.Config) { cfg, err := config.LoadConfig(name) require.NoError(t, err) - f := &federation{} + if cfg.Federation.Version == 0 { + cfg.Federation.Version = 1 + } + + f := &federation{Version: cfg.Federation.Version} cfg.Sources = append(cfg.Sources, f.InjectSourceEarly()) require.NoError(t, cfg.LoadSchema()) diff --git a/plugin/federation/testdata/federation2/federation2.graphql b/plugin/federation/testdata/federation2/federation2.graphql new file mode 100644 index 00000000000..875a9b6289e --- /dev/null +++ b/plugin/federation/testdata/federation2/federation2.graphql @@ -0,0 +1,16 @@ +extend schema + @link(url: "https://specs.apollo.dev/federation/v2.0", + import: ["@key", "@shareable", "@provides", "@external", "@tag", "@extends", "@override", "@inaccessible"]) + +schema { + query: CustomQuery +} + +type Hello @key(fields:"name", resolvable: false) { + name: String! +} + +type CustomQuery { + hello: Hello! +} + diff --git a/plugin/federation/testdata/federation2/federation2.yml b/plugin/federation/testdata/federation2/federation2.yml new file mode 100644 index 00000000000..f43bdd383a1 --- /dev/null +++ b/plugin/federation/testdata/federation2/federation2.yml @@ -0,0 +1,10 @@ +schema: + - "testdata/federation2/federation2.graphql" +exec: + filename: testdata/federation2/generated/exec.go +federation: + filename: testdata/federation2/generated/federation.go + version: 2 + +autobind: + - "github.com/99designs/gqlgen/plugin/federation/test_data/model" diff --git a/plugin/federation/testdata/federation2/generated/federation.go b/plugin/federation/testdata/federation2/generated/federation.go new file mode 100644 index 00000000000..38e956b7c8c --- /dev/null +++ b/plugin/federation/testdata/federation2/generated/federation.go @@ -0,0 +1,187 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := map[string]struct { + i []int + r []map[string]interface{} + }{} + + // We group entities by typename so that we can parallelize their resolution. + // This is particularly helpful when there are entity groups in multi mode. + buildRepresentationGroups := func(reps []map[string]interface{}) { + for i, rep := range reps { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + _r := repsMap[typeName] + _r.i = append(_r.i, i) + _r.r = append(_r.r, rep) + repsMap[typeName] = _r + } + } + + isMulti := func(typeName string) bool { + switch typeName { + default: + return false + } + } + + resolveEntity := func(ctx context.Context, typeName string, rep map[string]interface{}, idx []int, i int) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Hello": + resolverName, err := entityResolverNameForHello(ctx, rep) + if err != nil { + return fmt.Errorf(`finding resolver for Entity "Hello": %w`, err) + } + switch resolverName { + + case "findHelloByName": + id0, err := ec.unmarshalNString2string(ctx, rep["name"]) + if err != nil { + return fmt.Errorf(`unmarshalling param 0 for findHelloByName(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindHelloByName(ctx, id0) + if err != nil { + return fmt.Errorf(`resolving Entity "Hello": %w`, err) + } + + list[idx[i]] = entity + return nil + } + + } + return fmt.Errorf("%w: %s", ErrUnknownType, typeName) + } + + resolveManyEntities := func(ctx context.Context, typeName string, reps []map[string]interface{}, idx []int) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } + } + + resolveEntityGroup := func(typeName string, reps []map[string]interface{}, idx []int) { + if isMulti(typeName) { + err := resolveManyEntities(ctx, typeName, reps, idx) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, typeName, rep, idx, i) + if err != nil { + ec.Error(ctx, err) + } + e.Done() + }(i, rep) + } + e.Wait() + } + } + buildRepresentationGroups(representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + resolveEntityGroup(typeName, reps.r, reps.i) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []map[string]interface{}, idx []int) { + resolveEntityGroup(typeName, reps, idx) + g.Done() + }(typeName, reps.r, reps.i) + } + g.Wait() + return list + } +} + +func entityResolverNameForHello(ctx context.Context, rep map[string]interface{}) (string, error) { + for { + var ( + m map[string]interface{} + val interface{} + ok bool + ) + _ = val + m = rep + if _, ok = m["name"]; !ok { + break + } + return "findHelloByName", nil + } + return "", fmt.Errorf("%w for Hello", ErrTypeNotFound) +} From fa7027d04b7604723cbd4b3797caf2c71a48c43d Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Fri, 22 Apr 2022 15:59:55 -0400 Subject: [PATCH 4/9] fixing docs --- docs/content/recipes/federation.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/content/recipes/federation.md b/docs/content/recipes/federation.md index 13349db92fd..68b1556d4a5 100644 --- a/docs/content/recipes/federation.md +++ b/docs/content/recipes/federation.md @@ -19,6 +19,16 @@ federation: package: generated ``` +### Federation 2 + +If you are using Apollo's Federation 2 standard, your schema should automatically be upgraded so long as you include the required `@link` directive within your schema. If you want to force Federation 2 composition, the `federation` configuration supports a `version` flag to override that. For example: + +```yml +federation: + filename: graph/generated/federation.go + package: generated +``` + ## Create the federated servers For each server to be federated we will create a new gqlgen project. From b7da6f1b9feaa8fb1cadd4f26b78e7454e86ab89 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Sat, 23 Apr 2022 18:14:51 -0400 Subject: [PATCH 5/9] Update plugin/federation/federation.go --- plugin/federation/federation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index 64f3361d5d5..5599925ad43 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -59,7 +59,7 @@ func (f *federation) MutateConfig(cfg *config.Config) error { if f.Version == 2 { builtins["link__Import"] = config.TypeMapEntry{ - Model: config.StringList{"github.com/99designs/gqlgen/fedruntime.Link"}, + Model: config.StringList{"github.com/99designs/gqlgen/plugin/federation/fedruntime.Link"}, } } From 77c45c53eba5102933e297b44b48cbe5705509a1 Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Mon, 25 Apr 2022 09:11:21 -0400 Subject: [PATCH 6/9] removing custom scalar since it was causing issues --- plugin/federation/federation.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index 5599925ad43..7f911a13825 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -57,12 +57,6 @@ func (f *federation) MutateConfig(cfg *config.Config) error { }, } - if f.Version == 2 { - builtins["link__Import"] = config.TypeMapEntry{ - Model: config.StringList{"github.com/99designs/gqlgen/plugin/federation/fedruntime.Link"}, - } - } - for typeName, entry := range builtins { if cfg.Models.Exists(typeName) { return fmt.Errorf("%v already exists which must be reserved when Federation is enabled", typeName) @@ -104,9 +98,8 @@ func (f *federation) InjectSourceEarly() *ast.Source { ` } else if f.Version == 2 { input += ` - scalar link__Import directive @key(fields: _FieldSet!, resolvable: Boolean) repeatable on OBJECT | INTERFACE - directive @link(import: [link__Import], url: String!) repeatable on SCHEMA + directive @link(import: [String!], url: String!) repeatable on SCHEMA directive @shareable on OBJECT | FIELD_DEFINITION directive @tag repeatable on OBJECT | FIELD_DEFINITION | INTERFACE | UNION directive @override(from: String!) on FIELD_DEFINITION From e67cae2c225dde2b2789012d29abb91d72745261 Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Mon, 25 Apr 2022 10:28:26 -0400 Subject: [PATCH 7/9] fixing lint test --- .../testdata/entityresolver/generated/exec.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plugin/federation/testdata/entityresolver/generated/exec.go b/plugin/federation/testdata/entityresolver/generated/exec.go index 27f6692dba4..3d4e7317c07 100644 --- a/plugin/federation/testdata/entityresolver/generated/exec.go +++ b/plugin/federation/testdata/entityresolver/generated/exec.go @@ -754,14 +754,15 @@ type MultiHelloMultipleRequires @key(fields: "name") @entityResolver(multi: true } `, BuiltIn: false}, {Name: "federation/directives.graphql", Input: ` -scalar _Any -scalar _FieldSet - -directive @external on FIELD_DEFINITION -directive @requires(fields: _FieldSet!) on FIELD_DEFINITION -directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE -directive @extends on OBJECT | INTERFACE + scalar _Any + scalar _FieldSet + + directive @external on FIELD_DEFINITION + directive @requires(fields: _FieldSet!) on FIELD_DEFINITION + directive @provides(fields: _FieldSet!) on FIELD_DEFINITION + directive @extends on OBJECT | INTERFACE + + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive From 3e3cccfdf64518b4cfad8bbb2e69d7da1f374dff Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Mon, 25 Apr 2022 11:36:14 -0400 Subject: [PATCH 8/9] should fix for real this time --- .../accounts/graph/generated/generated.go | 17 +- .../products/graph/generated/generated.go | 17 +- .../reviews/graph/generated/generated.go | 17 +- codegen/testserver/followschema/resolver.go | 458 ------------------ 4 files changed, 27 insertions(+), 482 deletions(-) delete mode 100644 codegen/testserver/followschema/resolver.go diff --git a/_examples/federation/accounts/graph/generated/generated.go b/_examples/federation/accounts/graph/generated/generated.go index 9c31d91220c..d82b661ffdb 100644 --- a/_examples/federation/accounts/graph/generated/generated.go +++ b/_examples/federation/accounts/graph/generated/generated.go @@ -262,14 +262,15 @@ type User @key(fields: "id") { } `, BuiltIn: false}, {Name: "federation/directives.graphql", Input: ` -scalar _Any -scalar _FieldSet - -directive @external on FIELD_DEFINITION -directive @requires(fields: _FieldSet!) on FIELD_DEFINITION -directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE -directive @extends on OBJECT | INTERFACE + scalar _Any + scalar _FieldSet + + directive @external on FIELD_DEFINITION + directive @requires(fields: _FieldSet!) on FIELD_DEFINITION + directive @provides(fields: _FieldSet!) on FIELD_DEFINITION + directive @extends on OBJECT | INTERFACE + + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive diff --git a/_examples/federation/products/graph/generated/generated.go b/_examples/federation/products/graph/generated/generated.go index 48809f42bb7..8d13bd22479 100644 --- a/_examples/federation/products/graph/generated/generated.go +++ b/_examples/federation/products/graph/generated/generated.go @@ -290,14 +290,15 @@ type Product @key(fields: "manufacturer { id } id") @key(fields: "upc") { } `, BuiltIn: false}, {Name: "federation/directives.graphql", Input: ` -scalar _Any -scalar _FieldSet - -directive @external on FIELD_DEFINITION -directive @requires(fields: _FieldSet!) on FIELD_DEFINITION -directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE -directive @extends on OBJECT | INTERFACE + scalar _Any + scalar _FieldSet + + directive @external on FIELD_DEFINITION + directive @requires(fields: _FieldSet!) on FIELD_DEFINITION + directive @provides(fields: _FieldSet!) on FIELD_DEFINITION + directive @extends on OBJECT | INTERFACE + + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive diff --git a/_examples/federation/reviews/graph/generated/generated.go b/_examples/federation/reviews/graph/generated/generated.go index 5d70a184879..7a6fb7b3cfa 100644 --- a/_examples/federation/reviews/graph/generated/generated.go +++ b/_examples/federation/reviews/graph/generated/generated.go @@ -322,14 +322,15 @@ extend type Product @key(fields: " manufacturer{ id} id") { } `, BuiltIn: false}, {Name: "federation/directives.graphql", Input: ` -scalar _Any -scalar _FieldSet - -directive @external on FIELD_DEFINITION -directive @requires(fields: _FieldSet!) on FIELD_DEFINITION -directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE -directive @extends on OBJECT | INTERFACE + scalar _Any + scalar _FieldSet + + directive @external on FIELD_DEFINITION + directive @requires(fields: _FieldSet!) on FIELD_DEFINITION + directive @provides(fields: _FieldSet!) on FIELD_DEFINITION + directive @extends on OBJECT | INTERFACE + + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive diff --git a/codegen/testserver/followschema/resolver.go b/codegen/testserver/followschema/resolver.go deleted file mode 100644 index 04d4f581be7..00000000000 --- a/codegen/testserver/followschema/resolver.go +++ /dev/null @@ -1,458 +0,0 @@ -package followschema - -// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. - -import ( - "context" - - introspection1 "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" - invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" - "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" -) - -type Resolver struct{} - -func (r *backedByInterfaceResolver) ID(ctx context.Context, obj BackedByInterface) (string, error) { - panic("not implemented") -} - -func (r *errorsResolver) A(ctx context.Context, obj *Errors) (*Error, error) { - panic("not implemented") -} - -func (r *errorsResolver) B(ctx context.Context, obj *Errors) (*Error, error) { - panic("not implemented") -} - -func (r *errorsResolver) C(ctx context.Context, obj *Errors) (*Error, error) { - panic("not implemented") -} - -func (r *errorsResolver) D(ctx context.Context, obj *Errors) (*Error, error) { - panic("not implemented") -} - -func (r *errorsResolver) E(ctx context.Context, obj *Errors) (*Error, error) { - panic("not implemented") -} - -func (r *forcedResolverResolver) Field(ctx context.Context, obj *ForcedResolver) (*Circle, error) { - panic("not implemented") -} - -func (r *modelMethodsResolver) ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) { - panic("not implemented") -} - -func (r *mutationResolver) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { - panic("not implemented") -} - -func (r *mutationResolver) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { - panic("not implemented") -} - -func (r *mutationResolver) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { - panic("not implemented") -} - -func (r *overlappingFieldsResolver) OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) { - panic("not implemented") -} - -func (r *panicsResolver) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { - panic("not implemented") -} - -func (r *panicsResolver) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { - panic("not implemented") -} - -func (r *petResolver) Friends(ctx context.Context, obj *Pet, limit *int) ([]*Pet, error) { - panic("not implemented") -} - -func (r *primitiveResolver) Value(ctx context.Context, obj *Primitive) (int, error) { - panic("not implemented") -} - -func (r *primitiveStringResolver) Value(ctx context.Context, obj *PrimitiveString) (string, error) { - panic("not implemented") -} - -func (r *primitiveStringResolver) Len(ctx context.Context, obj *PrimitiveString) (int, error) { - panic("not implemented") -} - -func (r *queryResolver) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { - panic("not implemented") -} - -func (r *queryResolver) Collision(ctx context.Context) (*introspection1.It, error) { - panic("not implemented") -} - -func (r *queryResolver) MapInput(ctx context.Context, input map[string]interface{}) (*bool, error) { - panic("not implemented") -} - -func (r *queryResolver) Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) { - panic("not implemented") -} - -func (r *queryResolver) NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) { - panic("not implemented") -} - -func (r *queryResolver) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { - panic("not implemented") -} - -func (r *queryResolver) ModelMethods(ctx context.Context) (*ModelMethods, error) { - panic("not implemented") -} - -func (r *queryResolver) User(ctx context.Context, id int) (*User, error) { - panic("not implemented") -} - -func (r *queryResolver) NullableArg(ctx context.Context, arg *int) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) InputSlice(ctx context.Context, arg []string) (bool, error) { - panic("not implemented") -} - -func (r *queryResolver) InputNullableSlice(ctx context.Context, arg []string) (bool, error) { - panic("not implemented") -} - -func (r *queryResolver) ShapeUnion(ctx context.Context) (ShapeUnion, error) { - panic("not implemented") -} - -func (r *queryResolver) Autobind(ctx context.Context) (*Autobind, error) { - panic("not implemented") -} - -func (r *queryResolver) DeprecatedField(ctx context.Context) (string, error) { - panic("not implemented") -} - -func (r *queryResolver) Overlapping(ctx context.Context) (*OverlappingFields, error) { - panic("not implemented") -} - -func (r *queryResolver) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveArg(ctx context.Context, arg string) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveInputType(ctx context.Context, arg InnerInput) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveObject(ctx context.Context) (*ObjectDirectives, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveObjectWithCustomGoModel(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveFieldDef(ctx context.Context, ret string) (string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveField(ctx context.Context) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveDouble(ctx context.Context) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) DirectiveUnimplemented(ctx context.Context) (*string, error) { - panic("not implemented") -} - -func (r *queryResolver) EmbeddedCase1(ctx context.Context) (*EmbeddedCase1, error) { - panic("not implemented") -} - -func (r *queryResolver) EmbeddedCase2(ctx context.Context) (*EmbeddedCase2, error) { - panic("not implemented") -} - -func (r *queryResolver) EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) { - panic("not implemented") -} - -func (r *queryResolver) EnumInInput(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) { - panic("not implemented") -} - -func (r *queryResolver) Shapes(ctx context.Context) ([]Shape, error) { - panic("not implemented") -} - -func (r *queryResolver) NoShape(ctx context.Context) (Shape, error) { - panic("not implemented") -} - -func (r *queryResolver) Node(ctx context.Context) (Node, error) { - panic("not implemented") -} - -func (r *queryResolver) NoShapeTypedNil(ctx context.Context) (Shape, error) { - panic("not implemented") -} - -func (r *queryResolver) Animal(ctx context.Context) (Animal, error) { - panic("not implemented") -} - -func (r *queryResolver) NotAnInterface(ctx context.Context) (BackedByInterface, error) { - panic("not implemented") -} - -func (r *queryResolver) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { - panic("not implemented") -} - -func (r *queryResolver) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { - panic("not implemented") -} - -func (r *queryResolver) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) { - panic("not implemented") -} - -func (r *queryResolver) ErrorBubble(ctx context.Context) (*Error, error) { - panic("not implemented") -} - -func (r *queryResolver) ErrorBubbleList(ctx context.Context) ([]*Error, error) { - panic("not implemented") -} - -func (r *queryResolver) ErrorList(ctx context.Context) ([]*Error, error) { - panic("not implemented") -} - -func (r *queryResolver) Errors(ctx context.Context) (*Errors, error) { - panic("not implemented") -} - -func (r *queryResolver) Valid(ctx context.Context) (string, error) { - panic("not implemented") -} - -func (r *queryResolver) Panics(ctx context.Context) (*Panics, error) { - panic("not implemented") -} - -func (r *queryResolver) PrimitiveObject(ctx context.Context) ([]Primitive, error) { - panic("not implemented") -} - -func (r *queryResolver) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) { - panic("not implemented") -} - -func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { - panic("not implemented") -} - -func (r *queryResolver) Infinity(ctx context.Context) (float64, error) { - panic("not implemented") -} - -func (r *queryResolver) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { - panic("not implemented") -} - -func (r *queryResolver) StringFromContextFunction(ctx context.Context) (string, error) { - panic("not implemented") -} - -func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { - panic("not implemented") -} - -func (r *queryResolver) Slices(ctx context.Context) (*Slices, error) { - panic("not implemented") -} - -func (r *queryResolver) ScalarSlice(ctx context.Context) ([]byte, error) { - panic("not implemented") -} - -func (r *queryResolver) Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) { - panic("not implemented") -} - -func (r *queryResolver) OptionalUnion(ctx context.Context) (TestUnion, error) { - panic("not implemented") -} - -func (r *queryResolver) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { - panic("not implemented") -} - -func (r *queryResolver) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { - panic("not implemented") -} - -func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { - panic("not implemented") -} - -func (r *queryResolver) VariadicModel(ctx context.Context) (*VariadicModel, error) { - panic("not implemented") -} - -func (r *queryResolver) WrappedStruct(ctx context.Context) (*WrappedStruct, error) { - panic("not implemented") -} - -func (r *queryResolver) WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) { - panic("not implemented") -} - -func (r *queryResolver) WrappedMap(ctx context.Context) (WrappedMap, error) { - panic("not implemented") -} - -func (r *queryResolver) WrappedSlice(ctx context.Context) (WrappedSlice, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) Updated(ctx context.Context) (<-chan string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) InitPayload(ctx context.Context) (<-chan string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) DirectiveArg(ctx context.Context, arg string) (<-chan *string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) DirectiveDouble(ctx context.Context) (<-chan *string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { - panic("not implemented") -} - -func (r *subscriptionResolver) ErrorRequired(ctx context.Context) (<-chan *Error, error) { - panic("not implemented") -} - -func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { - panic("not implemented") -} - -func (r *userResolver) Pets(ctx context.Context, obj *User, limit *int) ([]*Pet, error) { - panic("not implemented") -} - -func (r *wrappedMapResolver) Get(ctx context.Context, obj WrappedMap, key string) (string, error) { - panic("not implemented") -} - -func (r *wrappedSliceResolver) Get(ctx context.Context, obj WrappedSlice, idx int) (string, error) { - panic("not implemented") -} - -// BackedByInterface returns BackedByInterfaceResolver implementation. -func (r *Resolver) BackedByInterface() BackedByInterfaceResolver { - return &backedByInterfaceResolver{r} -} - -// Errors returns ErrorsResolver implementation. -func (r *Resolver) Errors() ErrorsResolver { return &errorsResolver{r} } - -// ForcedResolver returns ForcedResolverResolver implementation. -func (r *Resolver) ForcedResolver() ForcedResolverResolver { return &forcedResolverResolver{r} } - -// ModelMethods returns ModelMethodsResolver implementation. -func (r *Resolver) ModelMethods() ModelMethodsResolver { return &modelMethodsResolver{r} } - -// Mutation returns MutationResolver implementation. -func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} } - -// OverlappingFields returns OverlappingFieldsResolver implementation. -func (r *Resolver) OverlappingFields() OverlappingFieldsResolver { - return &overlappingFieldsResolver{r} -} - -// Panics returns PanicsResolver implementation. -func (r *Resolver) Panics() PanicsResolver { return &panicsResolver{r} } - -// Pet returns PetResolver implementation. -func (r *Resolver) Pet() PetResolver { return &petResolver{r} } - -// Primitive returns PrimitiveResolver implementation. -func (r *Resolver) Primitive() PrimitiveResolver { return &primitiveResolver{r} } - -// PrimitiveString returns PrimitiveStringResolver implementation. -func (r *Resolver) PrimitiveString() PrimitiveStringResolver { return &primitiveStringResolver{r} } - -// Query returns QueryResolver implementation. -func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } - -// Subscription returns SubscriptionResolver implementation. -func (r *Resolver) Subscription() SubscriptionResolver { return &subscriptionResolver{r} } - -// User returns UserResolver implementation. -func (r *Resolver) User() UserResolver { return &userResolver{r} } - -// WrappedMap returns WrappedMapResolver implementation. -func (r *Resolver) WrappedMap() WrappedMapResolver { return &wrappedMapResolver{r} } - -// WrappedSlice returns WrappedSliceResolver implementation. -func (r *Resolver) WrappedSlice() WrappedSliceResolver { return &wrappedSliceResolver{r} } - -type backedByInterfaceResolver struct{ *Resolver } -type errorsResolver struct{ *Resolver } -type forcedResolverResolver struct{ *Resolver } -type modelMethodsResolver struct{ *Resolver } -type mutationResolver struct{ *Resolver } -type overlappingFieldsResolver struct{ *Resolver } -type panicsResolver struct{ *Resolver } -type petResolver struct{ *Resolver } -type primitiveResolver struct{ *Resolver } -type primitiveStringResolver struct{ *Resolver } -type queryResolver struct{ *Resolver } -type subscriptionResolver struct{ *Resolver } -type userResolver struct{ *Resolver } -type wrappedMapResolver struct{ *Resolver } -type wrappedSliceResolver struct{ *Resolver } From 6fbe6f17f117dc35c649ecaed752209ecc3424dd Mon Sep 17 00:00:00 2001 From: Lucas Leadbetter Date: Mon, 25 Apr 2022 13:50:16 -0400 Subject: [PATCH 9/9] fixing test failures --- codegen/testserver/followschema/resolver.go | 458 ++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 codegen/testserver/followschema/resolver.go diff --git a/codegen/testserver/followschema/resolver.go b/codegen/testserver/followschema/resolver.go new file mode 100644 index 00000000000..04d4f581be7 --- /dev/null +++ b/codegen/testserver/followschema/resolver.go @@ -0,0 +1,458 @@ +package followschema + +// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. + +import ( + "context" + + introspection1 "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" +) + +type Resolver struct{} + +func (r *backedByInterfaceResolver) ID(ctx context.Context, obj BackedByInterface) (string, error) { + panic("not implemented") +} + +func (r *errorsResolver) A(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) B(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) C(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) D(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) E(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *forcedResolverResolver) Field(ctx context.Context, obj *ForcedResolver) (*Circle, error) { + panic("not implemented") +} + +func (r *modelMethodsResolver) ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) { + panic("not implemented") +} + +func (r *mutationResolver) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { + panic("not implemented") +} + +func (r *mutationResolver) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { + panic("not implemented") +} + +func (r *mutationResolver) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { + panic("not implemented") +} + +func (r *overlappingFieldsResolver) OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) { + panic("not implemented") +} + +func (r *panicsResolver) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { + panic("not implemented") +} + +func (r *panicsResolver) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { + panic("not implemented") +} + +func (r *petResolver) Friends(ctx context.Context, obj *Pet, limit *int) ([]*Pet, error) { + panic("not implemented") +} + +func (r *primitiveResolver) Value(ctx context.Context, obj *Primitive) (int, error) { + panic("not implemented") +} + +func (r *primitiveStringResolver) Value(ctx context.Context, obj *PrimitiveString) (string, error) { + panic("not implemented") +} + +func (r *primitiveStringResolver) Len(ctx context.Context, obj *PrimitiveString) (int, error) { + panic("not implemented") +} + +func (r *queryResolver) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { + panic("not implemented") +} + +func (r *queryResolver) Collision(ctx context.Context) (*introspection1.It, error) { + panic("not implemented") +} + +func (r *queryResolver) MapInput(ctx context.Context, input map[string]interface{}) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { + panic("not implemented") +} + +func (r *queryResolver) ModelMethods(ctx context.Context) (*ModelMethods, error) { + panic("not implemented") +} + +func (r *queryResolver) User(ctx context.Context, id int) (*User, error) { + panic("not implemented") +} + +func (r *queryResolver) NullableArg(ctx context.Context, arg *int) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) InputSlice(ctx context.Context, arg []string) (bool, error) { + panic("not implemented") +} + +func (r *queryResolver) InputNullableSlice(ctx context.Context, arg []string) (bool, error) { + panic("not implemented") +} + +func (r *queryResolver) ShapeUnion(ctx context.Context) (ShapeUnion, error) { + panic("not implemented") +} + +func (r *queryResolver) Autobind(ctx context.Context) (*Autobind, error) { + panic("not implemented") +} + +func (r *queryResolver) DeprecatedField(ctx context.Context) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Overlapping(ctx context.Context) (*OverlappingFields, error) { + panic("not implemented") +} + +func (r *queryResolver) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveArg(ctx context.Context, arg string) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInputType(ctx context.Context, arg InnerInput) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveObject(ctx context.Context) (*ObjectDirectives, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveObjectWithCustomGoModel(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveFieldDef(ctx context.Context, ret string) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveField(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveDouble(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveUnimplemented(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase1(ctx context.Context) (*EmbeddedCase1, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase2(ctx context.Context) (*EmbeddedCase2, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) { + panic("not implemented") +} + +func (r *queryResolver) EnumInInput(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) { + panic("not implemented") +} + +func (r *queryResolver) Shapes(ctx context.Context) ([]Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) NoShape(ctx context.Context) (Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) Node(ctx context.Context) (Node, error) { + panic("not implemented") +} + +func (r *queryResolver) NoShapeTypedNil(ctx context.Context) (Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) Animal(ctx context.Context) (Animal, error) { + panic("not implemented") +} + +func (r *queryResolver) NotAnInterface(ctx context.Context) (BackedByInterface, error) { + panic("not implemented") +} + +func (r *queryResolver) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { + panic("not implemented") +} + +func (r *queryResolver) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { + panic("not implemented") +} + +func (r *queryResolver) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorBubble(ctx context.Context) (*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorBubbleList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) Errors(ctx context.Context) (*Errors, error) { + panic("not implemented") +} + +func (r *queryResolver) Valid(ctx context.Context) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Panics(ctx context.Context) (*Panics, error) { + panic("not implemented") +} + +func (r *queryResolver) PrimitiveObject(ctx context.Context) ([]Primitive, error) { + panic("not implemented") +} + +func (r *queryResolver) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) { + panic("not implemented") +} + +func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { + panic("not implemented") +} + +func (r *queryResolver) Infinity(ctx context.Context) (float64, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextFunction(ctx context.Context) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Slices(ctx context.Context) (*Slices, error) { + panic("not implemented") +} + +func (r *queryResolver) ScalarSlice(ctx context.Context) ([]byte, error) { + panic("not implemented") +} + +func (r *queryResolver) Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) { + panic("not implemented") +} + +func (r *queryResolver) OptionalUnion(ctx context.Context) (TestUnion, error) { + panic("not implemented") +} + +func (r *queryResolver) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { + panic("not implemented") +} + +func (r *queryResolver) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { + panic("not implemented") +} + +func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { + panic("not implemented") +} + +func (r *queryResolver) VariadicModel(ctx context.Context) (*VariadicModel, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedStruct(ctx context.Context) (*WrappedStruct, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedMap(ctx context.Context) (WrappedMap, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedSlice(ctx context.Context) (WrappedSlice, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) Updated(ctx context.Context) (<-chan string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) InitPayload(ctx context.Context) (<-chan string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveArg(ctx context.Context, arg string) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveDouble(ctx context.Context) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) ErrorRequired(ctx context.Context) (<-chan *Error, error) { + panic("not implemented") +} + +func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { + panic("not implemented") +} + +func (r *userResolver) Pets(ctx context.Context, obj *User, limit *int) ([]*Pet, error) { + panic("not implemented") +} + +func (r *wrappedMapResolver) Get(ctx context.Context, obj WrappedMap, key string) (string, error) { + panic("not implemented") +} + +func (r *wrappedSliceResolver) Get(ctx context.Context, obj WrappedSlice, idx int) (string, error) { + panic("not implemented") +} + +// BackedByInterface returns BackedByInterfaceResolver implementation. +func (r *Resolver) BackedByInterface() BackedByInterfaceResolver { + return &backedByInterfaceResolver{r} +} + +// Errors returns ErrorsResolver implementation. +func (r *Resolver) Errors() ErrorsResolver { return &errorsResolver{r} } + +// ForcedResolver returns ForcedResolverResolver implementation. +func (r *Resolver) ForcedResolver() ForcedResolverResolver { return &forcedResolverResolver{r} } + +// ModelMethods returns ModelMethodsResolver implementation. +func (r *Resolver) ModelMethods() ModelMethodsResolver { return &modelMethodsResolver{r} } + +// Mutation returns MutationResolver implementation. +func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} } + +// OverlappingFields returns OverlappingFieldsResolver implementation. +func (r *Resolver) OverlappingFields() OverlappingFieldsResolver { + return &overlappingFieldsResolver{r} +} + +// Panics returns PanicsResolver implementation. +func (r *Resolver) Panics() PanicsResolver { return &panicsResolver{r} } + +// Pet returns PetResolver implementation. +func (r *Resolver) Pet() PetResolver { return &petResolver{r} } + +// Primitive returns PrimitiveResolver implementation. +func (r *Resolver) Primitive() PrimitiveResolver { return &primitiveResolver{r} } + +// PrimitiveString returns PrimitiveStringResolver implementation. +func (r *Resolver) PrimitiveString() PrimitiveStringResolver { return &primitiveStringResolver{r} } + +// Query returns QueryResolver implementation. +func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } + +// Subscription returns SubscriptionResolver implementation. +func (r *Resolver) Subscription() SubscriptionResolver { return &subscriptionResolver{r} } + +// User returns UserResolver implementation. +func (r *Resolver) User() UserResolver { return &userResolver{r} } + +// WrappedMap returns WrappedMapResolver implementation. +func (r *Resolver) WrappedMap() WrappedMapResolver { return &wrappedMapResolver{r} } + +// WrappedSlice returns WrappedSliceResolver implementation. +func (r *Resolver) WrappedSlice() WrappedSliceResolver { return &wrappedSliceResolver{r} } + +type backedByInterfaceResolver struct{ *Resolver } +type errorsResolver struct{ *Resolver } +type forcedResolverResolver struct{ *Resolver } +type modelMethodsResolver struct{ *Resolver } +type mutationResolver struct{ *Resolver } +type overlappingFieldsResolver struct{ *Resolver } +type panicsResolver struct{ *Resolver } +type petResolver struct{ *Resolver } +type primitiveResolver struct{ *Resolver } +type primitiveStringResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } +type subscriptionResolver struct{ *Resolver } +type userResolver struct{ *Resolver } +type wrappedMapResolver struct{ *Resolver } +type wrappedSliceResolver struct{ *Resolver }