package org.scribble.codegen.java.endpointapi.ioifaces;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.scribble.codegen.java.endpointapi.HandlerInterfaceGenerator;
import org.scribble.codegen.java.endpointapi.ScribSocketGenerator;
import org.scribble.codegen.java.endpointapi.SessionApiGenerator;
import org.scribble.codegen.java.util.InterfaceBuilder;
import org.scribble.codegen.java.util.JavaBuilder;
import org.scribble.codegen.java.util.MethodBuilder;
import org.scribble.main.ScribbleException;
import org.scribble.model.endpoint.EState;
import org.scribble.model.endpoint.actions.EAction;
import org.scribble.sesstype.name.GProtocolName;
import org.scribble.sesstype.name.Role;
// Cf. HandlerInterfaceGenerator
public class HandleInterfaceGenerator extends IOStateInterfaceGenerator
{
//private final IOInterfacesGenerator iogen;
private final Map<EAction, InterfaceBuilder> caseActions;
public HandleInterfaceGenerator(IOInterfacesGenerator iogen, Map<EAction, InterfaceBuilder> actions, EState curr, Map<EAction, InterfaceBuilder> caseActions)
{
super(iogen.apigen, actions, curr);
//this.iogen = iogen;
this.caseActions = caseActions;
}
@Override
protected void constructInterface() throws ScribbleException
{
super.constructInterface();
addHandleMethods();
}
@Override
protected void addHeader()
{
GProtocolName gpn = this.apigen.getGProtocolName();
Role self = this.apigen.getSelf();
String packname = IOInterfacesGenerator.getIOInterfacePackageName(gpn, self);
String ifname = getHandleInterfaceName(self, this.curr);
this.ib.setName(ifname);
this.ib.setPackage(packname);
this.ib.addModifiers(JavaBuilder.PUBLIC);
}
@Override
protected void addCastField()
{
}
@Override
protected void addSuccessorParamsAndActionInterfaces()
{
//Role self = this.apigen.getSelf();
int i = 1;
//for (IOAction a : getHandleInterfaceIOActionParams(this.curr)) // Branch successor state successors, not the "direct" successors
// Duplicated from BranchInterfaceGenerator
for (EAction a : this.curr.getActions().stream().sorted(IOACTION_COMPARATOR).collect(Collectors.toList()))
{
this.ib.addParameters("__Succ" + i + " extends " + SuccessorInterfaceGenerator.getSuccessorInterfaceName(a));
this.ib.addInterfaces(this.caseActions.get(a).getName() + "<__Succ" + i + ">");
i++;
}
/*for (InterfaceBuilder ib : this.succifs) // Already sorted
{
this.ib.addParameters("__Succ" + i + " extends " + ib.getName());
i++;
}*/
}
/*// Pre: curr is a branch state
private static List<IOAction> getHandleInterfaceIOActionParams(EndpointState curr)
{
List<IOAction> as = new LinkedList<>();
for (IOAction a : curr.getAcceptable().stream().sorted(IOACTION_COMPARATOR).collect(Collectors.toList()))
{
EndpointState succ = curr.accept(a);
/*InterfaceBuilder iostateif = this.iogen.getIOStateInterface(IOStateInterfaceGenerator.getIOStateInterfaceName(self, succ));
for (String param : iostateif.getParameters())
{
this.ib.addParameters("__Succ" + i + " extends " + SuccessorInterfaceGenerator.getSuccessorInterfaceName(this.curr, a));
}* /
for (IOAction b : succ.getAcceptable().stream().sorted(IOACTION_COMPARATOR).collect(Collectors.toList()))
{
//if (!as.contains(b))
{
as.add(b);
}
}
}
return as;
}*/
protected void addHandleMethods() throws ScribbleException
{
GProtocolName gpn = this.apigen.getGProtocolName();
//Role self = this.apigen.getSelf();
//Set<EAction> as = this.curr.getActions();
List<EAction> as = this.curr.getActions();
this.ib.addImports(SessionApiGenerator.getOpsPackageName(gpn) + ".*");
int i = 1;
for (EAction a : as.stream().sorted(IOACTION_COMPARATOR).collect(Collectors.toList()))
{
/*EndpointState succ = this.curr.accept(a);
MethodBuilder mb = this.ib.newAbstractMethod();
HandlerInterfaceGenerator.setHandleMethodHeaderWithoutParamTypes(this.apigen, mb);
i = setHandleMethodSuccessorParam(this.iogen, self, succ, mb, i);
HandlerInterfaceGenerator.addHandleMethodOpAndPayloadParams(this.apigen, a, mb);*/
MethodBuilder mb = this.ib.newAbstractMethod();
HandlerInterfaceGenerator.setHandleMethodHeaderWithoutParamTypes(this.apigen, mb);
//setHandleMethodSuccessorParam(this.iogen, self, succ, mb);
mb.addParameters("__Succ" + i++ + " schan");
HandlerInterfaceGenerator.addHandleMethodOpAndPayloadParams(this.apigen, a, mb);
}
}
//protected static int setHandleMethodSuccessorParam(IOInterfacesGenerator iogen, Role self, EndpointState succ, MethodBuilder mb, int i)
protected static void setHandleMethodSuccessorParam(IOInterfacesGenerator iogen, Role self, EState succ, MethodBuilder mb, List<EAction> as, Map<EAction, Integer> count)
{
if (succ.isTerminal())
{
mb.addParameters(ScribSocketGenerator.ENDSOCKET_CLASS + "<?, ?> end");
}
else
{
InterfaceBuilder next = iogen.getIOStateInterface(IOStateInterfaceGenerator.getIOStateInterfaceName(self, succ)); // Select/Receive/Branch
String ret = next.getName() + "<";
/*//ret += "<" + next.getParameters().stream().map((p) -> "__Succ" + i++).collect(Collectors.joining(", ")) + ">"; // FIXME: fragile?
boolean first = true;
for (String p : next.getParameters())
{
if (first)
{
first = false;
}
else
{
ret += ", ";
}
ret += "__Succ" + i++;
}
ret += ">";
mb.addParameters(ret + " schan");
// duplicates possible? -- can have repeat continuations, but the branch operation ops themselves will be distinct
}
return i;*/
//Map<IOAction, Integer> ount = new HashMap<>();
boolean first = true;
for (EAction a : succ.getActions().stream().sorted(IOStateInterfaceGenerator.IOACTION_COMPARATOR).collect(Collectors.toList()))
{
int offset;
if (!count.containsKey(a))
{
offset = 0;
count.put(a, 0);
}
else
{
offset = count.get(a) + 1;
count.put(a, offset);
}
//if (count.keySet().size() > 1)
if (first)
{
first = false;
}
else
{
ret += ", ";
}
ret += "__Succ" + (as.indexOf(a) + 1 + offset);
}
ret += ">";
mb.addParameters(ret + " schan");
}
}
// Pre: s is a branch state
public static String getHandleInterfaceName(Role self, EState s)
{
// FIXME: factor out (CaseInterfaceGenerator, IOStateInterfaceGenerator.getIOStateInterfaceName)
String name = "Handle_" + self + "_" + s.getActions().stream().sorted(IOACTION_COMPARATOR)
.map((a) -> ActionInterfaceGenerator.getActionString(a)).collect(Collectors.joining("__"));
IOStateInterfaceGenerator.checkIOStateInterfaceNameLength(name);
return name;
}
}