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
}
splitTag takes a tag and splits it into directives and declarations.
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
}