func (d *Definition) Empty() bool {
	return len(d.Fields) == 0
}
Empty indicates that this definition has no fields.
package markers
import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	sc "text/scanner"
	"unicode"
	"sigs.k8s.io/controller-tools/pkg/loader"
)
func expect(scanner *sc.Scanner, expected rune, errDesc string) bool {
	tok := scanner.Scan()
	if tok != expected {
		scanner.Error(scanner, fmt.Sprintf("expected %s, got %q", errDesc, scanner.TokenText()))
		return false
	}
	return true
}
func peekNoSpace(scanner *sc.Scanner) rune {
	hint := scanner.Peek()
	for ; hint <= rune(' ') && ((1<<uint64(hint))&scanner.Whitespace) != 0; hint = scanner.Peek() {
		scanner.Next()  
	}
	return hint
}
var (
	interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
	rawArgsType   = reflect.TypeOf((*RawArguments)(nil)).Elem()
)
func lowerCamelCase(in string) string {
	isFirst := true
	return strings.Map(func(inRune rune) rune {
		if isFirst {
			isFirst = false
			return unicode.ToLower(inRune)
		}
		return inRune
	}, in)
}
type RawArguments []byte
type ArgumentType int
const (
	InvalidType ArgumentType = iota
	IntType
	StringType
	BoolType
	AnyType
	SliceType
	MapType
	RawType
)
type Argument struct {
	Type ArgumentType
	Optional bool
	Pointer bool
	ItemType *Argument
}
func (a Argument) typeString(out *strings.Builder) {
	if a.Pointer {
		out.WriteRune('*')
	}
	switch a.Type {
	case InvalidType:
		out.WriteString("<invalid>")
	case IntType:
		out.WriteString("int")
	case StringType:
		out.WriteString("string")
	case BoolType:
		out.WriteString("bool")
	case AnyType:
		out.WriteString("<any>")
	case SliceType:
		out.WriteString("[]")
		a.ItemType.typeString(out)
	case MapType:
		out.WriteString("map[string]")
		a.ItemType.typeString(out)
	case RawType:
		out.WriteString("<raw>")
	}
}
func (a Argument) TypeString() string {
	out := &strings.Builder{}
	a.typeString(out)
	return out.String()
}
func (a Argument) String() string {
	if a.Optional {
		return fmt.Sprintf("<optional arg %s>", a.TypeString())
	}
	return fmt.Sprintf("<arg %s>", a.TypeString())
}
func castAndSet(out, val reflect.Value) {
	outType := out.Type()
	if outType != val.Type() {
		val = val.Convert(outType)
	}
	out.Set(val)
}
func makeSliceType(itemType Argument) (reflect.Type, error) {
	var itemReflectedType reflect.Type
	switch itemType.Type {
	case IntType:
		itemReflectedType = reflect.TypeOf(int(0))
	case StringType:
		itemReflectedType = reflect.TypeOf("")
	case BoolType:
		itemReflectedType = reflect.TypeOf(false)
	case SliceType:
		subItemType, err := makeSliceType(*itemType.ItemType)
		if err != nil {
			return nil, err
		}
		itemReflectedType = subItemType
	case MapType:
		subItemType, err := makeMapType(*itemType.ItemType)
		if err != nil {
			return nil, err
		}
		itemReflectedType = subItemType
	default:
		return nil, fmt.Errorf("invalid type when constructing guessed slice out: %v", itemType.Type)
	}
	if itemType.Pointer {
		itemReflectedType = reflect.PtrTo(itemReflectedType)
	}
	return reflect.SliceOf(itemReflectedType), nil
}
func makeMapType(itemType Argument) (reflect.Type, error) {
	var itemReflectedType reflect.Type
	switch itemType.Type {
	case IntType:
		itemReflectedType = reflect.TypeOf(int(0))
	case StringType:
		itemReflectedType = reflect.TypeOf("")
	case BoolType:
		itemReflectedType = reflect.TypeOf(false)
	case SliceType:
		subItemType, err := makeSliceType(*itemType.ItemType)
		if err != nil {
			return nil, err
		}
		itemReflectedType = subItemType
	case MapType:
		subItemType, err := makeMapType(*itemType.ItemType)
		if err != nil {
			return nil, err
		}
		itemReflectedType = subItemType
	case AnyType:
		itemReflectedType = interfaceType
	default:
		return nil, fmt.Errorf("invalid type when constructing guessed slice out: %v", itemType.Type)
	}
	if itemType.Pointer {
		itemReflectedType = reflect.PtrTo(itemReflectedType)
	}
	return reflect.MapOf(reflect.TypeOf(""), itemReflectedType), nil
}
func guessType(scanner *sc.Scanner, raw string, allowSlice bool) *Argument {
	if allowSlice {
		maybeItem := guessType(scanner, raw, false)
		subRaw := raw[scanner.Pos().Offset:]
		subScanner := parserScanner(subRaw, scanner.Error)
		var tok rune
		for tok = subScanner.Scan(); tok != ',' && tok != sc.EOF && tok != ';'; tok = subScanner.Scan() {
		}
		if tok == ';' {
			return &Argument{
				Type:     SliceType,
				ItemType: maybeItem,
			}
		}
		return maybeItem
	}
	subRaw := raw[scanner.Pos().Offset:]
	subScanner := parserScanner(subRaw, scanner.Error)
	hint := peekNoSpace(subScanner)
	switch hint {
	case '"', '\'', '`':
		return &Argument{Type: StringType}
	}
	if hint == '{' {
		subScanner.Scan()
		firstElemType := guessType(subScanner, subRaw, false)
		if firstElemType.Type == StringType {
			var keyVal string  
			(&Argument{Type: StringType}).parseString(subScanner, raw, reflect.Indirect(reflect.ValueOf(&keyVal)))
			if subScanner.Scan() == ':' {
				return &Argument{
					Type:     MapType,
					ItemType: &Argument{Type: AnyType},
				}
			}
		}
		return &Argument{
			Type:     SliceType,
			ItemType: firstElemType,
		}
	}
	probablyString := false
	if hint == 't' || hint == 'f' {
		if nextTok := subScanner.Scan(); nextTok == sc.Ident {
			switch subScanner.TokenText() {
			case "true", "false":
				return &Argument{Type: BoolType}
			}
			probablyString = true
		} else {
			scanner.Error(scanner, fmt.Sprintf("got a token (%q) that looked like an ident, but was not", scanner.TokenText()))
			return &Argument{Type: InvalidType}
		}
	}
	if !probablyString {
		nextTok := subScanner.Scan()
		if nextTok == '-' {
			nextTok = subScanner.Scan()
		}
		if nextTok == sc.Int {
			return &Argument{Type: IntType}
		}
	}
	return &Argument{Type: StringType}
}
func (a *Argument) parseString(scanner *sc.Scanner, raw string, out reflect.Value) {
	tok := scanner.Scan()
	if tok == sc.String || tok == sc.RawString {
		val, err := strconv.Unquote(scanner.TokenText())
		if err != nil {
			scanner.Error(scanner, fmt.Sprintf("unable to parse string: %v", err))
			return
		}
		castAndSet(out, reflect.ValueOf(val))
		return
	}
	startPos := scanner.Position.Offset
	for hint := peekNoSpace(scanner); hint != ',' && hint != ';' && hint != ':' && hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) {
		scanner.Scan()
	}
	endPos := scanner.Position.Offset + len(scanner.TokenText())
	castAndSet(out, reflect.ValueOf(raw[startPos:endPos]))
}
func (a *Argument) parseSlice(scanner *sc.Scanner, raw string, out reflect.Value) {
	resSlice := reflect.Zero(out.Type())
	elem := reflect.Indirect(reflect.New(out.Type().Elem()))
	if peekNoSpace(scanner) == '{' {
		scanner.Scan()  
		for hint := peekNoSpace(scanner); hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) {
			a.ItemType.parse(scanner, raw, elem, true  )
			resSlice = reflect.Append(resSlice, elem)
			tok := peekNoSpace(scanner)
			if tok == '}' {
				break
			}
			if !expect(scanner, ',', "comma") {
				return
			}
		}
		if !expect(scanner, '}', "close curly brace") {
			return
		}
		castAndSet(out, resSlice)
		return
	}
	for hint := peekNoSpace(scanner); hint != ',' && hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) {
		a.ItemType.parse(scanner, raw, elem, true  )
		resSlice = reflect.Append(resSlice, elem)
		tok := peekNoSpace(scanner)
		if tok == ',' || tok == '}' || tok == sc.EOF {
			break
		}
		scanner.Scan()
		if tok != ';' {
			scanner.Error(scanner, fmt.Sprintf("expected comma, got %q", scanner.TokenText()))
			return
		}
	}
	castAndSet(out, resSlice)
}
func (a *Argument) parseMap(scanner *sc.Scanner, raw string, out reflect.Value) {
	resMap := reflect.MakeMap(out.Type())
	elem := reflect.Indirect(reflect.New(out.Type().Elem()))
	key := reflect.Indirect(reflect.New(out.Type().Key()))
	if !expect(scanner, '{', "open curly brace") {
		return
	}
	for hint := peekNoSpace(scanner); hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) {
		a.parseString(scanner, raw, key)
		if !expect(scanner, ':', "colon") {
			return
		}
		a.ItemType.parse(scanner, raw, elem, false  )
		resMap.SetMapIndex(key, elem)
		if peekNoSpace(scanner) == '}' {
			break
		}
		if !expect(scanner, ',', "comma") {
			return
		}
	}
	if !expect(scanner, '}', "close curly brace") {
		return
	}
	castAndSet(out, resMap)
}
func (a *Argument) parse(scanner *sc.Scanner, raw string, out reflect.Value, inSlice bool) {
	if a.Type == InvalidType {
		scanner.Error(scanner, fmt.Sprintf("cannot parse invalid type"))
		return
	}
	if a.Pointer {
		out.Set(reflect.New(out.Type().Elem()))
		out = reflect.Indirect(out)
	}
	switch a.Type {
	case RawType:
		castAndSet(out, reflect.ValueOf(raw[scanner.Pos().Offset:]))
		for tok := scanner.Scan(); tok != sc.EOF; tok = scanner.Scan() {
		}
	case IntType:
		nextChar := scanner.Peek()
		isNegative := false
		if nextChar == '-' {
			isNegative = true
			scanner.Scan()  
		}
		if !expect(scanner, sc.Int, "integer") {
			return
		}
		text := scanner.TokenText()
		if isNegative {
			text = "-" + text
		}
		val, err := strconv.Atoi(text)
		if err != nil {
			scanner.Error(scanner, fmt.Sprintf("unable to parse integer: %v", err))
			return
		}
		castAndSet(out, reflect.ValueOf(val))
	case StringType:
		a.parseString(scanner, raw, out)
	case BoolType:
		if !expect(scanner, sc.Ident, "true or false") {
			return
		}
		switch scanner.TokenText() {
		case "true":
			castAndSet(out, reflect.ValueOf(true))
		case "false":
			castAndSet(out, reflect.ValueOf(false))
		default:
			scanner.Error(scanner, fmt.Sprintf("expected true or false, got %q", scanner.TokenText()))
			return
		}
	case AnyType:
		guessedType := guessType(scanner, raw, !inSlice)
		newOut := out
		switch guessedType.Type {
		case SliceType:
			newType, err := makeSliceType(*guessedType.ItemType)
			if err != nil {
				scanner.Error(scanner, err.Error())
				return
			}
			newOut = reflect.Indirect(reflect.New(newType))
		case MapType:
			newType, err := makeMapType(*guessedType.ItemType)
			if err != nil {
				scanner.Error(scanner, err.Error())
				return
			}
			newOut = reflect.Indirect(reflect.New(newType))
		}
		if !newOut.CanSet() {
			panic("at the disco")  
		}
		guessedType.Parse(scanner, raw, newOut)
		castAndSet(out, newOut)
	case SliceType:
		a.parseSlice(scanner, raw, out)
	case MapType:
		a.parseMap(scanner, raw, out)
	}
}
func (a *Argument) Parse(scanner *sc.Scanner, raw string, out reflect.Value) {
	a.parse(scanner, raw, out, false)
}
func ArgumentFromType(rawType reflect.Type) (Argument, error) {
	if rawType == rawArgsType {
		return Argument{
			Type: RawType,
		}, nil
	}
	if rawType == interfaceType {
		return Argument{
			Type: AnyType,
		}, nil
	}
	arg := Argument{}
	if rawType.Kind() == reflect.Ptr {
		rawType = rawType.Elem()
		arg.Pointer = true
		arg.Optional = true
	}
	switch rawType.Kind() {
	case reflect.String:
		arg.Type = StringType
	case reflect.Int, reflect.Int32:  
		arg.Type = IntType
	case reflect.Bool:
		arg.Type = BoolType
	case reflect.Slice:
		arg.Type = SliceType
		itemType, err := ArgumentFromType(rawType.Elem())
		if err != nil {
			return Argument{}, fmt.Errorf("bad slice item type: %w", err)
		}
		arg.ItemType = &itemType
	case reflect.Map:
		arg.Type = MapType
		if rawType.Key().Kind() != reflect.String {
			return Argument{}, fmt.Errorf("bad map key type: map keys must be strings")
		}
		itemType, err := ArgumentFromType(rawType.Elem())
		if err != nil {
			return Argument{}, fmt.Errorf("bad slice item type: %w", err)
		}
		arg.ItemType = &itemType
	default:
		return Argument{}, fmt.Errorf("type has unsupported kind %s", rawType.Kind())
	}
	return arg, nil
}
type TargetType int
const (
	DescribesPackage TargetType = iota
	DescribesType
	DescribesField
)
func (t TargetType) String() string {
	switch t {
	case DescribesPackage:
		return "package"
	case DescribesType:
		return "type"
	case DescribesField:
		return "field"
	default:
		return "(unknown)"
	}
}
type Definition struct {
	Output reflect.Type
	Name string
	Target TargetType
	Fields map[string]Argument
	FieldNames map[string]string
	Strict bool
}
func (d *Definition) AnonymousField() bool {
	if len(d.Fields) != 1 {
		return false
	}
	_, hasAnonField := d.Fields[""]
	return hasAnonField
}