/*
 [The "BSD license"]
 Copyright (c) 2005-2006 Terence Parr
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** Template overrides to add debugging to normal Java output;
 *  If ASTs are built, then you'll also get ASTDbg.stg loaded.
 */
@outputFile.imports() ::= <<
<@super.imports()>
import org.antlr.runtime.debug.*;
import java.io.IOException;
>>

@genericParser.members() ::= <<
<if(grammar.grammarIsRoot)>
	public static final String[] ruleNames = new String[] {
		"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n\t\t", separator=", ">
	};<\n>
<endif>
	public static final boolean[] decisionCanBacktrack = new boolean[] {
		false, // invalid decision
		<grammar.decisions:{d | <d.dfa.hasSynPred; null="false">}; wrap="\n    ", separator=", ">
	};<\n>
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
	public int ruleLevel = 0;
	public int getRuleLevel() { return ruleLevel; }
	public void incRuleLevel() { ruleLevel++; }
	public void decRuleLevel() { ruleLevel--; }
<if(profile)>
	<ctorForProfilingRootGrammar()>
<else>
	<ctorForRootGrammar()>
<endif>
	<ctorForPredefinedListener()>
<else><! imported grammar !>
	public int getRuleLevel() { return <grammar.delegators:{g| <g:delegateName()>}>.getRuleLevel(); }
	public void incRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.incRuleLevel(); }
	public void decRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel(); }
	<ctorForDelegateGrammar()>
