func structNode(s interface{}) (node, error) {
	st := deref(reflect.TypeOf(s))
	if st.Kind() != reflect.Struct {
		return node{}, fmt.Errorf("expecting struct type, got %s", st.Kind())
	}
	return node{
		Name: st.Name(),
		Type: st,
	}, nil
}
structNode ensures a given type is a struct type and resolves it to a node.
package goql
import (
	"fmt"
	"io"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"sync"
)
const structTag = "goql"
var (
	reName = regexp.MustCompile(`^\w+$`)
	reDecl     = regexp.MustCompile(`^(?P<name>\w+)(?P<args>\((?:\w+:\$\w+<\[?\w+!?]?>,?)*\))$`)
	reDeclName = reDecl.SubexpIndex("name")
	reDeclArgs = reDecl.SubexpIndex("args")
	reParam     = regexp.MustCompile(`(?P<name>\w+):\$(?P<arg>\w+)<(?P<kind>\[?\w+!?]?)>`)
	reParamName = reParam.SubexpIndex("name")
	reParamArg  = reParam.SubexpIndex("arg")
	reParamKind = reParam.SubexpIndex("kind")
	reDirective     = regexp.MustCompile(`^@(?P<name>\w+)(?P<arg>\(\$?\w+\))$`)
	reDirectiveName = reDirective.SubexpIndex("name")
	reDirectiveArg  = reDirective.SubexpIndex("arg")
)
const keepTag = "keep"
type token struct {
	Kind string
	Name string
	Arg  string
}
func tokenize(tokens []token) string {
	tn := make([]string, 0, len(tokens))
	for _, t := range tokens {
		tn = append(tn, fmt.Sprintf("%s: $%s", t.Name, t.Arg))
	}
	return strings.Join(tn, ", ")
}
type declaration struct {
	Name     string
	Alias    string
	Tokens   []token
	Template string
}
func (d declaration) tokenize(w io.Writer) {
	if d.Alias != "" {
		fmt.Fprintf(w, "%s: ", d.Alias)  
	}
	if d.Template != "" {
		fmt.Fprintf(w, "%s(%s)", d.Name, tokenize(d.Tokens))  
		return
	}
	io.WriteString(w, d.Name)  
}
type directiveEnum string
const (
	directiveAlias   = directiveEnum("alias")
	directiveSkip    = directiveEnum("skip")
	directiveInclude = directiveEnum("include")
)
type directive struct {
	Type     directiveEnum
	Token    token
	Template string
}
func (d *directive) tokenize(w io.Writer) {
	fmt.Fprintf(w, "@%s(if: $%s)", d.Type, d.Token.Arg)  
}
type field struct {
	Decl       declaration
	Directives []directive
	Fields     []field
	Keep bool
}
func (f *field) tokens() []token {
	var tokens []token
	tokens = append(tokens, f.Decl.Tokens...)
	for _, directive := range f.Directives {
		if (directive.Token != token{}) {
			tokens = append(tokens, directive.Token)
		}
	}
	for _, field := range f.Fields {
		tokens = append(tokens, field.tokens()...)
	}
	return tokens
}
func argsFromTokens(tokens []token) ([]string, error) {
	argsMap := make(map[string]string, len(tokens))
	for _, token := range tokens {
		if kind, exists := argsMap[token.Arg]; exists {
			if token.Kind != kind {
				return nil, fmt.Errorf("argument $%s cannot have more than one type", token.Arg)
			}
			continue
		}
		argsMap[token.Arg] = token.Kind
	}
	args := make([]string, 0, len(argsMap))
	for arg, kind := range argsMap {
		args = append(args, fmt.Sprintf("$%s: %s", arg, kind))
	}
	return args, nil
}
func (f *field) tokenize(w io.Writer, fields Fields) (bool, error) {  
	var write bool
	if f.Keep || fields == nil {
		write = true
	} else if desired, exists := fields[f.Decl.Name]; exists {
		switch ts := desired.(type) {
		case bool:
			if ts {
				write = true
				if len(f.Fields) > 0 {
					return false, fmt.Errorf("field %s set to true in sparse fieldset map has children fields, needs submap for children fields", f.Decl.Name)
				}
			}
		case Fields:
			if len(f.Fields) == 0 {
				return false, fmt.Errorf("field %s set to a submap of fields in sparse fieldset map has no children fields, needs to be set to true or false", f.Decl.Name)
			}
			write = true
			fields = ts
		default:
			write = false
		}
	}
	if write {
		f.Decl.tokenize(w)
		for _, directive := range f.Directives {
			io.WriteString(w, " ")  
			directive.tokenize(w)
		}
		if len(f.Fields) > 0 {
			io.WriteString(w, " {\n")  
			for _, field := range f.Fields {
				written, err := field.tokenize(w, fields)
				if err != nil {
					return false, err
				}
				if written {
					io.WriteString(w, "\n")  
				}
			}
			io.WriteString(w, "}")  
		}
	}
	return write, nil
}
func splitTag(tag string) []string {
	var sb strings.Builder
	var split []string
	var inArgs bool
	for _, r := range tag {
		if strings.ContainsRune("()", r) {
			inArgs = !inArgs
		}
		if r == ',' && !inArgs {
			split = append(split, sb.String())
			sb.Reset()
			continue
		}
		sb.WriteRune(r)
	}
	split = append(split, sb.String())
	return split
}
func parseTag(tag string) (field, error) {  
	var f field
	var alias string
	for _, item := range splitTag(tag) {
		item = strings.TrimSpace(item)
		switch {
		case item == "":
			continue
		case reName.MatchString(item) && item != keepTag:
			f.Decl = declaration{Name: item}
		case reDecl.MatchString(item):
			f.Decl = parseDecl(item)
			f.Keep = true
		case reDirective.MatchString(item):
			dir, err := parseDirective(item)
			if err != nil {
				return field{}, err
			}
			if dir.Type == directiveAlias {
				alias = dir.Template
				continue
			}
			f.Directives = append(f.Directives, dir)
		case item == keepTag:
			f.Keep = true
		default:
			return field{}, fmt.Errorf("failed to parse tag \"%s\"", tag)
		}
	}
	f.Decl.Alias = alias
	sort.Slice(f.Directives, func(i, j int) bool {
		return f.Directives[i].Type < f.Directives[j].Type
	})
	j := 0
	for i := 1; i < len(f.Directives); i++ {
		x, y := &f.Directives[i], f.Directives[j]
		if x.Type == y.Type {
			return field{}, fmt.Errorf("duplicate directive in tag \"%s\"", x.Type)
		}
		j++
	}
	return f, nil
}
func parseDecl(s string) declaration {
	var tokens []token
	matches := reDecl.FindStringSubmatch(s)
	name := matches[reDeclName]
	params := strings.Trim(matches[reDeclArgs], "()")
	paramMatches := reParam.FindAllStringSubmatch(params, -1)
	for _, match := range paramMatches {
		tokens = append(tokens, token{
			Kind: match[reParamKind],
			Name: match[reParamName],
			Arg:  match[reParamArg],
		})
	}
	template := reParam.ReplaceAllStringFunc(params, func(param string) string {
		if i := strings.Index(param, "["); i != -1 {
			return param[:i]
		}
		return param
	})
	return declaration{
		Name:     name,
		Tokens:   tokens,
		Template: template,
	}
}
func parseDirective(s string) (directive, error) {
	matches := reDirective.FindStringSubmatch(s)
	dir := directive{
		Type:     directiveEnum(matches[reDirectiveName]),
		Template: strings.Trim(matches[reDirectiveArg], "()"),
	}
	switch dir.Type {
	case directiveAlias:
	case directiveInclude, directiveSkip:
		if strings.HasPrefix(dir.Template, "$") {
			dir.Token = token{
				Kind: "Boolean!",
				Arg:  dir.Template[1:],
			}
		}
	default:
		return directive{}, fmt.Errorf("unknown directive in tag \"%s\"", dir.Type)
	}
	return dir, nil
}
type node struct {
	Name string
	Type reflect.Type
	Tag  string
}
type visit func(n *node) error