/*
 [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 subgroup to add template rewrite output
 *  If debugging, then you'll also get STDbg.stg loaded.
 */

@outputFile.imports() ::= <<
<@super.imports()>
import stringtemplate3
>>

/** Add this to each rule's return value struct */
@returnScope.ruleReturnInit() ::= <<
self.st = None
>>

@returnScope.ruleReturnMembers() ::= <<
def getTemplate(self):
    return self.st

def toString(self):
    if self.st is not None:
        return self.st.toString()
    return None
__str__ = toString

>>

@genericParser.init() ::= <<
<@super.init()>
self.templateLib = stringtemplate3.StringTemplateGroup(
    '<name>Templates', lexer='angle-bracket'
    )

>>

@genericParser.members() ::= <<
<@super.members()>
def setTemplateLib(self, templateLib):
    self.templateLib = templateLib

def getTemplateLib(self):
    return self.templateLib

>>

/** x+=rule when output=template */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRef(...)>
<listLabel(label, {<label>.st})>
>>

rewriteTemplate(alts) ::= <<
# TEMPLATE REWRITE
<if(backtracking)>
if <actions.(actionScope).synpredgate>:
    <first(alts):rewriteTemplateAltFirst()>
    <rest(alts):{it | el<rewriteTemplateAlt(it)>}>
    <if(rewriteMode)><replaceTextInLine()><endif>

<else>
<first(alts):rewriteTemplateAltFirst()>
<rest(alts):{it | el<rewriteTemplateAlt(it)>}>
<if(rewriteMode)><replaceTextInLine()><endif>
<endif>
>>

replaceTextInLine() ::= <<
<if(TREE_PARSER)>
self.input.getTokenStream().replace(
    self.input.getTreeAdaptor().getTokenStartIndex(retval.start),
    self.input.getTreeAdaptor().getTokenStopIndex(retval.start),
    retval.st
    )
<else>
self.input.replace(
    retval.start.getTokenIndex(),
    self.input.LT(-1).getTokenIndex(),
    retval.st
    )
<endif>
>>

rewriteTemplateAltFirst(alt) ::= <<
<if(alt.pred)>
if <alt.pred>:
    # <alt.description>
    retval.st = <alt.alt>
<\n>
<else>
# <alt.description>
retval.st = <alt.alt>
<\n>
<endif>
>>

rewriteTemplateAlt(alt) ::= <<
<if(alt.pred)>if <alt.pred>:
    # <alt.description>
    retval.st = <alt.alt>
<\n>
<else>se:
    # <alt.description>
    retval.st = <alt.alt>
<\n>
<endif>
>>

rewriteEmptyTemplate(alts) ::= <<
None
>>

/** Invoke a template with a set of attribute name/value pairs.
 *  Set the value of the rule's template *after* having set
 *  the attributes because the rule's template might be used as
 *  an attribute to build a bigger template; you get a self-embedded
 *  template.
 */
rewriteExternalTemplate(name,args) ::= <%
self.templateLib.getInstanceOf("<name>"<if(args)>, attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}<endif>)
%>

/** expr is a string expression that says what template to load */
rewriteIndirectTemplate(expr,args) ::= <%
self.templateLib.getInstanceOf(<expr><if(args)>, attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}<endif>)
%>

/** Invoke an inline template with a set of attribute name/value pairs */
rewriteInlineTemplate(args, template) ::= <%
stringtemplate3.StringTemplate("<template>", group=self.templateLib<if(args)>, attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}<endif>)
%>

/** plain -> {foo} action */
rewriteAction(action) ::= <<
<action>
>>

/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
actionSetAttribute(st,attrName,expr) ::= <<
(<st>)["<attrName>"] = <expr>
>>

/** Translate %{stringExpr} */
actionStringConstructor(stringExpr) ::= <<
stringtemplate3.StringTemplate(<stringExpr>, group=self.templateLib)
>>