<endif>
<if(profile)>
	public boolean alreadyParsedRule(IntStream input, int ruleIndex) {
		int stopIndex = getRuleMemoization(ruleIndex, input.index());
		((Profiler)dbg).examineRuleMemoization(input, ruleIndex, stopIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
		return super.alreadyParsedRule(input, ruleIndex);
	}

	@Override
	public void memoize(IntStream input,
						int ruleIndex,
						int ruleStartIndex)
	{
		((Profiler)dbg).memoize(input, ruleIndex, ruleStartIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
		super.memoize(input, ruleIndex, ruleStartIndex);
	}<\n>
<endif>
	protected boolean evalPredicate(boolean result, String predicate) {
		dbg.semanticPredicate(result, predicate);
		return result;
	}<\n>
>>

ctorForRootGrammar() ::= <<
<! bug: can't use <@super.members()> cut-n-paste instead !>
<! Same except we add port number and profile stuff if root grammar !>
public <name>(<inputStreamType> input) {
	this(input, DebugEventSocketProxy.DEFAULT_DEBUGGER_PORT, new RecognizerSharedState());
}
public <name>(<inputStreamType> input, int port, RecognizerSharedState state) {
	super(input, state);
	<parserCtorBody()>
	<createListenerAndHandshake()>
	<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
	<@finally()>
}<\n>
>>

ctorForProfilingRootGrammar() ::= <<
<! bug: can't use <@super.members()> cut-n-paste instead !>
public <name>(<inputStreamType> input) {
	this(input, new Profiler(null), new RecognizerSharedState());
}
public <name>(<inputStreamType> input, DebugEventListener dbg, RecognizerSharedState state) {
	super(input, dbg, state);
	Profiler p = (Profiler)dbg;
	p.setParser(this);
	<parserCtorBody()>
	<grammar.directDelegates:
		{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
	<@finally()>
}
<\n>
>>

/** Basically we don't want to set any dbg listeners are root will have it. */
ctorForDelegateGrammar() ::= <<
public <name>(<inputStreamType> input, DebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
	super(input, dbg, state);
	<parserCtorBody()>
	<grammar.directDelegates:
		{g|<g:delegateName()> = new <g.recognizerName>(input, this, this.state<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
}<\n>
>>

ctorForPredefinedListener() ::= <<
public <name>(<inputStreamType> input, DebugEventListener dbg) {
	<@superClassRef>super(input, dbg, new RecognizerSharedState());<@end>
<if(profile)>
	Profiler p = (Profiler)dbg;
	p.setParser(this);
<endif>
	<parserCtorBody()>
	<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
	<@finally()>
}<\n>
>>

createListenerAndHandshake() ::= <<
<if(TREE_PARSER)>
DebugEventSocketProxy proxy =
	new DebugEventSocketProxy(this, port, input.getTreeAdaptor());<\n>
<else>
DebugEventSocketProxy proxy =
	new DebugEventSocketProxy(this, port, null);<\n>
<endif>
setDebugListener(proxy);
try {
	proxy.handshake();
}
catch (IOException ioe) {
	reportError(ioe);
}
>>

@genericParser.superClassName() ::= "Debug<@super.superClassName()>"

@rule.preamble() ::= <<
try { dbg.enterRule(getGrammarFileName(), "<ruleName>");
if ( getRuleLevel()==0 ) {dbg.commence();}
incRuleLevel();
dbg.location(<ruleDescriptor.tree.line>, <ruleDescriptor.tree.charPositionInLine>);<\n>
>>

@rule.postamble() ::= <<
dbg.location(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.charPositionInLine>);<\n>
}
finally {
	dbg.exitRule(getGrammarFileName(), "<ruleName>");
	decRuleLevel();
	if ( getRuleLevel()==0 ) {dbg.terminate();}
}<\n>
>>

@synpred.start() ::= "dbg.beginBacktrack(state.backtracking);"

@synpred.stop() ::= "dbg.endBacktrack(state.backtracking, success);"

// Common debug event triggers used by region overrides below

enterSubRule() ::=
	"try { dbg.enterSubRule(<decisionNumber>);<\n>"

exitSubRule() ::=
	"} finally {dbg.exitSubRule(<decisionNumber>);}<\n>"

enterDecision() ::=
	"try { dbg.enterDecision(<decisionNumber>, decisionCanBacktrack[<decisionNumber>]);<\n>"

exitDecision() ::=
	"} finally {dbg.exitDecision(<decisionNumber>);}<\n>"

enterAlt(n) ::= "dbg.enterAlt(<n>);<\n>"

// Region overrides that tell various constructs to add debugging triggers

@block.predecision() ::= "<enterSubRule()><enterDecision()>"

@block.postdecision() ::= "<exitDecision()>"

@block.postbranch() ::= "<exitSubRule()>"

@ruleBlock.predecision() ::= "<enterDecision()>"

@ruleBlock.postdecision() ::= "<exitDecision()>"

@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"

@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"

@positiveClosureBlock.preloop() ::= "<enterSubRule()>"

@positiveClosureBlock.postloop() ::= "<exitSubRule()>"

@positiveClosureBlock.predecision() ::= "<enterDecision()>"

@positiveClosureBlock.postdecision() ::= "<exitDecision()>"

@positiveClosureBlock.earlyExitException() ::=
	"dbg.recognitionException(eee);<\n>"

@closureBlock.preloop() ::= "<enterSubRule()>"

@closureBlock.postloop() ::= "<exitSubRule()>"

@closureBlock.predecision() ::= "<enterDecision()>"

@closureBlock.postdecision() ::= "<exitDecision()>"

@altSwitchCase.prealt() ::= "<enterAlt(altNum)>" // altNum is arg of altSwitchCase

@element.prematch() ::=
	"dbg.location(<e.line>,<e.pos>);" // e is arg of element

@matchSet.mismatchedSetException() ::=
	"dbg.recognitionException(mse);"

@dfaState.noViableAltException() ::= "dbg.recognitionException(nvae);"

@dfaStateSwitch.noViableAltException() ::= "dbg.recognitionException(nvae);"

dfaDecision(decisionNumber,description) ::= <<
try {
	isCyclicDecision = true;
	<super.dfaDecision(...)>
}
catch (NoViableAltException nvae) {
	dbg.recognitionException(nvae);
	throw nvae;
}
>>

@cyclicDFA.errorMethod() ::= <<
public void error(NoViableAltException nvae) {
	dbg.recognitionException(nvae);
}
>>

/** Force predicate validation to trigger an event */
evalPredicate(pred,description) ::= <<
evalPredicate(<pred>,"<description>")
>>
