github.com/niko0xdev/gqlgen@v0.17.55-0.20240120102243-2ecff98c3e37/codegen/root_.gotpl (about)

     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/niko0xdev/gqlgen/graphql" }}
    15  {{ reserveImport "github.com/niko0xdev/gqlgen/graphql/introspection" }}
    16  
    17  // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
    18  func 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  
    27  type Config struct {
    28  	Schema    *ast.Schema
    29  	Resolvers  ResolverRoot
    30  	Directives DirectiveRoot
    31  	Complexity ComplexityRoot
    32  }
    33  
    34  type 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  
    47  type DirectiveRoot struct {
    48  {{ range $directive := .Directives }}
    49  	{{- $directive.Declaration }}
    50  {{ end }}
    51  }
    52  
    53  type 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  
    70  type executableSchema struct {
    71  	schema    *ast.Schema
    72  	resolvers  ResolverRoot
    73  	directives DirectiveRoot
    74  	complexity ComplexityRoot
    75  }
    76  
    77  func (e *executableSchema) Schema() *ast.Schema {
    78  	if e.schema != nil {
    79  			return e.schema
    80  	}
    81  	return parsedSchema
    82  }
    83  
    84  func (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  
   118  func (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  
   219  type executionContext struct {
   220  	*graphql.OperationContext
   221  	*executableSchema
   222  	deferred        int32
   223  	pendingDeferred int32
   224  	deferredResults chan graphql.DeferredResult
   225  }
   226  
   227  func (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  
   246  func (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  
   253  func (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 }}
   263  var sourcesFS embed.FS
   264  
   265  func 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  
   274  var 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  }
   279  var parsedSchema = gqlparser.MustLoadSchema(sources...)