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

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

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

var _ syntax.Op
var _ fmt.State

const _ = utf8.RuneError

var GeneratedBasicBackRefCache sync.Map
var GeneratedBasicLexer lexer.Definition = lexerGeneratedBasicDefinitionImpl{}

type lexerGeneratedBasicDefinitionImpl struct{}

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

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

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

func (d lexerGeneratedBasicDefinitionImpl) 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 lexerGeneratedBasicState struct {
	name   string
	groups []string
}

type lexerGeneratedBasicImpl struct {
	s      string
	p      int
	pos    lexer.Position
	states []lexerGeneratedBasicState
}

func (l *lexerGeneratedBasicImpl) 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 := matchGeneratedBasicString(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -2
			groups = match[:]
		} else if match := matchGeneratedBasicNumber(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -3
			groups = match[:]
		} else if match := matchGeneratedBasicIdent(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -4
			groups = match[:]
		} else if match := matchGeneratedBasicPunct(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -5
			groups = match[:]
		} else if match := matchGeneratedBasicEOL(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -6
			groups = match[:]
		} else if match := matchGeneratedBasicComment(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -7
			groups = match[:]
		} else if match := matchGeneratedBasicWhitespace(l.s, l.p, l.states[len(l.states)-1].groups); match[1] != 0 {
			sym = -8
			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", string(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 *lexerGeneratedBasicImpl) 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
}

// "(\\"|[^"])*"
func matchGeneratedBasicString(s string, p int, backrefs []string) (groups [4]int) {
	// " (Literal)
	l0 := func(s string, p int) int {
		if p < len(s) && s[p] == '"' {
			return p + 1
		}
		return -1
	}
	// \\" (Literal)
	l1 := func(s string, p int) int {
		if p+2 <= len(s) && s[p:p+2] == "\\\"" {
			return p + 2
		}
		return -1
	}
	// [^"] (CharClass)
	l2 := 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
	}
	// \\"|[^"] (Alternate)
	l3 := func(s string, p int) int {
		if np := l1(s, p); np != -1 {
			return np
		}
		if np := l2(s, p); np != -1 {
			return np
		}
		return -1
	}
	// (\\"|[^"]) (Capture)
	l4 := func(s string, p int) int {
		np := l3(s, p)
		if np != -1 {
			groups[2] = p
			groups[3] = np
		}
		return np
	}
	// (\\"|[^"])* (Star)
	l5 := func(s string, p int) int {
		for len(s) > p {
			if np := l4(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	// "(\\"|[^"])*" (Concat)
	l6 := func(s string, p int) int {
		if p = l0(s, p); p == -1 {
			return -1
		}
		if p = l5(s, p); p == -1 {
			return -1
		}
		if p = l0(s, p); p == -1 {
			return -1
		}
		return p
	}
	np := l6(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [\+\-]?([0-9]*\.)?[0-9]+
func matchGeneratedBasicNumber(s string, p int, backrefs []string) (groups [4]int) {
	// [\+\-] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		if rn == '+' || rn == '-' {
			return p + 1
		}
		return -1
	}
	// [\+\-]? (Quest)
	l1 := func(s string, p int) int {
		if np := l0(s, p); np != -1 {
			return np
		}
		return p
	}
	// [0-9] (CharClass)
	l2 := 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]* (Star)
	l3 := func(s string, p int) int {
		for len(s) > p {
			if np := l2(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	// \. (Literal)
	l4 := func(s string, p int) int {
		if p < len(s) && s[p] == '.' {
			return p + 1
		}
		return -1
	}
	// [0-9]*\. (Concat)
	l5 := func(s string, p int) int {
		if p = l3(s, p); p == -1 {
			return -1
		}
		if p = l4(s, p); p == -1 {
			return -1
		}
		return p
	}
	// ([0-9]*\.) (Capture)
	l6 := func(s string, p int) int {
		np := l5(s, p)
		if np != -1 {
			groups[2] = p
			groups[3] = np
		}
		return np
	}
	// ([0-9]*\.)? (Quest)
	l7 := func(s string, p int) int {
		if np := l6(s, p); np != -1 {
			return np
		}
		return p
	}
	// [0-9]+ (Plus)
	l8 := func(s string, p int) int {
		if p = l2(s, p); p == -1 {
			return -1
		}
		for len(s) > p {
			if np := l2(s, p); np == -1 {
				return p
			} else {
				p = np
			}
		}
		return p
	}
	// [\+\-]?([0-9]*\.)?[0-9]+ (Concat)
	l9 := func(s string, p int) int {
		if p = l1(s, p); p == -1 {
			return -1
		}
		if p = l7(s, p); p == -1 {
			return -1
		}
		if p = l8(s, p); p == -1 {
			return -1
		}
		return p
	}
	np := l9(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [A-Z_a-z][0-9A-Z_a-z]*
func matchGeneratedBasicIdent(s string, p int, backrefs []string) (groups [2]int) {
	// [A-Z_a-z] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		switch {
		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] (CharClass)
	l1 := 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]* (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
	}
	// [A-Z_a-z][0-9A-Z_a-z]* (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
}

// [!-/:-@\[-`\{-~]+
func matchGeneratedBasicPunct(s string, p int, backrefs []string) (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 >= ':' && rn <= '@':
			return p + 1
		case rn >= '[' && rn <= '`':
			return p + 1
		case rn >= '{' && rn <= '~':
			return p + 1
		}
		return -1
	}
	// [!-/:-@\[-`\{-~]+ (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
}

// \n
func matchGeneratedBasicEOL(s string, p int, backrefs []string) (groups [2]int) {
	if p < len(s) && s[p] == '\n' {
		groups[0] = p
		groups[1] = p + 1
	}
	return
}

// (?i:REM)[^\n]*(?i:\n)
func matchGeneratedBasicComment(s string, p int, backrefs []string) (groups [2]int) {
	// (?i:REM) (Literal)
	l0 := func(s string, p int) int {
		if p+3 <= len(s) && strings.EqualFold(s[p:p+3], "REM") {
			return p + 3
		}
		return -1
	}
	// [^\n] (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 <= '\t':
			return p + 1
		case rn >= '\v' && rn <= '\U0010ffff':
			return p + n
		}
		return -1
	}
	// [^\n]* (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
	}
	// (?i:\n) (Literal)
	l3 := func(s string, p int) int {
		if p < len(s) && s[p] == '\n' {
			return p + 1
		}
		return -1
	}
	// (?i:REM)[^\n]*(?i:\n) (Concat)
	l4 := 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 = l3(s, p); p == -1 {
			return -1
		}
		return p
	}
	np := l4(s, p)
	if np == -1 {
		return
	}
	groups[0] = p
	groups[1] = np
	return
}

// [\t ]+
func matchGeneratedBasicWhitespace(s string, p int, backrefs []string) (groups [2]int) {
	// [\t ] (CharClass)
	l0 := func(s string, p int) int {
		if len(s) <= p {
			return -1
		}
		rn := s[p]
		if rn == '\t' || rn == ' ' {
			return p + 1
		}
		return -1
	}
	// [\t ]+ (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
}
