package org.scribble.ast.context; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.scribble.sesstype.name.ProtocolName; import org.scribble.sesstype.name.Role; // Mutable // Used for two purposes: one to encapsulate Map structure and add method for ContextBuilder; second to allow overriding the generic types in ProtocolDeclContext (cf. nested Map generics) public abstract class DependencyMap<N extends ProtocolName<?>> // Maybe better to parameterise on Kind only? { // self -> (proto -> target) -- the self role in this proto, depends on the proto, for the role param target private final Map<Role, Map<N, Set<Role>>> deps = new HashMap<>(); // All the potential dependencies from this protocol decl as the root public DependencyMap() { } protected DependencyMap(DependencyMap<N> deps) { for (Role r : deps.deps.keySet()) // FIXME: optimise { Map<N, Set<Role>> tmp = deps.deps.get(r); for (Entry<N, Set<Role>> e : tmp.entrySet()) { for (Role rr : e.getValue()) { addProtocolDependency(r, e.getKey(), rr); } } } } public abstract DependencyMap<N> clone(); public void addProtocolDependency(Role self, N pn, Role target) { Map<N, Set<Role>> tmp1 = this.deps.get(self); if (tmp1 == null) { tmp1 = new HashMap<>(); this.deps.put(self, tmp1); } Set<Role> tmp2 = tmp1.get(pn); if (tmp2 == null) { tmp2 = new HashSet<>(); tmp1.put(pn, tmp2); } tmp2.add(target); } public Map<Role, Map<N, Set<Role>>> getDependencies() { return this.deps; } }