/*
* Copyright 2003-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.generator.impl.template;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import org.jetbrains.mps.openapi.language.SProperty;
import org.jetbrains.mps.openapi.language.SReferenceLink;
import java.util.ArrayList;
import java.util.List;
/**
* Facility to use in templates that records used meta-objects, assigns them integer value,
* and facilitates generation of array of meta-object proxies to be accessed by integer index.
*
* Deemed to be used from single thread or synchronized externally, no synchronization/access control here.
* @author Artem Tikhomirov
*/
public class MetaObjectGenerationHelper {
private final ArrayList<SConcept> myConcepts = new ArrayList<>();
private final TObjectIntHashMap<SConcept> myConceptKeys = new TObjectIntHashMap<>();
private final ArrayList<SProperty> myProperties = new ArrayList<>();
private final TObjectIntHashMap<SProperty> myPropertyKeys = new TObjectIntHashMap<>();
private final ArrayList<SReferenceLink> myAssociations = new ArrayList<>();
private final TObjectIntHashMap<SReferenceLink> myAssociationKeys = new TObjectIntHashMap<>();
private final ArrayList<SContainmentLink> myAggregations = new ArrayList<>();
private final TObjectIntHashMap<SContainmentLink> myAggregationKeys = new TObjectIntHashMap<>();
public int record(SConcept concept) {
return doRecord(concept, myConcepts, myConceptKeys);
}
public int record(SProperty property) {
return doRecord(property, myProperties, myPropertyKeys);
}
public int record(SReferenceLink link) {
return doRecord(link, myAssociations, myAssociationKeys);
}
public int record(SContainmentLink link) {
return doRecord(link, myAggregations, myAggregationKeys);
}
private static <T> int doRecord(T element, List<T> ordered, TObjectIntHashMap<T> map) {
if (map.contains(element)) {
return map.get(element);
}
int rv = ordered.size();
map.put(element, rv);
ordered.add(element);
return rv;
}
public SConcept[] getConcepts() {
return myConcepts.toArray(new SConcept[myConcepts.size()]);
}
public SProperty[] getProperties() {
return myProperties.toArray(new SProperty[myProperties.size()]);
}
public SReferenceLink[] getAssociationLinks() {
return myAssociations.toArray(new SReferenceLink[myAssociations.size()]);
}
public SContainmentLink[] getAggregationLinks() {
return myAggregations.toArray(new SContainmentLink[myAggregations.size()]);
}
}