package org.scribble.ast.global;
import java.util.List;
import java.util.stream.Collectors;
import org.antlr.runtime.tree.CommonTree;
import org.scribble.ast.Constants;
import org.scribble.ast.Interrupt;
import org.scribble.ast.MessageNode;
import org.scribble.ast.name.simple.RoleNode;
import org.scribble.sesstype.kind.Global;
public class GInterrupt extends Interrupt implements GSimpleInteractionNode
{
/*public static final Function<Interrupt, GlobalInterrupt> toGlobalInterrupt =
(Interrupt interr) -> (GlobalInterrupt) interr;*/
public GInterrupt(CommonTree source, RoleNode src, List<MessageNode> msgs)
{
//this(ct, src, msgs, null, null);
//this(t, src, msgs, null, null);
super(source, src, msgs);
}
/*// Destination Roles is "type info", not a syntax element -- could wrap in a generic "type info" object
//public GlobalInterrupt(CommonTree ct, RoleNode src, List<MessageNode> msgs)//, List<Role> dests)
public GlobalInterrupt(CommonTree ct, RoleNode src, List<MessageNode> msgs, GlobalInterruptContext icontext)
{
//super(ct, src, msgs);//, dests);
super(ct, src, msgs, icontext);
}*/
/*protected GlobalInterrupt(CommonTree ct, RoleNode src, List<MessageNode> msgs, GlobalInterruptContext icontext, Env env)
{
//super(ct, src, msgs);//, dests);
super(ct, src, msgs, icontext, env);
}
//@Override // LocalInterrupt has a different signature
protected GlobalInterrupt reconstruct(CommonTree ct, RoleNode src, List<MessageNode> msgs, GlobalInterruptContext icontext, Env env)
{
return new GlobalInterrupt(ct, src, msgs, icontext, env);
}
@Override
public GlobalInterrupt leaveWFChoiceCheck(WellFormedChoiceChecker checker) throws ScribbleException
{
Role src = this.src.toName();
if (!checker.getEnv().isEnabled(src))
{
throw new ScribbleException("Role not enabled: " + src);
}
return (GlobalInterrupt) super.leaveWFChoiceCheck(checker);
/*Interrupt interr = super.leaveWFChoiceCheck(checker);
return new GlobalInterrupt(interr.ct, interr.src, interr.msgs, interr.getContext(), interr.getEnv());* /
}
@Override
public GlobalInterrupt leaveProjection(Projector proj) //throws ScribbleException
{
Role self = proj.peekSelf();
Role srcrole = this.src.toName();
List<Role> destroles = ((GlobalInterruptContext) getContext()).getDestinations();
LocalInterrupt projection = null;
if (srcrole.equals(self) || destroles.contains(self))
{
RoleNode src = new RoleNode(null, this.src.toName().toString()); // FIXME: project by visiting
List<MessageNode> msgs =
this.msgs.stream().map((m) -> (MessageNode) ((ProjectionEnv) m.getEnv()).getProjection()).collect(Collectors.toList());
List<RoleNode> dests =
destroles.stream().map((d) -> new RoleNode(null, d.toString())).collect(Collectors.toList());
if (srcrole.equals(self))
{
projection = new LocalThrows(null, src, msgs, dests);
}
else if (destroles.contains(self))
{
projection = new LocalCatches(null, src, msgs, dests);
}
}
this.setEnv(new ProjectionEnv(proj.getJobContext(), proj.getModuleContext(), projection));
return this;
}
/*@Override
public GlobalInterrupt leaveContextBuilding(Node parent, NodeContextBuilder builder) throws ScribbleException
{
GlobalInterrupt interr = (GlobalInterrupt) super.leaveContextBuilding(parent, builder);
ProtocolBlockContext bcontext = (ProtocolBlockContext) ((GlobalInterruptible) parent).block.getContext();
System.out.println("3: " + bcontext);
List<Role> dests = new LinkedList<>(bcontext.getRoles());
// FIXME: also include other interrupt sources? (would be better to do in GlobalInterruptible)
dests.remove(this.src.toName());
return new GlobalInterrupt(interr.ct, interr.src, interr.msgs, dests);
}*/
/*@Override
public GlobalInterrupt substitute(Substitutor subs) throws ScribbleException
{
Interrupt interr = super.substitute(subs);
return new GlobalInterrupt(interr.ct, interr.src, interr.msgs, interr.dests);
}
@Override
public GlobalInterrupt checkWellFormedness(WellFormednessChecker wfc) throws ScribbleException
{
GlobalInterrupt gi = (GlobalInterrupt) super.checkWellFormedness(wfc);
Env env = wfc.getEnv();
Role src = this.src.toName();
if (!env.roles.isRoleEnabled(src))
{
throw new ScribbleException("Interrupt role not enabled: " + src);
}
for (MessageNode msg : this.msgs)
{
// Duplicated from GlobalMesssageTransfer
if (msg.isParameterNode())
{
//MessageSignatureParameter param = ((ParameterNode) msg).toMessageSignatureParameter();
Parameter param = ((ParameterNode) msg).toName();
if (!env.params.isParameterDeclared(param))
{
throw new ScribbleException("Bad parameter: " + param);
}
ParameterDecl.Kind pdkind = env.params.getParameterKind(((ParameterNode) msg).toName());
if (!pdkind.equals(ParameterDecl.Kind.SIG))
{
throw new ScribbleException("GlobalMessageTransfer type parameter should be of SIG kind, not: " + pdkind);
}
}
}
Set<Role> dests = new HashSet<>();
dests.addAll(env.ops.getSources());
dests.addAll(env.ops.getAllDestinations());
dests.remove(this.src.toName());
return new GlobalInterrupt(gi.ct, gi.src, gi.msgs, new LinkedList<>(dests));
}
@Override
public LocalNode project(Projector proj)
{
Role role = proj.getRole();
if (this.src.toName().equals(role))
{
return new LocalThrows(null, this.src, this.msgs, this.dests);
}
else if (this.dests.contains(role))
{
return new LocalCatches(null, this.src, this.msgs, this.dests);
}
return null;
}
@Override
public GlobalInterrupt collectRoles(RoleCollector rc) throws ScribbleException
{
rc.addRole(this.src.toName());
for (Role dest : this.dests)
{
rc.addRole(dest);
}
return (GlobalInterrupt) super.collectRoles(rc);
}* /
@Override
public GlobalInterrupt visitChildren(NodeVisitor nv) throws ScribbleException
{
Interrupt interr = super.visitChildren(nv);
//return new GlobalInterrupt(interr.ct, interr.src, interr.msgs); //, interr.dests);
//return new GlobalInterrupt(interr.ct, interr.src, interr.msgs, interr.getContext(), interr.getEnv());
return reconstruct(interr.ct, interr.src, interr.msgs, interr.getContext(), interr.getEnv());
}*/
// FIXME: shouldn't be needed, but here due to Eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=436350
@Override
public Global getKind()
{
return GSimpleInteractionNode.super.getKind();
}
@Override
public String toString()
{
return this.getMessages().stream().map((msg) -> msg.toString()).collect(Collectors.joining(", "))
+ " " + Constants.BY_KW + " " + this.src + ";";
}
}