/*
 * [The "BSD license"]
 * Copyright (c) 2007-2008 Johannes Luber
 * Copyright (c) 2005-2007 Kunle Odutola
 * Copyright (c) 2011 Sam Harwell
 * Copyright (c) 2011 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.debugPreprocessor() ::= "#define ANTLR_DEBUG"

@outputFile.imports() ::= <<
<@super.imports()>
using Antlr.Runtime.Debug;
using IOException = System.IO.IOException;
>>

@genericParser.members() ::= <<
<if(grammar.grammarIsRoot)>
public static readonly string[] ruleNames =
	new string[]
	{
		"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n	", separator=", ">
	};<\n>
<endif>
<if(grammar.grammarIsRoot)><! grammar imports other grammar(s) !>
	int ruleLevel = 0;
	public virtual int RuleLevel { get { return ruleLevel; } }
	public virtual void IncRuleLevel() { ruleLevel++; }
	public virtual void DecRuleLevel() { ruleLevel--; }
<if(profile)>
	<ctorForProfilingRootGrammar()>
<else>
	<ctorForRootGrammar()>
<endif>
<ctorForPredefinedListener()>
<else><! imported grammar !>
	public int RuleLevel { get { return <grammar.delegators:{g| <g:delegateName()>}>.RuleLevel; } }
	public void IncRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.IncRuleLevel(); }
	public void DecRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.DecRuleLevel(); }
	<ctorForDelegateGrammar()>
<endif>
<if(profile)>
public override bool AlreadyParsedRule( IIntStream input, int ruleIndex )
{
	int stopIndex = GetRuleMemoization(ruleIndex, input.Index);
	((Profiler)dbg).ExamineRuleMemoization(input, ruleIndex, stopIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
	return base.AlreadyParsedRule(input, ruleIndex);
}<\n>
public override void Memoize( IIntStream input, int ruleIndex, int ruleStartIndex )
{
	((Profiler)dbg).Memoize(input, ruleIndex, ruleStartIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
	base.Memoize(input, ruleIndex, ruleStartIndex);
}<\n>
<endif>
protected virtual bool EvalPredicate( bool 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 !>
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input )
	: this( input, DebugEventSocketProxy.DefaultDebuggerPort, new RecognizerSharedState() )
{
}
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input, int port, RecognizerSharedState state )
	: base( 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 !>
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input )
	: this( input, new Profiler(null), new RecognizerSharedState() )
{
}
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state )
	: base( 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() ::= <<
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}> )
	: base( 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() ::= <<
<actions.(actionScope).ctorModifier; null="public"> <name>( <inputStreamType> input, IDebugEventListener dbg )
	<@superClassRef>: base( 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.TreeAdaptor );<\n>
<else>
DebugEventSocketProxy proxy = new DebugEventSocketProxy( this, port, null );<\n>
<endif>
DebugListener = proxy;
try
{
	proxy.Handshake();
}
catch ( IOException ioe )
{
	ReportError( ioe );
}
>>

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

/*
 * Many of the following rules were merged into CSharp2.stg.
 */

@rule.preamble() ::= <<
if (RuleLevel == 0)
	DebugListener.Commence();
IncRuleLevel();
>>
//@rule.preamble() ::= <<
//try
//{
//	dbg.EnterRule( GrammarFileName, "<ruleName>" );
//	if ( RuleLevel == 0 )
//	{
//		dbg.Commence();
//	}
//	IncRuleLevel();
//	dbg.Location( <ruleDescriptor.tree.line>, <ruleDescriptor.tree.charPositionInLine> );<\n>
//>>

@rule.postamble() ::= <<
DecRuleLevel();
if (RuleLevel == 0)
	DebugListener.Terminate();
>>
//@rule.postamble() ::= <<
//dbg.Location(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.charPositionInLine>);<\n>
//}
//finally
//{
//	dbg.ExitRule( GrammarFileName, "<ruleName>" );
//	DecRuleLevel();
//	if ( RuleLevel == 0 )
//	{
//		dbg.Terminate();
//	}
//}<\n>
//>>

//@insertSynpreds.start() ::= "dbg.BeginBacktrack( state.backtracking );"
//@insertSynpreds.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> );<\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<decisionNumber> );<\n>"

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

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

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

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

//@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"

//@element.prematch() ::=
//	"dbg.Location( <it.line>, <it.pos> );"

//@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 override void Error( NoViableAltException nvae )
//{
//	((DebugParser)recognizer).dbg.RecognitionException( nvae );
//}
//>>

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