1// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2// Use of this file is governed by the BSD 3-clause license that
3// can be found in the LICENSE.txt file in the project root.
4
5package antlr
6
7import (
8	"reflect"
9	"strconv"
10)
11
12type ParserRuleContext interface {
13	RuleContext
14
15	SetException(RecognitionException)
16
17	AddTokenNode(token Token) *TerminalNodeImpl
18	AddErrorNode(badToken Token) *ErrorNodeImpl
19
20	EnterRule(listener ParseTreeListener)
21	ExitRule(listener ParseTreeListener)
22
23	SetStart(Token)
24	GetStart() Token
25
26	SetStop(Token)
27	GetStop() Token
28
29	AddChild(child RuleContext) RuleContext
30	RemoveLastChild()
31}
32
33type BaseParserRuleContext struct {
34	*BaseRuleContext
35
36	start, stop Token
37	exception   RecognitionException
38	children    []Tree
39}
40
41func NewBaseParserRuleContext(parent ParserRuleContext, invokingStateNumber int) *BaseParserRuleContext {
42	prc := new(BaseParserRuleContext)
43
44	prc.BaseRuleContext = NewBaseRuleContext(parent, invokingStateNumber)
45
46	prc.RuleIndex = -1
47	// * If we are debugging or building a parse tree for a Visitor,
48	// we need to track all of the tokens and rule invocations associated
49	// with prc rule's context. This is empty for parsing w/o tree constr.
50	// operation because we don't the need to track the details about
51	// how we parse prc rule.
52	// /
53	prc.children = nil
54	prc.start = nil
55	prc.stop = nil
56	// The exception that forced prc rule to return. If the rule successfully
57	// completed, prc is {@code nil}.
58	prc.exception = nil
59
60	return prc
61}
62
63func (prc *BaseParserRuleContext) SetException(e RecognitionException) {
64	prc.exception = e
65}
66
67func (prc *BaseParserRuleContext) GetChildren() []Tree {
68	return prc.children
69}
70
71func (prc *BaseParserRuleContext) CopyFrom(ctx *BaseParserRuleContext) {
72	// from RuleContext
73	prc.parentCtx = ctx.parentCtx
74	prc.invokingState = ctx.invokingState
75	prc.children = nil
76	prc.start = ctx.start
77	prc.stop = ctx.stop
78}
79
80func (prc *BaseParserRuleContext) GetText() string {
81	if prc.GetChildCount() == 0 {
82		return ""
83	}
84
85	var s string
86	for _, child := range prc.children {
87		s += child.(ParseTree).GetText()
88	}
89
90	return s
91}
92
93// Double dispatch methods for listeners
94func (prc *BaseParserRuleContext) EnterRule(listener ParseTreeListener) {
95}
96
97func (prc *BaseParserRuleContext) ExitRule(listener ParseTreeListener) {
98}
99
100// * Does not set parent link other add methods do that///
101func (prc *BaseParserRuleContext) addTerminalNodeChild(child TerminalNode) TerminalNode {
102	if prc.children == nil {
103		prc.children = make([]Tree, 0)
104	}
105	if child == nil {
106		panic("Child may not be null")
107	}
108	prc.children = append(prc.children, child)
109	return child
110}
111
112func (prc *BaseParserRuleContext) AddChild(child RuleContext) RuleContext {
113	if prc.children == nil {
114		prc.children = make([]Tree, 0)
115	}
116	if child == nil {
117		panic("Child may not be null")
118	}
119	prc.children = append(prc.children, child)
120	return child
121}
122
123// * Used by EnterOuterAlt to toss out a RuleContext previously added as
124// we entered a rule. If we have // label, we will need to remove
125// generic ruleContext object.
126// /
127func (prc *BaseParserRuleContext) RemoveLastChild() {
128	if prc.children != nil && len(prc.children) > 0 {
129		prc.children = prc.children[0 : len(prc.children)-1]
130	}
131}
132
133func (prc *BaseParserRuleContext) AddTokenNode(token Token) *TerminalNodeImpl {
134
135	node := NewTerminalNodeImpl(token)
136	prc.addTerminalNodeChild(node)
137	node.parentCtx = prc
138	return node
139
140}
141
142func (prc *BaseParserRuleContext) AddErrorNode(badToken Token) *ErrorNodeImpl {
143	node := NewErrorNodeImpl(badToken)
144	prc.addTerminalNodeChild(node)
145	node.parentCtx = prc
146	return node
147}
148
149func (prc *BaseParserRuleContext) GetChild(i int) Tree {
150	if prc.children != nil && len(prc.children) >= i {
151		return prc.children[i]
152	}
153
154	return nil
155}
156
157func (prc *BaseParserRuleContext) GetChildOfType(i int, childType reflect.Type) RuleContext {
158	if childType == nil {
159		return prc.GetChild(i).(RuleContext)
160	}
161
162	for j := 0; j < len(prc.children); j++ {
163		child := prc.children[j]
164		if reflect.TypeOf(child) == childType {
165			if i == 0 {
166				return child.(RuleContext)
167			}
168
169			i--
170		}
171	}
172
173	return nil
174}
175
176func (prc *BaseParserRuleContext) ToStringTree(ruleNames []string, recog Recognizer) string {
177	return TreesStringTree(prc, ruleNames, recog)
178}
179
180func (prc *BaseParserRuleContext) GetRuleContext() RuleContext {
181	return prc
182}
183
184func (prc *BaseParserRuleContext) Accept(visitor ParseTreeVisitor) interface{} {
185	return visitor.VisitChildren(prc)
186}
187
188func (prc *BaseParserRuleContext) SetStart(t Token) {
189	prc.start = t
190}
191
192func (prc *BaseParserRuleContext) GetStart() Token {
193	return prc.start
194}
195
196func (prc *BaseParserRuleContext) SetStop(t Token) {
197	prc.stop = t
198}
199
200func (prc *BaseParserRuleContext) GetStop() Token {
201	return prc.stop
202}
203
204func (prc *BaseParserRuleContext) GetToken(ttype int, i int) TerminalNode {
205
206	for j := 0; j < len(prc.children); j++ {
207		child := prc.children[j]
208		if c2, ok := child.(TerminalNode); ok {
209			if c2.GetSymbol().GetTokenType() == ttype {
210				if i == 0 {
211					return c2
212				}
213
214				i--
215			}
216		}
217	}
218	return nil
219}
220
221func (prc *BaseParserRuleContext) GetTokens(ttype int) []TerminalNode {
222	if prc.children == nil {
223		return make([]TerminalNode, 0)
224	}
225
226	tokens := make([]TerminalNode, 0)
227
228	for j := 0; j < len(prc.children); j++ {
229		child := prc.children[j]
230		if tchild, ok := child.(TerminalNode); ok {
231			if tchild.GetSymbol().GetTokenType() == ttype {
232				tokens = append(tokens, tchild)
233			}
234		}
235	}
236
237	return tokens
238}
239
240func (prc *BaseParserRuleContext) GetPayload() interface{} {
241	return prc
242}
243
244func (prc *BaseParserRuleContext) getChild(ctxType reflect.Type, i int) RuleContext {
245	if prc.children == nil || i < 0 || i >= len(prc.children) {
246		return nil
247	}
248
249	j := -1 // what element have we found with ctxType?
250	for _, o := range prc.children {
251
252		childType := reflect.TypeOf(o)
253
254		if childType.Implements(ctxType) {
255			j++
256			if j == i {
257				return o.(RuleContext)
258			}
259		}
260	}
261	return nil
262}
263
264// Go lacks generics, so it's not possible for us to return the child with the correct type, but we do
265// check for convertibility
266
267func (prc *BaseParserRuleContext) GetTypedRuleContext(ctxType reflect.Type, i int) RuleContext {
268	return prc.getChild(ctxType, i)
269}
270
271func (prc *BaseParserRuleContext) GetTypedRuleContexts(ctxType reflect.Type) []RuleContext {
272	if prc.children == nil {
273		return make([]RuleContext, 0)
274	}
275
276	contexts := make([]RuleContext, 0)
277
278	for _, child := range prc.children {
279		childType := reflect.TypeOf(child)
280
281		if childType.ConvertibleTo(ctxType) {
282			contexts = append(contexts, child.(RuleContext))
283		}
284	}
285	return contexts
286}
287
288func (prc *BaseParserRuleContext) GetChildCount() int {
289	if prc.children == nil {
290		return 0
291	}
292
293	return len(prc.children)
294}
295
296func (prc *BaseParserRuleContext) GetSourceInterval() *Interval {
297	if prc.start == nil || prc.stop == nil {
298		return TreeInvalidInterval
299	}
300
301	return NewInterval(prc.start.GetTokenIndex(), prc.stop.GetTokenIndex())
302}
303
304//need to manage circular dependencies, so export now
305
306// Print out a whole tree, not just a node, in LISP format
307// (root child1 .. childN). Print just a node if b is a leaf.
308//
309
310func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) string {
311
312	var p ParserRuleContext = prc
313	s := "["
314	for p != nil && p != stop {
315		if ruleNames == nil {
316			if !p.IsEmpty() {
317				s += strconv.Itoa(p.GetInvokingState())
318			}
319		} else {
320			ri := p.GetRuleIndex()
321			var ruleName string
322			if ri >= 0 && ri < len(ruleNames) {
323				ruleName = ruleNames[ri]
324			} else {
325				ruleName = strconv.Itoa(ri)
326			}
327			s += ruleName
328		}
329		if p.GetParent() != nil && (ruleNames != nil || !p.GetParent().(ParserRuleContext).IsEmpty()) {
330			s += " "
331		}
332		pi := p.GetParent()
333		if pi != nil {
334			p = pi.(ParserRuleContext)
335		} else {
336			p = nil
337		}
338	}
339	s += "]"
340	return s
341}
342
343var RuleContextEmpty = NewBaseParserRuleContext(nil, -1)
344
345type InterpreterRuleContext interface {
346	ParserRuleContext
347}
348
349type BaseInterpreterRuleContext struct {
350	*BaseParserRuleContext
351}
352
353func NewBaseInterpreterRuleContext(parent BaseInterpreterRuleContext, invokingStateNumber, ruleIndex int) *BaseInterpreterRuleContext {
354
355	prc := new(BaseInterpreterRuleContext)
356
357	prc.BaseParserRuleContext = NewBaseParserRuleContext(parent, invokingStateNumber)
358
359	prc.RuleIndex = ruleIndex
360
361	return prc
362}
363