/*
 * [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 )
{
	<createListenerAndHandshake()>
	<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>( input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}> );}; separator="\n">
	<parserCtorBody()>
	<@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);
	<grammar.directDelegates:
	 {g|<g:delegateName()> = new <g.recognizerName>( input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}> );}; separator="\n">
	<parserCtorBody()>
	<@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 )
{
	<grammar.directDelegates:
	 {g|<g:delegateName()> = new <g.recognizerName>( input, this, this.state<grammar.delegators:{g|, <g:delegateName()>}> );}; separator="\n">
	<parserCtorBody()>
}<\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>
	<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
	<parserCtorBody()>
	<@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>")
>>
