package org.scribble.ast;
import java.util.LinkedList;
import java.util.List;
import org.antlr.runtime.tree.CommonTree;
import org.scribble.ast.name.simple.RoleNode;
// Maybe factor out a base class with MessageTransfer (the list of dest roles has a different meaning though)
// Can't use abstract/reconstruct pattern, LocalInterrupt has different arguments -- add dummy dests field here to make reconstruct work?
public class Interrupt extends ScribNodeBase//AbstractSimpleInteractionNode
{
public final RoleNode src;
private final List<MessageNode> msgs;
protected Interrupt(CommonTree source, RoleNode src, List<MessageNode> msgs)
{
super(source);
this.src = src;
this.msgs = new LinkedList<>(msgs);
}
@Override
protected ScribNodeBase copy()
{
// TODO Auto-generated method stub
throw new RuntimeException("TODO: " + this);
}
@Override
public Interrupt clone()
{
// TODO Auto-generated method stub
throw new RuntimeException("TODO: " + this);
}
public List<MessageNode> getMessages()
{
return this.msgs;
}
//protected abstract Interrupt reconstruct(CommonTree ct, RoleNode src, List<MessageNode> msgs, GlobalInterruptContext ncontext, Env env);
/*@Override
public Interrupt leaveWFChoiceCheck(WellFormedChoiceChecker checker) throws ScribbleException
{
Role src = this.src.toName();
WellFormedChoiceEnv env = checker.getEnv();
for (Message msg : this.msgs.stream().map((mn) -> mn.toMessage()).collect(Collectors.toList()))
{
for (Role dest : ((GlobalInterruptContext) getContext()).getDestinations())
{
// Recorded in the interruptible env (not the block or the parent)
//checker.setEnv(checker.getEnv().addInterrupt(src, dest, msg.toScopedMessage(checker.getScope()))); // No: src must be enabled, and if receiver may be enabled by this interrupt then it must also be receiving normally inside the interruptible block
//checker.getEnv().addMessage(src, dest, msg);
env = env.addInterrupt(src, dest, msg.toScopedMessage(checker.getScope()));
}
}
checker.setEnv(env);
return this;
}
/*@Override
public Interrupt leave(EnvVisitor nv) throws ScribbleException
{
Interrupt gi = (Interrupt) super.leave(nv);
Env env = nv.getEnv();
Role src = gi.src.toName();
List<Role> tmp = new LinkedList<>(gi.dests); // For GlobalInterrupt, won't work till after well-formedness checked
tmp.remove(src);
for (MessageNode msg : this.msgs)
{
for (Role dest : tmp)
{
env.ops.addOperator(src, dest, msg.getOperator());
}
}
return gi;
}
@Override
public Interrupt substitute(Substitutor subs) throws ScribbleException
{
// Follows GlobalMessageTransfer
RoleNode src = subs.substituteRole(this.src.toName());
List<MessageNode> msgs = new LinkedList<>();
for (MessageNode msg : this.msgs)
{
if (msg.isParameterNode())
{
msgs.add((MessageNode) subs.substituteParameter(((ParameterNode) msg).toName()));
}
else
{
msgs.add((MessageNode) subs.visit((AbstractNode) msg));
}
}
List<Role> dests = new LinkedList<>();
for (Role dest : this.dests)
{
dests.add(subs.substituteRole(dest).toName());
}
return new Interrupt(this.ct, src, msgs, dests);
}* /
@Override
public Interrupt visitChildren(NodeVisitor nv) throws ScribbleException
{
RoleNode src = (RoleNode) visitChild(this.src, nv);
List<MessageNode> msgs = new LinkedList<>();
for (MessageNode msg : this.msgs)
{
//msgs.add(MessageTransfer.visitMessageNode(nv, msg));
msgs.add((MessageNode) visitChild(msg, nv));
}
return new Interrupt(this.ct, src, msgs, getContext(), getEnv());//, this.dests);
//return reconstruct(this.ct, src, msgs, getContext(), getEnv());
}
@Override
public GlobalInterruptContext getContext()
{
return (GlobalInterruptContext) super.getContext();
}*/
/*public List<Operator> getOperators(Env env)
{
List<Operator> ops = new LinkedList<>();
for (MessageNode msg : this.msgs)
{
// FIXME: factor out scope prefix manipulation
ops.add(new Operator(env.scopes.getCurrentPrefix() + msg.getOperator().text));
}
return ops;
}*/
}