{{- range $object := .Objects }}{{- range $field := $object.Fields }}

func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) (ret {{ if $object.Stream }}func(ctx context.Context){{ end }}graphql.Marshaler) {
	{{- $null := "graphql.Null" }}
	{{- if $object.Stream }}
		{{- $null = "nil" }}
	{{- end }}
	fc, err := ec.{{ $field.FieldContextFunc }}(ctx, field)
	if err != nil {
		return {{ $null }}
	}
	ctx = graphql.WithFieldContext(ctx, fc)
	defer func () {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = {{ $null }}
		}
	}()
	{{- if $field.TypeReference.IsRoot }}
		{{- if $field.TypeReference.IsPtr }}
			res := &{{ $field.TypeReference.Elem.GO | ref }}{}
		{{- else }}
			res := {{ $field.TypeReference.GO | ref }}{}
		{{- end }}
		fc.Result = res
		return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
	{{- else}}
		{{- if  $.AllDirectives.LocationDirectives "FIELD" }}
			resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {
				{{ template "field" $field }}
			})
		{{ else }}
			resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
				{{ template "field" $field }}
			})
			if err != nil {
				ec.Error(ctx, err)
				return {{ $null }}
			}
		{{- end }}
		if resTmp == nil {
			{{- if $field.TypeReference.GQL.NonNull }}
				if !graphql.HasFieldError(ctx, fc) {
					ec.Errorf(ctx, "must not be null")
				}
			{{- end }}
			return {{ $null }}
		}
		{{- if $object.Stream }}
			return func(ctx context.Context) graphql.Marshaler {
				select {
				case res, ok := <-resTmp.(<-chan {{$field.TypeReference.GO | ref}}):
					if !ok {
						return nil
					}
					return graphql.WriterFunc(func(w io.Writer) {
						w.Write([]byte{'{'})
						graphql.MarshalString(field.Alias).MarshalGQL(w)
						w.Write([]byte{':'})
						ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
						w.Write([]byte{'}'})
					})
				case <-ctx.Done():
					return nil
				}
			}
		{{- else }}
			res := resTmp.({{$field.TypeReference.GO | ref}})
			fc.Result = res
			return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
		{{- end }}
	{{- end }}
}

func (ec *executionContext) {{ $field.FieldContextFunc }}({{ if not $field.Args }}_{{ else }}ctx{{ end }} context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
	fc = &graphql.FieldContext{
		Object: {{quote $field.Object.Name}},
		Field: field,
		IsMethod: {{or $field.IsMethod $field.IsResolver}},
		IsResolver: {{ $field.IsResolver }},
		Child: func (ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
			{{- if not $field.TypeReference.Definition.Fields }}
				return nil, errors.New("field of type {{ $field.TypeReference.Definition.Name }} does not have child fields")
			{{- else if ne $field.TypeReference.Definition.Kind "OBJECT" }}
				return nil, errors.New("FieldContext.Child cannot be called on type {{ $field.TypeReference.Definition.Kind }}")
			{{- else }}
				switch field.Name {
					{{- range $f := $field.TypeReference.Definition.Fields }}
						case "{{ $f.Name }}":
							return ec.{{ $field.ChildFieldContextFunc $f.Name }}(ctx, field)
					{{- end }}
				}
				return nil, fmt.Errorf("no field named %q was found under type {{ $field.TypeReference.Definition.Name }}", field.Name)
			{{- end }}
		},
	}
	{{- if $field.Args }}
		defer func () {
			if r := recover(); r != nil {
				err = ec.Recover(ctx, r)
				ec.Error(ctx, err)
			}
		}()
		ctx = graphql.WithFieldContext(ctx, fc)
		if fc.Args, err = ec.{{ $field.ArgsFunc }}(ctx, field.ArgumentMap(ec.Variables)); err != nil {
			ec.Error(ctx, err)
			return fc, err
		}
	{{- end }}
	return fc, nil
}

{{- end }}{{- end}}

{{ define "field" }}
	{{- if .HasDirectives -}}
		directive0 := func(rctx context.Context) (interface{}, error) {
			ctx = rctx  // use context from middleware stack in children
			{{ template "fieldDefinition" . }}
		}
		{{ template "implDirectives" . }}
		tmp, err := directive{{.ImplDirectives|len}}(rctx)
		if err != nil {
			return nil, graphql.ErrorOnPath(ctx, err)
		}
		if tmp == nil {
		    return nil, nil
		}
		if data, ok := tmp.({{if .Stream}}<-chan {{end}}{{ .TypeReference.GO | ref }}) ; ok {
			return data, nil
		}
		return nil, fmt.Errorf(`unexpected type %T from directive, should be {{if .Stream}}<-chan {{end}}{{ .TypeReference.GO }}`, tmp)
	{{- else -}}
		ctx = rctx  // use context from middleware stack in children
		{{ template "fieldDefinition" . }}
	{{- end -}}
{{ end }}

{{ define "fieldDefinition" }}
	{{- if .IsResolver -}}
		return ec.resolvers.{{ .ShortInvocation }}
	{{- else if .IsMap -}}
		switch v := {{.GoReceiverName}}[{{.Name|quote}}].(type) {
		case {{if .Stream}}<-chan {{end}}{{.TypeReference.GO | ref}}:
			return v, nil
		case {{if .Stream}}<-chan {{end}}{{.TypeReference.Elem.GO | ref}}:
			return &v, nil
		case nil:
			return ({{.TypeReference.GO | ref}})(nil), nil
		default:
			return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ .Name | quote}})
		}
	{{- else if .IsMethod -}}
		{{- if .VOkFunc -}}
			v, ok := {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }})
			if !ok {
				return nil, nil
			}
			return v, nil
		{{- else if .NoErr -}}
			return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}), nil
		{{- else -}}
			return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }})
		{{- end -}}
	{{- else if .IsVariable -}}
		return {{.GoReceiverName}}.{{.GoFieldName}}, nil
	{{- end }}
{{- end }}
