func (schema *Schema) valueFromGo(ctx context.Context, variables map[string]Value, goValue reflect.Value, typ *gqlType, sel *SelectionSet) (Value, []error) {
	goValue = unwrapPointer(goValue)
	if !goValue.IsValid() {
		if !typ.isNullable() {
			return Value{typ: typ}, []error{xerrors.Errorf("cannot convert nil to %v", typ)}
		}
		return Value{typ: typ, val: nil}, nil
	}
	resolvedType, err := resolveDynamicType(schema.types, goValue, typ)
	if err != nil {
		return Value{typ: typ}, []error{err}
	}
	typ = resolvedType
	sel = sel.forType(typ.toNullable().Name().String())
	if isGraphQLNull(interfaceValueForAssertions(goValue)) {
		if !typ.isNullable() {
			return Value{typ: typ}, []error{xerrors.Errorf("cannot convert nil to %v", typ)}
		}
		return Value{typ: typ, val: nil}, nil
	}
	switch {
	case typ.isScalar() || typ.isEnum():
		v, err := scalarFromGo(goValue, typ)
		if err != nil {
			return Value{typ: typ}, []error{err}
		}
		return v, nil
	case typ.isList():
		if kind := goValue.Kind(); kind != reflect.Slice && kind != reflect.Array {
			return Value{typ: typ}, []error{xerrors.Errorf("cannot convert %v to %v", goValue.Type(), typ)}
		}
		gqlValues := make([]Value, goValue.Len())
		var errs []error
		for i := range gqlValues {
			var ierrs []error
			gqlValues[i], ierrs = schema.valueFromGo(ctx, variables, goValue.Index(i), typ.listElem, sel)
			for _, err := range ierrs {
				errs = append(errs, &listElementError{idx: i, err: err})
			}
			if len(errs) > 0 && !typ.listElem.isNullable() {
				return Value{typ: typ}, errs
			}
		}
		return Value{typ: typ, val: gqlValues}, errs
	case typ.isObject():
		if sel == nil {
			return Value{typ: typ, val: []Field(nil)}, nil
		}
		gqlFields := make([]Field, 0, len(sel.fields))
		goValue = valueForAssertions(goValue)
		desc := schema.typeDescriptor(typeKey{
			goType:  goValue.Type(),
			gqlType: typ.obj,
		})
		if desc.err != nil {
			return Value{typ: typ}, []error{desc.err}
		}
		var errs []error
		for _, f := range sel.fields {
			var fval Value
			var ferrs []error
			switch f.name {
			case typeNameFieldName:
				fval = Value{
					typ: stringType.toNonNullable(),
					val: typ.toNullable().String(),
				}
			case schemaFieldName:
				fval, ferrs = schema.introspectSchema(ctx, variables, f)
			case typeByNameFieldName:
				fval, ferrs = schema.introspectType(ctx, variables, f)
			default:
				fval, ferrs = schema.readField(ctx, variables, goValue, desc, typ.obj.field(f.name).typ, f)
			}
			gqlFields = append(gqlFields, Field{Key: f.key, Value: fval})
			errs = append(errs, ferrs...)
		}
		return Value{typ: typ, val: gqlFields}, errs
	default:
		return Value{typ: typ}, []error{xerrors.Errorf("unhandled type: %v", typ)}
	}
}
valueFromGo converts a Go value into a GraphQL value. The selection set is
ignored for scalars.
package graphql
import (
	"context"
	"encoding"
	"encoding/json"
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"unicode/utf16"
	"golang.org/x/xerrors"
	"zombiezen.com/go/graphql-server/internal/gqlang"
)
type Value struct {
	typ *gqlType
	val interface{}  
}
type Field struct {
	Key string
	Value Value
}
func (f Field) encodeGraphQL(sb *strings.Builder, indent int) {
	sb.WriteString(f.Key)
	sb.WriteString(": ")
	f.Value.encodeGraphQL(sb, indent)
}
type FieldResolver interface {
	ResolveField(ctx context.Context, req FieldRequest) (interface{}, error)
}
type FieldRequest struct {
	Name      string
	Args      map[string]Value
	Selection *SelectionSet
}