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

var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}}

{{- if .Stream }}
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func(ctx context.Context) graphql.Marshaler {
	fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
	ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
		Object: {{$object.Name|quote}},
	})
	if len(fields) != 1 {
		ec.Errorf(ctx, "must subscribe to exactly one stream")
		return nil
	}

	switch fields[0].Name {
	{{- range $field := $object.Fields }}
	case "{{$field.Name}}":
		return ec._{{$object.Name}}_{{$field.Name}}(ctx, fields[0])
	{{- end }}
	default:
		panic("unknown field " + strconv.Quote(fields[0].Name))
	}
}
{{- else }}
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
	fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
	{{- if $object.Root }}
		ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
			Object: {{$object.Name|quote}},
		})
	{{end}}

	out := graphql.NewFieldSet(fields)
	deferred := make(map[string]*graphql.FieldSet)
	for i, field := range fields {
		{{- if $object.Root }}
			innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
				Object: field.Name,
				Field: field,
			})
		{{end}}
		switch field.Name {
		case "__typename":
			out.Values[i] = graphql.MarshalString({{$object.Name|quote}})
		{{- range $field := $object.Fields }}
		case "{{$field.Name}}":
			{{- if $field.IsConcurrent }}
				field := field

				innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
					defer func() {
						if r := recover(); r != nil {
							ec.Error(ctx, ec.Recover(ctx, r))
						}
					}()
					res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
					{{- if $field.TypeReference.GQL.NonNull }}
						if res == graphql.Null {
							{{- if $object.IsConcurrent }}
								atomic.AddUint32(&fs.Invalids, 1)
							{{- else }}
								fs.Invalids++
							{{- end }}
						}
					{{- end }}
					return res
				}

				{{if $object.Root}}
					rrm := func(ctx context.Context) graphql.Marshaler {
						return ec.OperationContext.RootResolverMiddleware(ctx,
							func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
					}
				{{end}}

				{{if not $object.Root}}
					if field.Deferrable != nil {
						dfs, ok := deferred[field.Deferrable.Label]
						di := 0
						if ok {
							dfs.AddField(field)
							di = len(dfs.Values) - 1
						} else {
							dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
							deferred[field.Deferrable.Label] = dfs
						}
						dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
							return innerFunc(ctx, dfs)
						})

						// don't run the out.Concurrently() call below
						out.Values[i] = graphql.Null
						continue
					}
				{{end}}

				out.Concurrently(i, func(ctx context.Context) graphql.Marshaler {
					{{- if $object.Root -}}
						return rrm(innerCtx)
					{{- else -}}
						return innerFunc(ctx, out)
					{{- end -}}
				})
			{{- else }}
				{{- if $object.Root -}}
					out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
						return ec._{{$object.Name}}_{{$field.Name}}(ctx, field)
					})
				{{- else -}}
					out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field, obj)
				{{- end -}}

				{{- if $field.TypeReference.GQL.NonNull }}
					if out.Values[i] == graphql.Null {
						{{- if $object.IsConcurrent }}
							atomic.AddUint32(&out.Invalids, 1)
						{{- else }}
							out.Invalids++
						{{- end }}
					}
				{{- end }}
			{{- end }}
		{{- end }}
		default:
			panic("unknown field " + strconv.Quote(field.Name))
		}
	}
	out.Dispatch(ctx)
	if out.Invalids > 0 { return graphql.Null }

	atomic.AddInt32(&ec.deferred, int32(len(deferred)))

	for label, dfs := range deferred {
		ec.processDeferredGroup(graphql.DeferredGroup{
			Label:    label,
			Path:     graphql.GetPath(ctx),
			FieldSet: dfs,
			Context:  ctx,
		})
	}

	return out
}
{{- end }}

{{- end }}
