1package parser
2
3import "github.com/goccy/go-yaml/token"
4
5// context context at parsing
6type context struct {
7	idx    int
8	size   int
9	tokens token.Tokens
10	mode   Mode
11}
12
13func (c *context) next() bool {
14	return c.idx < c.size
15}
16
17func (c *context) previousToken() *token.Token {
18	if c.idx > 0 {
19		return c.tokens[c.idx-1]
20	}
21	return nil
22}
23
24func (c *context) insertToken(idx int, tk *token.Token) {
25	if c.size < idx {
26		return
27	}
28	if c.size == idx {
29		curToken := c.tokens[c.size-1]
30		tk.Next = curToken
31		curToken.Prev = tk
32
33		c.tokens = append(c.tokens, tk)
34		c.size = len(c.tokens)
35		return
36	}
37
38	curToken := c.tokens[idx]
39	tk.Next = curToken
40	curToken.Prev = tk
41
42	c.tokens = append(c.tokens[:idx+1], c.tokens[idx:]...)
43	c.tokens[idx] = tk
44	c.size = len(c.tokens)
45}
46
47func (c *context) currentToken() *token.Token {
48	if c.idx >= c.size {
49		return nil
50	}
51	return c.tokens[c.idx]
52}
53
54func (c *context) nextToken() *token.Token {
55	if c.idx+1 >= c.size {
56		return nil
57	}
58	return c.tokens[c.idx+1]
59}
60
61func (c *context) afterNextToken() *token.Token {
62	if c.idx+2 >= c.size {
63		return nil
64	}
65	return c.tokens[c.idx+2]
66}
67
68func (c *context) nextNotCommentToken() *token.Token {
69	for i := c.idx + 1; i < c.size; i++ {
70		tk := c.tokens[i]
71		if tk.Type == token.CommentType {
72			continue
73		}
74		return tk
75	}
76	return nil
77}
78
79func (c *context) afterNextNotCommentToken() *token.Token {
80	notCommentTokenCount := 0
81	for i := c.idx + 1; i < c.size; i++ {
82		tk := c.tokens[i]
83		if tk.Type == token.CommentType {
84			continue
85		}
86		notCommentTokenCount++
87		if notCommentTokenCount == 2 {
88			return tk
89		}
90	}
91	return nil
92}
93
94func (c *context) enabledComment() bool {
95	return c.mode&ParseComments != 0
96}
97
98func (c *context) isCurrentCommentToken() bool {
99	tk := c.currentToken()
100	if tk == nil {
101		return false
102	}
103	return tk.Type == token.CommentType
104}
105
106func (c *context) progressIgnoreComment(num int) {
107	if c.size <= c.idx+num {
108		c.idx = c.size
109	} else {
110		c.idx += num
111	}
112}
113
114func (c *context) progress(num int) {
115	if c.isCurrentCommentToken() {
116		return
117	}
118	c.progressIgnoreComment(num)
119}
120
121func newContext(tokens token.Tokens, mode Mode) *context {
122	filteredTokens := token.Tokens{}
123	if mode&ParseComments != 0 {
124		filteredTokens = tokens
125	} else {
126		for _, tk := range tokens {
127			if tk.Type == token.CommentType {
128				continue
129			}
130			filteredTokens.Add(tk)
131		}
132	}
133	return &context{
134		idx:    0,
135		size:   len(filteredTokens),
136		tokens: filteredTokens,
137		mode:   mode,
138	}
139}
140