/*
 [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 org.antlr.stringtemplate.*;
import org.antlr.stringtemplate.language.*;
import java.util.HashMap;
>>

/** Add this to each rule's return value struct */
@returnScope.ruleReturnMembers() ::= <<
public StringTemplate st;
public Object getTemplate() { return st; }
public String toString() { return st==null?null:st.toString(); }
>>

@genericParser.members() ::= <<
<@super.members()>
protected StringTemplateGroup templateLib =
  new StringTemplateGroup("<name>Templates", AngleBracketTemplateLexer.class);

public void setTemplateLib(StringTemplateGroup templateLib) {
  this.templateLib = templateLib;
}
public StringTemplateGroup getTemplateLib() {
  return templateLib;
}
/** allows convenient multi-value initialization:
 *  "new STAttrMap().put(...).put(...)"
 */
public static class STAttrMap extends HashMap {
  public STAttrMap put(String attrName, Object value) {
    super.put(attrName, value);
    return this;
  }
  public STAttrMap put(String attrName, int value) {
    super.put(attrName, new Integer(value));
    return this;
  }
}
>>

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

rewriteTemplate(alts) ::= <<

// TEMPLATE REWRITE
<if(backtracking)>
if ( <actions.(actionScope).synpredgate> ) {
  <alts:rewriteTemplateAlt(); separator="else ">
  <if(rewriteMode)><replaceTextInLine()><endif>
}
<else>
<alts:rewriteTemplateAlt(); separator="else ">
<if(rewriteMode)><replaceTextInLine()><endif>
<endif>
>>

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

rewriteTemplateAlt(alt) ::= <<
// <alt.description>
<if(alt.pred)>
if (<alt.pred>) {
    retval.st = <alt.alt>;
}<\n>
<else>
{
    retval.st = <alt.alt>;
}<\n>
<endif>
>>

rewriteEmptyTemplate(alts) ::= <<
null;
>>

/** 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) ::= <%
templateLib.getInstanceOf("<name>"<if(args)>,
  new STAttrMap()<args:{a | .put("<a.name>", <a.value>)}>
  <endif>)
%>

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

/** Invoke an inline template with a set of attribute name/value pairs */
rewriteInlineTemplate(args, template) ::= <%
new StringTemplate(templateLib, "<template>"<if(args)>,
  new STAttrMap()<args:{a | .put("<a.name>", <a.value>)}>
  <endif>)
%>

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

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

/** Translate %{stringExpr} */
actionStringConstructor(stringExpr) ::= <<
new StringTemplate(templateLib,<stringExpr>)
>>
