package org.scribble.visit;
import org.scribble.ast.ProtocolDef;
import org.scribble.ast.ScribNode;
import org.scribble.del.ProtocolDefDel;
import org.scribble.main.Job;
import org.scribble.main.ScribbleException;
import org.scribble.visit.env.Env;
public abstract class InlinedProtocolVisitor<T extends Env<?>> extends EnvVisitor<T>
{
public InlinedProtocolVisitor(Job job)
{
super(job);
}
@Override
public ScribNode visit(ScribNode parent, ScribNode child) throws ScribbleException
{
enter(parent, child);
ScribNode visited = visitInlinedProtocol(parent, child);
return leave(parent, child, visited);
}
protected ScribNode visitInlinedProtocol(ScribNode parent, ScribNode child) throws ScribbleException
{
if (child instanceof ProtocolDef)
{
return visitOverrideForProtocolDef(parent, (ProtocolDef<?>) child); // parent is InteractionSequence
}
else
{
return child.visitChildren(this);
// The base (super) behaviour (could factor it out in ModelVisitor as its own visitor method) -- not super.visit because that does enter/exit
}
}
// N.B. results of visiting inlined version are stored back to inlined field, but original AST is unaffected -- so any Env/Del or AST updates to inlined version do not reflect back onto original AST -- a motivation for the original SubprotocolVisitor approach
private ScribNode visitOverrideForProtocolDef(ScribNode parent, ProtocolDef<?> pd) throws ScribbleException
{
ProtocolDef<?> inlined = ((ProtocolDefDel) pd.del()).getInlinedProtocolDef();
if (inlined == null)
{
throw new ScribbleException("InlineProtocolVisitor error: " + pd); // E.g. -fsm when inconsistent choice subjects
// FIXME: shouldn't occur any more?
}
/*if (this instanceof EndpointGraphBuilder)
{
System.out.println("\nBuilding graph from: " + inlined + "\n");
}*/
ProtocolDef<?> visited = (ProtocolDef<?>) inlined.visitChildren(this);
ProtocolDefDel del = (ProtocolDefDel) pd.del();
return pd.del(del.setInlinedProtocolDef(visited));
}
@Override
protected final void envEnter(ScribNode parent, ScribNode child) throws ScribbleException
{
super.envEnter(parent, child);
inlinedEnter(parent, child);
}
@Override
protected final ScribNode envLeave(ScribNode parent, ScribNode child, ScribNode visited) throws ScribbleException
{
ScribNode n = inlinedLeave(parent, child, visited);
return super.envLeave(parent, child, n);
}
protected void inlinedEnter(ScribNode parent, ScribNode child) throws ScribbleException
{
}
protected ScribNode inlinedLeave(ScribNode parent, ScribNode child, ScribNode visited) throws ScribbleException
{
return visited;
}
}