package jetbrains.mps.smodel.search;
/*Generated by MPS */
import jetbrains.mps.cache.AbstractCache;
import jetbrains.mps.cache.DataSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Set;
import java.util.LinkedHashSet;
import jetbrains.mps.smodel.SNodeUtil;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.HashSet;
import jetbrains.mps.smodel.event.SModelChildEvent;
import jetbrains.mps.smodel.event.SModelPropertyEvent;
import java.util.Map;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Arrays;
import jetbrains.mps.util.FlattenIterable;
import jetbrains.mps.kernel.model.SModelUtil;
/*package*/ class Datasets {
/*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> CONCEPTS_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() {
@Override
public DataSet create(ConceptAndSuperConceptsCache ownerCache) {
return new Datasets.ConceptsDataSet(ownerCache);
}
};
/*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> PROPDECL_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() {
@Override
public DataSet create(ConceptAndSuperConceptsCache ownerCache) {
return new Datasets.PropertyDeclarationsDataSet(ownerCache);
}
};
/*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> LINKDECL_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() {
@Override
public DataSet create(ConceptAndSuperConceptsCache ownerCache) {
return new Datasets.LinkDeclarationsDataSet(ownerCache);
}
};
/*package*/ Datasets() {
}
private static void collectImplementedAndExtended(@NotNull SNode top, Set<SNode> result) {
Set<SNode> frontier = new LinkedHashSet<SNode>();
Set<SNode> newFrontier = new LinkedHashSet<SNode>();
frontier.add(top);
result.add(top);
while (!(frontier.isEmpty())) {
// AbstractConceptDeclaration
for (SNode cd : frontier) {
if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(cd)) {
for (SNode interfaceDeclaration : SNodeUtil.getInterfaceConceptDeclaration_Extends(cd)) {
if (interfaceDeclaration != null && !(result.contains(interfaceDeclaration))) {
newFrontier.add(interfaceDeclaration);
result.add(interfaceDeclaration);
}
}
} else
if (SNodeUtil.isInstanceOfConceptDeclaration(cd)) {
SNode anExtends = SNodeUtil.getConceptDeclaration_Extends(cd);
if (anExtends != null && !(result.contains(anExtends))) {
newFrontier.add(anExtends);
result.add(anExtends);
}
for (SNode interfaceDeclaration : SNodeUtil.getConceptDeclaration_Implements(cd)) {
if (interfaceDeclaration != null && !(result.contains(interfaceDeclaration))) {
newFrontier.add(interfaceDeclaration);
result.add(interfaceDeclaration);
}
}
}
}
frontier = newFrontier;
newFrontier = new LinkedHashSet<SNode>();
}
}
/*package*/ static class ConceptsDataSet extends DataSet {
public static final String ID = "CONCEPTS_DATASET";
@NotNull
private final SNode myTopConcept;
private SNode[] myConcepts;
private Set<SNode> myDependsOnNodes;
public ConceptsDataSet(ConceptAndSuperConceptsCache ownerCache) {
super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_OWNER_CACHE);
myTopConcept = ownerCache.getTopConcept();
}
public SNode[] getConcepts() {
return myConcepts;
}
@Override
public Set<SNode> getDependsOnNodes() {
return myDependsOnNodes;
}
@Override
protected void init() {
Set<SNode> result = new LinkedHashSet<SNode>();
Datasets.collectImplementedAndExtended(myTopConcept, result);
result.add(SNodeOperations.getNode("r:00000000-0000-4000-0000-011c89590288(jetbrains.mps.lang.core.structure)", "1133920641626"));
myConcepts = result.toArray(new SNode[result.size()]);
// depends on concepts and implemented interface references
myDependsOnNodes = new HashSet<SNode>(myConcepts.length * 2);
for (SNode concept : myConcepts) {
myDependsOnNodes.add(concept);
if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(concept)) {
for (SNode n : SNodeUtil.getInterfaceConceptDeclaration_ExtendsReferenceNodes(concept)) {
if (n == null) {
continue;
}
myDependsOnNodes.add(n);
}
} else
if (SNodeUtil.isInstanceOfConceptDeclaration(concept)) {
for (SNode n : SNodeUtil.getConceptDeclaration_ImplementsReferenceNodes(concept)) {
if (n == null) {
continue;
}
myDependsOnNodes.add(n);
}
}
}
}
@Override
public void childAdded(SModelChildEvent event) {
// event handling
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process adding of smth. to concept unless it is extended/implemented interface-concept
if (isExtendsImplementsRole(event)) {
super.childAdded(event);
}
}
}
@Override
public void childRemoved(SModelChildEvent event) {
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process removing of smth. from concept unless it is extended/implemented interface-concept
if (isExtendsImplementsRole(event)) {
super.childRemoved(event);
}
}
}
private boolean isExtendsImplementsRole(SModelChildEvent event) {
String role = event.getChildRole();
return SNodeUtil.link_ConceptDeclaration_implements.getRoleName().equals(role) || SNodeUtil.link_ConceptDeclaration_extends.getRoleName().equals(role);
}
@Override
public void propertyChanged(SModelPropertyEvent event) {
}
}
/*package*/ static class PropertyDeclarationsDataSet extends DataSet {
public static final String ID = "PROPERTY_DECLARATIONS_DATASET";
private Map<String, SNode> myPropertyByName = null;
private List<SNode> myProperties = null;
private Set<SNode> myDependsOnNodes;
public PropertyDeclarationsDataSet(AbstractCache ownerCache) {
super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_DATA_SET);
}
@Override
public Set<SNode> getDependsOnNodes() {
return myDependsOnNodes;
}
public SNode getPropertyDeclarationByName(String name) {
return (myPropertyByName == null ? null : myPropertyByName.get(name));
}
public List<SNode> getPropertyDeclarations() {
return (myProperties == null ? Collections.<SNode>emptyList() : new ArrayList<SNode>(myProperties));
}
@Override
protected void init() {
List<SNode> allProperties = new ArrayList<SNode>();
myPropertyByName = null;
myProperties = null;
SNode[] concepts = ((ConceptAndSuperConceptsCache) getOwnerCache()).getConcepts();
// iterate bottom-up
for (int i = concepts.length - 1; i >= 0; i--) {
Iterable<SNode> props = SNodeUtil.getConcept_PropertyDeclarations(concepts[i]);
for (SNode prop : props) {
allProperties.add(prop);
String name = prop.getName();
if (name == null) {
continue;
}
if (myPropertyByName != null && myPropertyByName.containsKey(name)) {
// properties can not be "overridden"
continue;
}
if (myProperties == null) {
myProperties = new ArrayList<SNode>(1);
}
myProperties.add(prop);
if (myPropertyByName == null) {
myPropertyByName = new HashMap<String, SNode>();
}
myPropertyByName.put(name, prop);
}
}
// depends on concepts and link declarations
myDependsOnNodes = new HashSet<SNode>();
myDependsOnNodes.addAll(Arrays.asList(concepts));
for (SNode prop : allProperties) {
myDependsOnNodes.add(prop);
}
}
@Override
public void childAdded(SModelChildEvent event) {
// ------event handling
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process adding of smth. to concept unless it is property-declaration
if (isPropertyDeclarationRole(event)) {
super.childAdded(event);
}
}
}
@Override
public void childRemoved(SModelChildEvent event) {
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process removing of smth. from concept unless it is property-declaration
if (isPropertyDeclarationRole(event)) {
super.childRemoved(event);
}
}
}
private boolean isPropertyDeclarationRole(SModelChildEvent event) {
String role = event.getChildRole();
return SNodeUtil.link_AbstractConceptDeclaration_propertyDeclaration.getRoleName().equals(role);
}
@Override
public void propertyChanged(SModelPropertyEvent event) {
// don't process unless it is property name
if (SNodeUtil.isInstanceOfPropertyDeclaration(event.getNode())) {
super.propertyChanged(event);
}
}
}
/*package*/ static class LinkDeclarationsDataSet extends DataSet {
public static final String ID = "LINK_DECLARATIONS_DATASET";
private Map<String, SNode> myLinkByRole = null;
private Map<SNode, SNode> myMostSpecificLinkBySpecializedLink = null;
private List<SNode> myMostSpecificLinks = null;
private Set<SNode> myDependsOnNodes;
public LinkDeclarationsDataSet(AbstractCache ownerCache) {
super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_DATA_SET);
}
@Override
public Set<SNode> getDependsOnNodes() {
return myDependsOnNodes;
}
public SNode getLinkDeclarationByRole(String role) {
return (myLinkByRole == null ? null : myLinkByRole.get(role));
}
public SNode getMostSpecificLinkDeclarationByRole(String role) {
SNode linkDeclaration = getLinkDeclarationByRole(role);
if (linkDeclaration == null) {
return null;
}
if (myMostSpecificLinkBySpecializedLink == null) {
return linkDeclaration;
}
SNode mostSpecificLinkDeclaration = myMostSpecificLinkBySpecializedLink.get(linkDeclaration);
if (mostSpecificLinkDeclaration == null) {
return linkDeclaration;
}
return mostSpecificLinkDeclaration;
}
public List<SNode> getLinkDeclarationsExcludingOverridden() {
return (myMostSpecificLinks == null ? Collections.<SNode>emptyList() : new ArrayList<SNode>(myMostSpecificLinks));
}
@Override
protected void init() {
myLinkByRole = null;
SNode[] concepts = ((ConceptAndSuperConceptsCache) getOwnerCache()).getConcepts();
FlattenIterable<SNode> allLinks = new FlattenIterable<SNode>(new ArrayList<Iterable<SNode>>(concepts.length));
for (SNode concept : concepts) {
Iterable<SNode> list = SNodeUtil.getConcept_LinkDeclarations((SNode) concept);
allLinks.add(list);
for (SNode link : list) {
String role1 = SModelUtil.getLinkDeclarationRole(link);
if (role1 == null) {
continue;
}
if (myLinkByRole != null && myLinkByRole.containsKey(role1)) {
continue;
}
if (myLinkByRole == null) {
myLinkByRole = new HashMap<String, SNode>();
}
myLinkByRole.put(role1, link);
}
}
Map<SNode, SNode> specializedLinks = new HashMap<SNode, SNode>();
for (SNode link : allLinks) {
SNode specializedLink = SModelUtil.getLinkDeclarationSpecializedLink(link);
if (specializedLink != null) {
specializedLinks.put(specializedLink, link);
}
}
myMostSpecificLinkBySpecializedLink = null;
myMostSpecificLinks = null;
for (SNode link : allLinks) {
SNode moreSpecificLink = specializedLinks.get(link);
if (moreSpecificLink == null) {
if (myMostSpecificLinks == null) {
myMostSpecificLinks = new ArrayList<SNode>(5);
}
myMostSpecificLinks.add(link);
} else {
while (moreSpecificLink != null) {
if (myMostSpecificLinkBySpecializedLink == null) {
myMostSpecificLinkBySpecializedLink = new HashMap<SNode, SNode>();
}
myMostSpecificLinkBySpecializedLink.put(link, moreSpecificLink);
moreSpecificLink = specializedLinks.get(moreSpecificLink);
}
}
}
// depends on concepts and link declarations
myDependsOnNodes = new HashSet<SNode>();
myDependsOnNodes.addAll(Arrays.asList(concepts));
for (SNode link : allLinks) {
myDependsOnNodes.add(link);
}
}
@Override
public void childAdded(SModelChildEvent event) {
// event handling
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process adding of smth. to concept unless it is link-declaration
if (isLinkDeclarationRole(event)) {
super.childAdded(event);
}
}
}
@Override
public void childRemoved(SModelChildEvent event) {
if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) {
// don't process removing of smth. from concept unless it is link-declaration
if (isLinkDeclarationRole(event)) {
super.childRemoved(event);
}
}
}
private boolean isLinkDeclarationRole(SModelChildEvent event) {
String role = event.getChildRole();
return SNodeUtil.link_AbstractConceptDeclaration_linkDeclaration.getRoleName().equals(role);
}
@Override
public void propertyChanged(SModelPropertyEvent event) {
// don't process unless it is link's role
if (!(SNodeUtil.property_LinkDeclaration_role.getName().equals(event.getPropertyName())) || !(SNodeUtil.isInstanceOfLinkDeclaration(event.getNode()))) {
return;
}
String oldRole = event.getOldPropertyValue();
if (oldRole != null) {
if (myLinkByRole != null) {
myLinkByRole.remove(oldRole);
}
}
String newRole = event.getNewPropertyValue();
if (newRole == null) {
return;
}
if (myLinkByRole == null) {
myLinkByRole = new HashMap<String, SNode>();
myLinkByRole.put(newRole, event.getNode());
} else
if (!(myLinkByRole.containsKey(newRole))) {
myLinkByRole.put(newRole, event.getNode());
}
}
}
}