...

Text file src/github.com/99designs/gqlgen/codegen/root_.gotpl

Documentation: github.com/99designs/gqlgen/codegen

     1{{ reserveImport "context"  }}
     2{{ reserveImport "fmt"  }}
     3{{ reserveImport "io"  }}
     4{{ reserveImport "strconv"  }}
     5{{ reserveImport "time"  }}
     6{{ reserveImport "sync"  }}
     7{{ reserveImport "sync/atomic" }}
     8{{ reserveImport "errors"  }}
     9{{ reserveImport "bytes"  }}
    10{{ reserveImport "embed"  }}
    11
    12{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }}
    13{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }}
    14{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
    15{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
    16
    17// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
    18func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
    19	return &executableSchema{
    20		schema: cfg.Schema,
    21		resolvers: cfg.Resolvers,
    22		directives: cfg.Directives,
    23		complexity: cfg.Complexity,
    24	}
    25}
    26
    27type Config struct {
    28	Schema    *ast.Schema
    29	Resolvers  ResolverRoot
    30	Directives DirectiveRoot
    31	Complexity ComplexityRoot
    32}
    33
    34type ResolverRoot interface {
    35{{- range $object := .Objects -}}
    36	{{ if $object.HasResolvers -}}
    37		{{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver
    38	{{ end }}
    39{{- end }}
    40{{- range $object := .Inputs -}}
    41	{{ if $object.HasResolvers -}}
    42		{{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver
    43	{{ end }}
    44{{- end }}
    45}
    46
    47type DirectiveRoot struct {
    48{{ range $directive := .Directives }}
    49	{{- $directive.Declaration }}
    50{{ end }}
    51}
    52
    53type ComplexityRoot struct {
    54{{- if not .Config.OmitComplexity }}
    55{{ range $object := .Objects }}
    56	{{ if not $object.IsReserved -}}
    57		{{ ucFirst $object.Name }} struct {
    58		{{ range $_, $fields := $object.UniqueFields }}
    59			{{- $field := index $fields 0 -}}
    60			{{ if not $field.IsReserved -}}
    61				{{ $field.GoFieldName }} {{ $field.ComplexitySignature }}
    62			{{ end }}
    63		{{- end }}
    64		}
    65	{{- end }}
    66{{ end }}
    67{{- end }}
    68}
    69
    70type executableSchema struct {
    71	schema    *ast.Schema
    72	resolvers  ResolverRoot
    73	directives DirectiveRoot
    74	complexity ComplexityRoot
    75}
    76
    77func (e *executableSchema) Schema() *ast.Schema {
    78	if e.schema != nil {
    79			return e.schema
    80	}
    81	return parsedSchema
    82}
    83
    84func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
    85	ec := executionContext{nil, e, 0, 0, nil}
    86	_ = ec
    87	{{- if not .Config.OmitComplexity }}
    88	switch typeName + "." + field {
    89	{{ range $object := .Objects }}
    90		{{ if not $object.IsReserved }}
    91			{{ range $_, $fields := $object.UniqueFields }}
    92				{{- $len := len $fields }}
    93				{{- range $i, $field := $fields }}
    94					{{- $last := eq (add $i 1) $len }}
    95					{{- if not $field.IsReserved }}
    96						{{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}:
    97						if e.complexity.{{ucFirst $object.Name }}.{{$field.GoFieldName}} == nil {
    98						break
    99						}
   100						{{ if $field.Args }}
   101							args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs)
   102							if err != nil {
   103							return 0, false
   104							}
   105						{{ end }}
   106						return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true
   107						{{ end }}
   108					{{- end }}
   109				{{- end }}
   110			{{ end }}
   111		{{ end }}
   112	{{ end }}
   113	}
   114	{{- end }}
   115	return 0, false
   116}
   117
   118func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
   119	rc := graphql.GetOperationContext(ctx)
   120	ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)}
   121	inputUnmarshalMap := graphql.BuildUnmarshalerMap(
   122		{{- range $input := .Inputs -}}
   123			{{ if not $input.HasUnmarshal }}
   124				ec.unmarshalInput{{ $input.Name }},
   125			{{- end }}
   126		{{- end }}
   127	)
   128	first := true
   129
   130	switch rc.Operation.Operation {
   131	{{- if .QueryRoot }} case ast.Query:
   132		return func(ctx context.Context) *graphql.Response {
   133			var response graphql.Response
   134			var data graphql.Marshaler
   135			if first {
   136				first = false
   137				ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
   138				{{ if .Directives.LocationDirectives "QUERY" -}}
   139					data = ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
   140						return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
   141					})
   142				{{- else -}}
   143					data = ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
   144				{{- end }}
   145			} else {
   146				if atomic.LoadInt32(&ec.pendingDeferred) > 0 {
   147					result := <-ec.deferredResults
   148					atomic.AddInt32(&ec.pendingDeferred, -1)
   149					data = result.Result
   150					response.Path = result.Path
   151					response.Label = result.Label
   152					response.Errors = result.Errors
   153				} else {
   154					return nil
   155				}
   156			}
   157			var buf bytes.Buffer
   158			data.MarshalGQL(&buf)
   159			response.Data = buf.Bytes()
   160			if atomic.LoadInt32(&ec.deferred) > 0 {
   161				hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0
   162				response.HasNext = &hasNext
   163			}
   164
   165			return &response
   166		}
   167	{{ end }}
   168
   169	{{- if .MutationRoot }} case ast.Mutation:
   170		return func(ctx context.Context) *graphql.Response {
   171			if !first { return nil }
   172			first = false
   173			ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
   174			{{ if .Directives.LocationDirectives "MUTATION" -}}
   175				data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
   176					return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
   177				})
   178			{{- else -}}
   179				data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet)
   180			{{- end }}
   181			var buf bytes.Buffer
   182			data.MarshalGQL(&buf)
   183
   184			return &graphql.Response{
   185				Data:       buf.Bytes(),
   186			}
   187		}
   188	{{ end }}
   189
   190	{{- if .SubscriptionRoot }} case ast.Subscription:
   191		{{ if .Directives.LocationDirectives "SUBSCRIPTION" -}}
   192			next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
   193				return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil
   194			})
   195		{{- else -}}
   196			next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet)
   197		{{- end }}
   198
   199		var buf bytes.Buffer
   200		return func(ctx context.Context) *graphql.Response {
   201			buf.Reset()
   202			data := next(ctx)
   203
   204			if data == nil {
   205				return nil
   206			}
   207			data.MarshalGQL(&buf)
   208
   209			return &graphql.Response{
   210				Data:       buf.Bytes(),
   211			}
   212		}
   213	{{ end }}
   214	default:
   215		return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
   216	}
   217}
   218
   219type executionContext struct {
   220	*graphql.OperationContext
   221	*executableSchema
   222	deferred        int32
   223	pendingDeferred int32
   224	deferredResults chan graphql.DeferredResult
   225}
   226
   227func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) {
   228	atomic.AddInt32(&ec.pendingDeferred, 1)
   229	go func () {
   230		ctx := graphql.WithFreshResponseContext(dg.Context)
   231		dg.FieldSet.Dispatch(ctx)
   232		ds := graphql.DeferredResult{
   233			Path:   dg.Path,
   234			Label:  dg.Label,
   235			Result: dg.FieldSet,
   236			Errors: graphql.GetErrors(ctx),
   237		}
   238		// null fields should bubble up
   239		if dg.FieldSet.Invalids > 0 {
   240			ds.Result = graphql.Null
   241		}
   242		ec.deferredResults <- ds
   243	}()
   244}
   245
   246func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
   247	if ec.DisableIntrospection {
   248		return nil, errors.New("introspection disabled")
   249	}
   250	return introspection.WrapSchema(ec.Schema()), nil
   251}
   252
   253func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
   254	if ec.DisableIntrospection {
   255		return nil, errors.New("introspection disabled")
   256	}
   257	return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil
   258}
   259
   260
   261{{if .HasEmbeddableSources }}
   262//go:embed{{- range $source := .AugmentedSources }}{{if $source.Embeddable}} {{$source.RelativePath|quote}}{{end}}{{- end }}
   263var sourcesFS embed.FS
   264
   265func sourceData(filename string) string {
   266	data, err := sourcesFS.ReadFile(filename)
   267	if err != nil {
   268		panic(fmt.Sprintf("codegen problem: %s not available", filename))
   269	}
   270	return string(data)
   271}
   272{{- end}}
   273
   274var sources = []*ast.Source{
   275{{- range $source := .AugmentedSources }}
   276	{Name: {{$source.RelativePath|quote}}, Input: {{if (not $source.Embeddable)}}{{$source.Source|rawQuote}}{{else}}sourceData({{$source.RelativePath|quote}}){{end}}, BuiltIn: {{$source.BuiltIn}}},
   277{{- end }}
   278}
   279var parsedSchema = gqlparser.MustLoadSchema(sources...)

View as plain text