// Code generated by Participle. DO NOT EDIT.
package main

import (
	"io"
	"regexp/syntax"
	"strings"
	"unicode/utf8"

	"github.com/alecthomas/participle/v2"
	"github.com/alecthomas/participle/v2/lexer"
)

var _ syntax.Op

var Lexer lexer.Definition = definitionImpl{}

type definitionImpl struct{}

func (definitionImpl) Symbols() map[string]lexer.TokenType {
	return map[string]lexer.TokenType{
		"Comment":    -7,
		"EOF":        -1,
		"Ident":      -3,
		"Number":     -2,
		"Punct":      -6,
		"String":     -4,
		"Whitespace": -5,
	}
}

func (definitionImpl) LexString(filename string, s string) (lexer.Lexer, error) {
	return &lexerImpl{
		s: s,
		pos: lexer.Position{
			Filename: filename,
			Line:     1,
			Column:   1,
		},
		states: []lexerState{{name: "Root"}},
	}, nil
}

func (d definitionImpl) LexBytes(filename string, b []byte) (lexer.Lexer, error) {
	return d.LexString(filename, string(b))
}

func (d definitionImpl) Lex(filename string, r io.Reader) (lexer.Lexer, error) {
	s := &strings.Builder{}
	_, err := io.Copy(s, r)
	if err != nil {
		return nil, err
	}
	return d.LexString(filename, s.String())
}

type lexerState struct {
	name   string
	groups []string
}

type lexerImpl struct {
	s      string
	p      int
	pos    lexer.Position
	states []lexerState
}

func (l *lexerImpl) Next() (lexer.Token, error) {
	if l.p == len(l.s) {
		return lexer.EOFToken(l.pos), nil
	}
	var (
		state  = l.states[len(l.states)-1]
		groups []int
		sym    lexer.TokenType
	)
	switch state.name {
	case "Root":
		if match := matchNumber(l.s, l.p); match[1] != 0 {
			sym = -2
			groups = match[:]
		} else if match := matchIdent(l.s, l.p); match[1] != 0 {
			sym = -3
			groups = match[:]
		} else if match := matchString(l.s, l.p); match[1] != 0 {
			sym = -4
			groups = match[:]
		} else if match := matchWhitespace(l.s, l.p); match[1] != 0 {
			sym = -5
			groups = match[:]
		} else if match := matchPunct(l.s, l.p); match[1] != 0 {
			sym = -6
			groups = match[:]
		} else if match := matchComment(l.s, l.p); match[1] != 0 {
			sym = -7
			groups = match[:]
		}
	}
	if groups == nil {
		sample := []rune(l.s[l.p:])
		if len(sample) > 16 {
			sample = append(sample[:16], []rune("...")...)
		}
		return lexer.Token{}, participle.Errorf(l.pos, "invalid input text %q", sample)
	}
	pos := l.pos
	span := l.s[groups[0]:groups[1]]
	l.p = groups[1]
	l.pos.Advance(span)
	return lexer.Token{
		Type:  sym,
		Value: span,
		Pos:   pos,
	}, nil
}

func (l *lexerImpl) sgroups(match []int) []string {
	sgroups := make([]string, len(match)/2)
	for i := 0; i < len(match)-1; i += 2 {
		sgroups[i/2] = l.s[l.p+match[i] : l.p+match[i+1]]
	}
	return sgroups
}

// [0-9]+
func matchNumber(s string, p int) (groups [2]int) {
	// [0-9] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		switch {
		case rn >= '0' && rn <= '9':
			return p + 1
		}
		return -1
	}
	// [0-9]+ (Plus)
	l1 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		for len(s) > p {
			if np := l0(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	np := l1(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [0-9A-Z_a-z]+
func matchIdent(s string, p int) (groups [2]int) {
	// [0-9A-Z_a-z] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		switch {
		case rn >= '0' && rn <= '9':
			return p + 1
		case rn >= 'A' && rn <= 'Z':
			return p + 1
		case rn == '_':
			return p + 1
		case rn >= 'a' && rn <= 'z':
			return p + 1
		}
		return -1
	}
	// [0-9A-Z_a-z]+ (Plus)
	l1 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		for len(s) > p {
			if np := l0(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	np := l1(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// "[^"]*"
func matchString(s string, p int) (groups [2]int) {
	// " (Literal)
	l0 := func(s string, p int) int {
		if p < len(s) && s[p] == '"' {
			return p + 1
		}
		return -1
	}
	// [^"] (CharClass)
	l1 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		var (
			rn rune
			n  int
		)
		if s[p] < utf8.RuneSelf {
			rn, n = rune(s[p]), 1
		} else {
			rn, n = utf8.DecodeRuneInString(s[p:])
		}
		switch {
		case rn >= '\x00' && rn <= '!':
			return p + 1
		case rn >= '#' && rn <= '\U0010ffff':
			return p + n
		}
		return -1
	}
	// [^"]* (Star)
	l2 := func(s string, p int) int {
		for len(s) > p {
			if np := l1(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	// "[^"]*" (Concat)
	l3 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		if p = l2(s, p); p == -1 {
			return -1
		}
		if p = l0(s, p); p == -1 {
			return -1
		}
		return p
	}
	np := l3(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [\t-\n\f-\r ]+
func matchWhitespace(s string, p int) (groups [2]int) {
	// [\t-\n\f-\r ] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		switch {
		case rn >= '\t' && rn <= '\n':
			return p + 1
		case rn >= '\f' && rn <= '\r':
			return p + 1
		case rn == ' ':
			return p + 1
		}
		return -1
	}
	// [\t-\n\f-\r ]+ (Plus)
	l1 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		for len(s) > p {
			if np := l0(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	np := l1(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [\(-\),\.:<->\{\}]
func matchPunct(s string, p int) (groups [2]int) {
	// [\(-\),\.:<->\{\}] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		switch {
		case rn >= '(' && rn <= ')':
			return p + 1
		case rn == ',':
			return p + 1
		case rn == '.':
			return p + 1
		case rn == ':':
			return p + 1
		case rn >= '<' && rn <= '>':
			return p + 1
		case rn == '{':
			return p + 1
		case rn == '}':
			return p + 1
		}
		return -1
	}
	np := l0(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// //(?-s:.)*
func matchComment(s string, p int) (groups [2]int) {
	// // (Literal)
	l0 := func(s string, p int) int {
		if p+2 < len(s) && s[p:p+2] == "//" {
			return p + 2
		}
		return -1
	}
	// (?-s:.) (AnyCharNotNL)
	l1 := func(s string, p int) int {
		var (
			rn rune
			n  int
		)
		if s[p] < utf8.RuneSelf {
			rn, n = rune(s[p]), 1
		} else {
			rn, n = utf8.DecodeRuneInString(s[p:])
		}
		if len(s) <= p+n || rn == '\n' {
			return -1
		}
		return p + n
	}
	// (?-s:.)* (Star)
	l2 := func(s string, p int) int {
		for len(s) > p {
			if np := l1(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	// //(?-s:.)* (Concat)
	l3 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		if p = l2(s, p); p == -1 {
			return -1
		}
		return p
	}
	np := l3(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}
