/* ModuleScope - Decompiled by JODE
 * Visit http://jode.sourceforge.net/
 */
package alloy.semantic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import alloy.ast.Decl;
import alloy.ast.Paragraph;
import alloy.ast.QualifiedName;
import alloy.ast.Signature;
import alloy.ast.Variable;
import alloy.util.Dbg;

public class ModuleScope
{
    private Map _nameToPara = new HashMap();
    private Map _qualNameToPara = new HashMap();
    private Map _fieldsToSigs = new HashMap();
    
    public class NoSigsException extends Exception
    {
    }
    
    public class NoParagraphException extends Exception
    {
    }
    
    public static class MultipleMappingsException extends Exception
    {
	public ArrayList mappedTo;
	
	public MultipleMappingsException() {
	    /* empty */
	}
	
	public MultipleMappingsException(ArrayList arraylist) {
	    mappedTo = arraylist;
	}
	
	public String mappingsString() {
	    StringBuffer stringbuffer
		= (new StringBuffer
		   ("reference to ambiguous unqualified name, could be "));
	    Iterator iterator = mappedTo.iterator();
	    while (iterator.hasNext()) {
		stringbuffer.append(((Paragraph) iterator.next()).getName());
		if (iterator.hasNext())
		    stringbuffer.append(" or ");
	    }
	    return stringbuffer.toString();
	}
    }
    
    public void addUsedParagraph
	(QualifiedName qualifiedname, Paragraph paragraph)
	throws AlreadyMappedException {
	Dbg.chk(qualifiedname != null, "attempt to add null name");
	Dbg.chk(paragraph != null, "attempt to add null paragraph");
	String string = qualifiedname.nodeString();
	if (_qualNameToPara.containsKey(string))
	    throw new AlreadyMappedException();
	_qualNameToPara.put(string, paragraph);
	if (paragraph instanceof Signature)
	    addFieldSigMappings((Signature) paragraph);
    }
    
    public void addOpenedParagraph
	(QualifiedName qualifiedname, Paragraph paragraph)
	throws AlreadyMappedException {
	addUsedParagraph(qualifiedname, paragraph);
	String string = qualifiedname.getId().nodeString();
	if (_nameToPara.containsKey(string)) {
	    Object object = _nameToPara.get(string);
	    if (object instanceof ArrayList)
		((ArrayList) object).add(paragraph);
	    else {
		ArrayList arraylist = new ArrayList();
		arraylist.add(object);
		arraylist.add(paragraph);
		_nameToPara.put(string, arraylist);
	    }
	} else
	    _nameToPara.put(string, paragraph);
    }
    
    public void addFieldSigMappings(Signature signature) {
	Iterator iterator = signature.getDecls().getDeclIter();
	while (iterator.hasNext()) {
	    Decl decl = (Decl) iterator.next();
	    if (!decl.isEmpty()) {
		Iterator iterator_0_ = decl.getVariables().getVariableIter();
		while (iterator_0_.hasNext()) {
		    Variable variable = (Variable) iterator_0_.next();
		    String string = variable.getId().nodeString();
		    addFieldSigMapping(string, signature);
		}
	    }
	}
    }
    
    private void addFieldSigMapping(String string, Signature signature) {
	Dbg.chk(string != null, "attempt to add null field");
	Dbg.chk(signature != null, "attempt to add null signature");
	if (_fieldsToSigs.containsKey(string)) {
	    ArrayList arraylist = (ArrayList) _fieldsToSigs.get(string);
	    arraylist.add(signature);
	} else {
	    ArrayList arraylist = new ArrayList();
	    arraylist.add(signature);
	    _fieldsToSigs.put(string, arraylist);
	}
    }
    
    public List getSigsForField(String string) throws NoSigsException {
	ArrayList arraylist = (ArrayList) _fieldsToSigs.get(string);
	if (arraylist == null)
	    throw new NoSigsException();
	return (ArrayList) arraylist.clone();
    }
    
    public Paragraph getParagraphUnqual(QualifiedName qualifiedname)
	throws MultipleMappingsException, NoParagraphException {
	Dbg.chk(qualifiedname.hasEmptyPath(),
		"attempt to use qualified name un unqualified lookup");
	Object object = _nameToPara.get(qualifiedname.nodeString());
	if (object instanceof ArrayList)
	    throw new MultipleMappingsException((ArrayList) object);
	if (object == null)
	    throw new NoParagraphException();
	return (Paragraph) object;
    }
    
    public Paragraph getParagraph(QualifiedName qualifiedname)
	throws NoParagraphException {
	Object object = _qualNameToPara.get(qualifiedname.nodeString());
	if (object == null)
	    throw new NoParagraphException();
	return (Paragraph) object;
    }
    
    public Paragraph getParagraph(String string)
	throws MultipleMappingsException, NoParagraphException {
	Object object = _nameToPara.get(string);
	if (object instanceof ArrayList)
	    throw new MultipleMappingsException((ArrayList) object);
	if (object == null)
	    throw new NoParagraphException();
	return (Paragraph) object;
    }
}
