package org.scribble.del.global; import java.util.List; import java.util.Map; import java.util.Set; import org.scribble.ast.Module; import org.scribble.ast.ScribNode; import org.scribble.ast.context.DependencyMap; import org.scribble.ast.context.global.GProtocolDeclContext; import org.scribble.ast.global.GProtocolDecl; import org.scribble.ast.local.LProtocolDecl; import org.scribble.ast.local.LProtocolDef; import org.scribble.del.ModuleDel; import org.scribble.del.ProtocolDeclDel; import org.scribble.main.Job; import org.scribble.main.JobContext; import org.scribble.main.ScribbleException; import org.scribble.model.global.SGraph; import org.scribble.sesstype.kind.Global; import org.scribble.sesstype.name.GProtocolName; import org.scribble.sesstype.name.ProtocolName; import org.scribble.sesstype.name.Role; import org.scribble.visit.context.Projector; import org.scribble.visit.context.ProtocolDeclContextBuilder; import org.scribble.visit.context.env.ProjectionEnv; import org.scribble.visit.util.RoleCollector; import org.scribble.visit.validation.GProtocolValidator; public class GProtocolDeclDel extends ProtocolDeclDel<Global> { public GProtocolDeclDel() { } @Override public GProtocolDeclContext getProtocolDeclContext() { return (GProtocolDeclContext) super.getProtocolDeclContext(); } @Override protected GProtocolDeclDel copy() { return new GProtocolDeclDel(); } @Override protected void addSelfDependency(ProtocolDeclContextBuilder builder, ProtocolName<?> proto, Role role) { builder.addGlobalProtocolDependency(role, (GProtocolName) proto, role); } @Override public GProtocolDecl leaveProtocolDeclContextBuilding(ScribNode parent, ScribNode child, ProtocolDeclContextBuilder builder, ScribNode visited) throws ScribbleException { GProtocolDecl gpd = (GProtocolDecl) visited; GProtocolDeclContext gcontext = new GProtocolDeclContext(builder.getGlobalProtocolDependencyMap()); GProtocolDeclDel del = (GProtocolDeclDel) setProtocolDeclContext(gcontext); return (GProtocolDecl) gpd.del(del); } @Override public ScribNode leaveRoleCollection(ScribNode parent, ScribNode child, RoleCollector coll, ScribNode visited) throws ScribbleException { GProtocolDecl gpd = (GProtocolDecl) visited; // Need to do here (e.g. RoleDeclList too early, def not visited yet) // Currently only done for global, local does roledecl fixing after role collection -- should separate this check to a later pass after context building // Maybe relax to check only occs.size() > 1 List<Role> decls = gpd.header.roledecls.getRoles(); Set<Role> occs = coll.getNames(); if (occs.size() != decls.size()) { decls.removeAll(occs); throw new ScribbleException(gpd.header.roledecls.getSource(), "Unused role decl(s) in " + gpd.header.name + ": " + decls); } return super.leaveRoleCollection(parent, child, coll, gpd); } @Override public GProtocolDecl leaveProjection(ScribNode parent, ScribNode child, Projector proj, ScribNode visited) throws ScribbleException { Module root = proj.job.getContext().getModule(proj.getModuleContext().root); GProtocolDecl gpd = (GProtocolDecl) visited; Role self = proj.peekSelf(); LProtocolDef def = (LProtocolDef) ((ProjectionEnv) gpd.def.del().env()).getProjection(); LProtocolDecl lpd = gpd.project(root, self, def); // FIXME: is root (always) the correct module? (wrt. LProjectionDeclDel?) Map<GProtocolName, Set<Role>> deps = ((GProtocolDeclDel) gpd.del()).getGlobalProtocolDependencies(self); Module projected = ((ModuleDel) root.del()).createModuleForProjection(proj, root, gpd, lpd, deps); proj.addProjection(gpd.getFullMemberName(root), self, projected); return gpd; } private Map<GProtocolName, Set<Role>> getGlobalProtocolDependencies(Role self) { DependencyMap<GProtocolName> deps = getProtocolDeclContext().getDependencyMap(); return deps.getDependencies().get(self); } @Override public void enterValidation(ScribNode parent, ScribNode child, GProtocolValidator checker) throws ScribbleException { GProtocolDecl gpd = (GProtocolDecl) child; if (gpd.isAuxModifier()) { return; } GProtocolName fullname = gpd.getFullMemberName((Module) parent); validate(checker.job, fullname, true); if (!checker.job.fair) { checker.job.debugPrintln("(" + fullname + ") Validating with \"unfair\" output choices.. "); validate(checker.job, fullname, false); // FIXME: only need to check progress, not full validation } } private static void validate(Job job, GProtocolName fullname, boolean fair) throws ScribbleException { JobContext jc = job.getContext(); SGraph graph = (fair) ? jc.getSGraph(fullname) : jc.getUnfairSGraph(fullname); graph.toModel().validate(job); } }