/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.template.soy.soytree;
import com.google.template.soy.basetree.AbstractNodeVisitor;
import com.google.template.soy.basetree.ParentNode;
import com.google.template.soy.soytree.SoyNode.LoopNode;
import com.google.template.soy.soytree.SoyNode.MsgSubstUnitNode;
import com.google.template.soy.soytree.SoyNode.ParentSoyNode;
/**
* Abstract base class for all SoyNode visitors. A visitor is basically a function implemented for
* some or all SoyNodes, where the implementation can be different for each specific node class.
*
* <p>Same as {@link AbstractReturningSoyNodeVisitor} except that in this class, internal {@code
* visit()} calls do not return a value.
*
* <p>Important: Do not use outside of Soy code (treat as superpackage-private).
*
* <p>To create a visitor:
*
* <ol>
* <li> Subclass this class.
* <li> Implement {@code visit*Node()} methods for some specific node types.
* <li> Implement fallback methods for node types not specifically handled. The most general
* fallback method is {@link #visitSoyNode visitSoyNode()}, which is usually needed. Other
* fallback methods include {@code visitLoopNode()} and {@code visitCallParamNode()}.
* <li> Maybe implement a constructor, taking appropriate parameters for your visitor call.
* <li> Maybe implement {@link #exec exec()} if this visitor needs to return a non-null final
* result and/or if this visitor has state that needs to be setup/reset before each unrelated
* use of {@code visit()}.
* </ol>
*
* @param <R> The return type of this visitor.
* @see AbstractReturningSoyNodeVisitor
*/
public abstract class AbstractSoyNodeVisitor<R> extends AbstractNodeVisitor<SoyNode, R> {
@Override
protected void visit(SoyNode node) {
switch (node.getKind()) {
case SOY_FILE_SET_NODE:
visitSoyFileSetNode((SoyFileSetNode) node);
break;
case SOY_FILE_NODE:
visitSoyFileNode((SoyFileNode) node);
break;
case TEMPLATE_BASIC_NODE:
visitTemplateBasicNode((TemplateBasicNode) node);
break;
case TEMPLATE_DELEGATE_NODE:
visitTemplateDelegateNode((TemplateDelegateNode) node);
break;
case RAW_TEXT_NODE:
visitRawTextNode((RawTextNode) node);
break;
case MSG_FALLBACK_GROUP_NODE:
visitMsgFallbackGroupNode((MsgFallbackGroupNode) node);
break;
case MSG_NODE:
visitMsgNode((MsgNode) node);
break;
case MSG_PLURAL_NODE:
visitMsgPluralNode((MsgPluralNode) node);
break;
case MSG_PLURAL_CASE_NODE:
visitMsgPluralCaseNode((MsgPluralCaseNode) node);
break;
case MSG_PLURAL_DEFAULT_NODE:
visitMsgPluralDefaultNode((MsgPluralDefaultNode) node);
break;
case MSG_SELECT_NODE:
visitMsgSelectNode((MsgSelectNode) node);
break;
case MSG_SELECT_CASE_NODE:
visitMsgSelectCaseNode((MsgSelectCaseNode) node);
break;
case MSG_SELECT_DEFAULT_NODE:
visitMsgSelectDefaultNode((MsgSelectDefaultNode) node);
break;
case MSG_PLACEHOLDER_NODE:
visitMsgPlaceholderNode((MsgPlaceholderNode) node);
break;
case MSG_HTML_TAG_NODE:
visitMsgHtmlTagNode((MsgHtmlTagNode) node);
break;
case PRINT_NODE:
visitPrintNode((PrintNode) node);
break;
case PRINT_DIRECTIVE_NODE:
visitPrintDirectiveNode((PrintDirectiveNode) node);
break;
case CSS_NODE:
visitCssNode((CssNode) node);
break;
case XID_NODE:
visitXidNode((XidNode) node);
break;
case LET_VALUE_NODE:
visitLetValueNode((LetValueNode) node);
break;
case LET_CONTENT_NODE:
visitLetContentNode((LetContentNode) node);
break;
case IF_NODE:
visitIfNode((IfNode) node);
break;
case IF_COND_NODE:
visitIfCondNode((IfCondNode) node);
break;
case IF_ELSE_NODE:
visitIfElseNode((IfElseNode) node);
break;
case SWITCH_NODE:
visitSwitchNode((SwitchNode) node);
break;
case SWITCH_CASE_NODE:
visitSwitchCaseNode((SwitchCaseNode) node);
break;
case SWITCH_DEFAULT_NODE:
visitSwitchDefaultNode((SwitchDefaultNode) node);
break;
case FOREACH_NODE:
visitForeachNode((ForeachNode) node);
break;
case FOREACH_NONEMPTY_NODE:
visitForeachNonemptyNode((ForeachNonemptyNode) node);
break;
case FOREACH_IFEMPTY_NODE:
visitForeachIfemptyNode((ForeachIfemptyNode) node);
break;
case FOR_NODE:
visitForNode((ForNode) node);
break;
case CALL_BASIC_NODE:
visitCallBasicNode((CallBasicNode) node);
break;
case CALL_DELEGATE_NODE:
visitCallDelegateNode((CallDelegateNode) node);
break;
case CALL_PARAM_VALUE_NODE:
visitCallParamValueNode((CallParamValueNode) node);
break;
case CALL_PARAM_CONTENT_NODE:
visitCallParamContentNode((CallParamContentNode) node);
break;
case HTML_CLOSE_TAG_NODE:
visitHtmlCloseTagNode((HtmlCloseTagNode) node);
break;
case HTML_OPEN_TAG_NODE:
visitHtmlOpenTagNode((HtmlOpenTagNode) node);
break;
case HTML_ATTRIBUTE_NODE:
visitHtmlAttributeNode((HtmlAttributeNode) node);
break;
case HTML_ATTRIBUTE_VALUE_NODE:
visitHtmlAttributeValueNode((HtmlAttributeValueNode) node);
break;
case LOG_NODE:
visitLogNode((LogNode) node);
break;
case DEBUGGER_NODE:
visitDebuggerNode((DebuggerNode) node);
break;
default:
visitSoyNode(node);
break;
}
}
/**
* Helper to visit all the children of a node, in order.
*
* @param node The parent node whose children to visit.
* @see #visitChildrenAllowingConcurrentModification
*/
protected void visitChildren(ParentSoyNode<?> node) {
visitChildren((ParentNode<? extends SoyNode>) node);
}
/**
* Helper to visit all the children of a node, in order.
*
* <p>This method differs from {@code visitChildren} in that we are iterating through a copy of
* the children. Thus, concurrent modification of the list of children is allowed.
*
* @param node The parent node whose children to visit.
* @see #visitChildren
*/
protected void visitChildrenAllowingConcurrentModification(ParentSoyNode<?> node) {
visitChildrenAllowingConcurrentModification((ParentNode<? extends SoyNode>) node);
}
// -----------------------------------------------------------------------------------------------
// Implementations for concrete nodes.
protected void visitSoyFileSetNode(SoyFileSetNode node) {
visitSoyNode(node);
}
protected void visitSoyFileNode(SoyFileNode node) {
visitSoyNode(node);
}
protected void visitTemplateBasicNode(TemplateBasicNode node) {
visitTemplateNode(node);
}
protected void visitTemplateDelegateNode(TemplateDelegateNode node) {
visitTemplateNode(node);
}
protected void visitTemplateNode(TemplateNode node) {
visitSoyNode(node);
}
protected void visitRawTextNode(RawTextNode node) {
visitSoyNode(node);
}
protected void visitMsgFallbackGroupNode(MsgFallbackGroupNode node) {
visitSoyNode(node);
}
protected void visitMsgNode(MsgNode node) {
visitSoyNode(node);
}
protected void visitMsgPluralNode(MsgPluralNode node) {
visitMsgSubstUnitNode(node);
}
protected void visitMsgPluralCaseNode(MsgPluralCaseNode node) {
visitSoyNode(node);
}
protected void visitMsgPluralDefaultNode(MsgPluralDefaultNode node) {
visitSoyNode(node);
}
protected void visitMsgSelectNode(MsgSelectNode node) {
visitMsgSubstUnitNode(node);
}
protected void visitMsgSelectCaseNode(MsgSelectCaseNode node) {
visitSoyNode(node);
}
protected void visitMsgSelectDefaultNode(MsgSelectDefaultNode node) {
visitSoyNode(node);
}
protected void visitMsgPlaceholderNode(MsgPlaceholderNode node) {
visitMsgSubstUnitNode(node);
}
protected void visitMsgHtmlTagNode(MsgHtmlTagNode node) {
visitSoyNode(node);
}
protected void visitMsgSubstUnitNode(MsgSubstUnitNode node) {
visitSoyNode(node);
}
protected void visitPrintNode(PrintNode node) {
visitSoyNode(node);
}
protected void visitPrintDirectiveNode(PrintDirectiveNode node) {
visitSoyNode(node);
}
protected void visitCssNode(CssNode node) {
visitSoyNode(node);
}
protected void visitXidNode(XidNode node) {
visitSoyNode(node);
}
protected void visitLetValueNode(LetValueNode node) {
visitLetNode(node);
}
protected void visitLetContentNode(LetContentNode node) {
visitLetNode(node);
}
protected void visitLetNode(LetNode node) {
visitSoyNode(node);
}
protected void visitIfNode(IfNode node) {
visitSoyNode(node);
}
protected void visitIfCondNode(IfCondNode node) {
visitSoyNode(node);
}
protected void visitIfElseNode(IfElseNode node) {
visitSoyNode(node);
}
protected void visitSwitchNode(SwitchNode node) {
visitSoyNode(node);
}
protected void visitSwitchCaseNode(SwitchCaseNode node) {
visitSoyNode(node);
}
protected void visitSwitchDefaultNode(SwitchDefaultNode node) {
visitSoyNode(node);
}
protected void visitForeachNode(ForeachNode node) {
visitSoyNode(node);
}
protected void visitForeachIfemptyNode(ForeachIfemptyNode node) {
visitSoyNode(node);
}
protected void visitForeachNonemptyNode(ForeachNonemptyNode node) {
visitLoopNode(node);
}
protected void visitForNode(ForNode node) {
visitLoopNode(node);
}
protected void visitLoopNode(LoopNode node) {
visitSoyNode(node);
}
protected void visitCallBasicNode(CallBasicNode node) {
visitCallNode(node);
}
protected void visitCallDelegateNode(CallDelegateNode node) {
visitCallNode(node);
}
protected void visitCallNode(CallNode node) {
visitSoyNode(node);
}
protected void visitCallParamValueNode(CallParamValueNode node) {
visitCallParamNode(node);
}
protected void visitCallParamContentNode(CallParamContentNode node) {
visitCallParamNode(node);
}
protected void visitCallParamNode(CallParamNode node) {
visitSoyNode(node);
}
protected void visitHtmlOpenTagNode(HtmlOpenTagNode node) {
visitSoyNode(node);
}
protected void visitHtmlCloseTagNode(HtmlCloseTagNode node) {
visitSoyNode(node);
}
protected void visitHtmlAttributeNode(HtmlAttributeNode node) {
visitSoyNode(node);
}
protected void visitHtmlAttributeValueNode(HtmlAttributeValueNode node) {
visitSoyNode(node);
}
protected void visitLogNode(LogNode node) {
visitSoyNode(node);
}
protected void visitDebuggerNode(DebuggerNode node) {
visitSoyNode(node);
}
// -----------------------------------------------------------------------------------------------
// Fallback implementation.
/** @param node the visited node. */
protected void visitSoyNode(SoyNode node) {
throw new UnsupportedOperationException();
}
}