package jetbrains.mps.project.persistence;
/*Generated by MPS */
import jetbrains.mps.util.MacroHelper;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.project.structure.modules.GeneratorDescriptor;
import org.jdom.Element;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.util.xml.XmlUtil;
import jetbrains.mps.project.ModuleId;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingPriorityRule;
import jetbrains.mps.project.structure.modules.mappingpriorities.RuleType;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_AbstractRef;
import jetbrains.mps.util.annotation.ToRemove;
import jetbrains.mps.vfs.IFile;
import org.jetbrains.mps.openapi.module.SModuleReference;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_RefAllLocal;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_RefAllGlobal;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_SimpleRef;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_ExternalRef;
import jetbrains.mps.project.structure.modules.mappingpriorities.MappingConfig_RefSet;
/**
* XML/DOM persistence for a descriptor of Generator module
*/
public class GeneratorDescriptorPersistence {
private final String SOURCE_GEN_DEFAULT = "${module}/generator/source_gen";
private final MacroHelper myMacroHelper;
public GeneratorDescriptorPersistence(@NotNull MacroHelper macroHelper) {
myMacroHelper = macroHelper;
}
@NotNull
public GeneratorDescriptor load(@NotNull final Element generatorElement) throws ModuleReadException {
try {
GeneratorDescriptor descriptor = new _FunctionTypes._return_P0_E0<GeneratorDescriptor>() {
public GeneratorDescriptor invoke() {
final GeneratorDescriptor result_wk2vdq_a0a0a0a0g = new GeneratorDescriptor();
// FIXME generatorUID is legacy key, remove in 2017.2 or 2017.3 (depending on moment we save new attributes)
String genUID = generatorElement.getAttributeValue("namespace", generatorElement.getAttributeValue("generatorUID"));
final String result_wk2vdq_a2a0a0a0a0g = genUID;
result_wk2vdq_a0a0a0a0g.setNamespace(result_wk2vdq_a2a0a0a0a0g);
boolean genTemplatesSetting = XmlUtil.booleanWithDefault(generatorElement, "generate-templates", false);
final boolean result_wk2vdq_a4a0a0a0a0g = genTemplatesSetting;
result_wk2vdq_a0a0a0a0g.setGenerateTemplates(result_wk2vdq_a4a0a0a0a0g);
// reflective queries are deprecated and are off by default now. For generated templates, however, I don't want to have
// regular QG API (there's no need, generated templates still invoke static methods directly) just not get confused now.
// Perhaps, later will generate non-reflective access for generated templates as well, and even may utilize query objects in there.
final boolean result_wk2vdq_a8a0a0a0a0g = XmlUtil.booleanWithDefault(generatorElement, "reflective-queries", genTemplatesSetting);
result_wk2vdq_a0a0a0a0g.setReflectiveQueries(result_wk2vdq_a8a0a0a0a0g);
final String result_wk2vdq_a9a0a0a0a0g = myMacroHelper.expandPath(XmlUtil.stringWithDefault(generatorElement, "generatorOutputPath", SOURCE_GEN_DEFAULT));
result_wk2vdq_a0a0a0a0g.setOutputPath(result_wk2vdq_a9a0a0a0a0g);
String uuid = generatorElement.getAttributeValue("uuid");
if (uuid != null) {
final ModuleId result_wk2vdq_a0a21a0a0a0a0g = ModuleId.fromString(uuid);
result_wk2vdq_a0a0a0a0g.setId(result_wk2vdq_a0a21a0a0a0a0g);
}
// FIXME use of 'name' is legacy, see comment above
String generatorName = generatorElement.getAttributeValue("alias", generatorElement.getAttributeValue("name"));
if (generatorName != null) {
final String result_wk2vdq_a0a61a0a0a0a0g = generatorName;
result_wk2vdq_a0a0a0a0g.setAlias(result_wk2vdq_a0a61a0a0a0a0g);
}
Element models = XmlUtil.first(generatorElement, "models");
if (models != null) {
result_wk2vdq_a0a0a0a0g.getModelRootDescriptors().addAll(ModuleDescriptorPersistence.loadModelRoots(XmlUtil.children(models, "modelRoot"), myMacroHelper));
}
Element facets = XmlUtil.first(generatorElement, "facets");
if (facets != null) {
result_wk2vdq_a0a0a0a0g.getModuleFacetDescriptors().addAll(ModuleDescriptorPersistence.loadFacets(XmlUtil.children(facets, "facet"), myMacroHelper));
}
ModuleDescriptorPersistence.loadDependencies(result_wk2vdq_a0a0a0a0g, generatorElement);
// "depends on" generators
for (Element refGenerator : Sequence.fromIterable(XmlUtil.children(XmlUtil.first(generatorElement, "external-templates"), "generator"))) {
result_wk2vdq_a0a0a0a0g.getDepGenerators().add(PersistenceFacade.getInstance().createModuleReference(refGenerator.getAttributeValue("generatorUID")));
}
for (Element ruleElement : Sequence.fromIterable(XmlUtil.children(XmlUtil.first(generatorElement, "mapping-priorities"), "mapping-priority-rule"))) {
final MappingPriorityRule result_wk2vdq_a0a92a0a0a0a0g = new MappingPriorityRule();
final RuleType result_wk2vdq_a0a0a92a0a0a0a0g = RuleType.parse(ruleElement.getAttributeValue("kind"));
result_wk2vdq_a0a92a0a0a0a0g.setType(result_wk2vdq_a0a0a92a0a0a0a0g);
Element greaterPM = XmlUtil.first(ruleElement, "greater-priority-mapping");
if (greaterPM != null) {
final MappingConfig_AbstractRef result_wk2vdq_a0a2a0a92a0a0a0a0g = loadGeneratorMappingConfigRef(greaterPM, genUID, false);
result_wk2vdq_a0a92a0a0a0a0g.setLeft(result_wk2vdq_a0a2a0a92a0a0a0a0g);
}
Element lesserPM = XmlUtil.first(ruleElement, "lesser-priority-mapping");
if (lesserPM != null) {
final MappingConfig_AbstractRef result_wk2vdq_a0a4a0a92a0a0a0a0g = loadGeneratorMappingConfigRef(lesserPM, genUID, false);
result_wk2vdq_a0a92a0a0a0a0g.setRight(result_wk2vdq_a0a4a0a92a0a0a0a0g);
}
result_wk2vdq_a0a0a0a0g.getPriorityRules().add(result_wk2vdq_a0a92a0a0a0a0g);
}
return result_wk2vdq_a0a0a0a0g;
}
}.invoke();
return descriptor;
} catch (Exception ex) {
throw new ModuleReadException(ex);
}
}
/**
*
* @deprecated use {@link jetbrains.mps.project.persistence.GeneratorDescriptorPersistence#load(Element) instance method} instead
*/
@Deprecated
@ToRemove(version = 3.5)
public static GeneratorDescriptor loadGeneratorDescriptor(Element generatorElement, IFile file, MacroHelper macroHelper) {
GeneratorDescriptor descriptor = new GeneratorDescriptorPersistence(macroHelper).load(generatorElement);
ModuleDescriptorPersistence.setTimestamp(descriptor, file);
return descriptor;
}
@NotNull
public Element save(@NotNull GeneratorDescriptor descriptor) {
Element generator = new Element("generator");
if (descriptor.getAlias() != null) {
generator.setAttribute("alias", descriptor.getAlias());
}
if (descriptor.getNamespace() != null) {
generator.setAttribute("namespace", descriptor.getNamespace());
}
if (descriptor.getId() != null) {
generator.setAttribute("uuid", descriptor.getId().toString());
}
if (descriptor.isGenerateTemplates()) {
generator.setAttribute("generate-templates", Boolean.toString(descriptor.isGenerateTemplates()));
}
if (descriptor.isReflectiveQueries() && !(descriptor.isGenerateTemplates())) {
// XXX transition. I've changed default to be off, and only explicitly set options ought to be persisted.
// Since generated templated do not use non-reflective (aka API) queries, we ignore this option for generated templates,
// assuming it to be true.
generator.setAttribute("reflective-queries", Boolean.toString(true));
}
if (descriptor.getOutputPath() != null) {
String p = myMacroHelper.shrinkPath(descriptor.getOutputPath());
if (!(SOURCE_GEN_DEFAULT.equals(p))) {
// meanwhile, don't want to persist default value as it requires re-generation of all modules. Can do it any time later
generator.setAttribute("generatorOutputPath", p);
}
}
Element models = new Element("models");
ModuleDescriptorPersistence.saveModelRoots(models, descriptor.getModelRootDescriptors(), myMacroHelper);
generator.addContent(models);
if (!(descriptor.getModuleFacetDescriptors().isEmpty())) {
Element facets = new Element("facets");
ModuleDescriptorPersistence.saveFacets(facets, descriptor.getModuleFacetDescriptors(), myMacroHelper);
generator.addContent(facets);
}
// "depends on" generators
Element extTemplates = new Element("external-templates");
for (SModuleReference generatorReference : SetSequence.fromSet(descriptor.getDepGenerators())) {
XmlUtil.tagWithAttribute(extTemplates, "generator", "generatorUID", generatorReference.toString());
}
generator.addContent(extTemplates);
ModuleDescriptorPersistence.saveDependencies(generator, descriptor);
// mapping priority rules
Element mapPrio = new Element("mapping-priorities");
for (MappingPriorityRule rule : ListSequence.fromList(descriptor.getPriorityRules())) {
Element ruleElement = new Element("mapping-priority-rule");
ruleElement.setAttribute("kind", rule.getType().getName());
Element gpm = new Element("greater-priority-mapping");
saveGeneratorMappingConfigRef(rule.getLeft(), gpm);
ruleElement.addContent(gpm);
Element lpm = new Element("lesser-priority-mapping");
saveGeneratorMappingConfigRef(rule.getRight(), lpm);
ruleElement.addContent(lpm);
mapPrio.addContent(ruleElement);
}
return generator.addContent(mapPrio);
}
/**
*
* @deprecated use {@link jetbrains.mps.project.persistence.GeneratorDescriptorPersistence#save(GeneratorDescriptor) instance method} instead
*/
@Deprecated
@ToRemove(version = 3.5)
public static void saveGeneratorDescriptor(Element languageGeneratorsElement, GeneratorDescriptor descriptor, MacroHelper macroHelper) {
Element generator = new GeneratorDescriptorPersistence(macroHelper).save(descriptor);
languageGeneratorsElement.addContent(generator);
}
private static void saveGeneratorMappingConfigRef(MappingConfig_AbstractRef mappingRef, Element parentElement) {
if (mappingRef instanceof MappingConfig_RefAllLocal) {
parentElement.addContent(new Element("all-local-mappings"));
} else if (mappingRef instanceof MappingConfig_RefAllGlobal) {
parentElement.addContent(new Element("all-mappings"));
} else if (mappingRef instanceof MappingConfig_SimpleRef) {
XmlUtil.tagWithAttributes(parentElement, "mapping-node", "modelUID", ((MappingConfig_SimpleRef) mappingRef).getModelUID(), "nodeID", ((MappingConfig_SimpleRef) mappingRef).getNodeID());
} else if (mappingRef instanceof MappingConfig_ExternalRef) {
XmlUtil.tagWithAttribute(parentElement, "generator", "generatorUID", ((MappingConfig_ExternalRef) mappingRef).getGenerator().toString());
Element extMapping = new Element("external-mapping");
saveGeneratorMappingConfigRef(((MappingConfig_ExternalRef) mappingRef).getMappingConfig(), extMapping);
parentElement.addContent(extMapping);
} else if (mappingRef instanceof MappingConfig_RefSet) {
Element mappingSet = new Element("mapping-set");
for (MappingConfig_AbstractRef mappingRefInner : ListSequence.fromList(((MappingConfig_RefSet) mappingRef).getMappingConfigs())) {
Element mappingSetElement = new Element("mapping-set-element");
saveGeneratorMappingConfigRef(mappingRefInner, mappingSetElement);
mappingSet.addContent(mappingSetElement);
}
parentElement.addContent(mappingSet);
}
}
private static MappingConfig_AbstractRef loadGeneratorMappingConfigRef(final Element parentElement, final String genUID, boolean childOfGen) {
// FIXME there seems to be little reason (if any) to change MCref structure during read. Consider removing childOfGen
// attribute altogether
if (Sequence.fromIterable(XmlUtil.children(parentElement, "all-mappings")).isNotEmpty()) {
return new MappingConfig_RefAllGlobal();
} else if (Sequence.fromIterable(XmlUtil.children(parentElement, "all-local-mappings")).isNotEmpty()) {
final MappingConfig_RefAllLocal local = new MappingConfig_RefAllLocal();
if (childOfGen) {
return local;
}
return new _FunctionTypes._return_P0_E0<MappingConfig_ExternalRef>() {
public MappingConfig_ExternalRef invoke() {
final MappingConfig_ExternalRef result_wk2vdq_a0a3a0c0p = new MappingConfig_ExternalRef();
final SModuleReference result_wk2vdq_a0a0a3a0c0p = PersistenceFacade.getInstance().createModuleReference(genUID);
result_wk2vdq_a0a3a0c0p.setGenerator(result_wk2vdq_a0a0a3a0c0p);
final MappingConfig_AbstractRef result_wk2vdq_a1a0a3a0c0p = local;
result_wk2vdq_a0a3a0c0p.setMappingConfig(result_wk2vdq_a1a0a3a0c0p);
return result_wk2vdq_a0a3a0c0p;
}
}.invoke();
} else if (XmlUtil.first(parentElement, "mapping-set") != null) {
MappingConfig_RefSet mappingSet = new MappingConfig_RefSet();
for (Element mappingSetElement : Sequence.fromIterable(XmlUtil.children(XmlUtil.first(parentElement, "mapping-set"), "mapping-set-element"))) {
mappingSet.getMappingConfigs().add(loadGeneratorMappingConfigRef(mappingSetElement, genUID, childOfGen));
}
return mappingSet;
} else if (XmlUtil.first(parentElement, "generator") != null) {
// external reference
final Element generator = XmlUtil.first(parentElement, "generator");
return new _FunctionTypes._return_P0_E0<MappingConfig_ExternalRef>() {
public MappingConfig_ExternalRef invoke() {
final MappingConfig_ExternalRef result_wk2vdq_a0a2a2c0p = new MappingConfig_ExternalRef();
final SModuleReference result_wk2vdq_a0a0a2a2c0p = PersistenceFacade.getInstance().createModuleReference(generator.getAttributeValue("generatorUID"));
result_wk2vdq_a0a2a2c0p.setGenerator(result_wk2vdq_a0a0a2a2c0p);
final MappingConfig_AbstractRef result_wk2vdq_a1a0a2a2c0p = loadGeneratorMappingConfigRef(XmlUtil.first(parentElement, "external-mapping"), generator.getAttributeValue("generatorUID"), true);
result_wk2vdq_a0a2a2c0p.setMappingConfig(result_wk2vdq_a1a0a2a2c0p);
return result_wk2vdq_a0a2a2c0p;
}
}.invoke();
} else if (XmlUtil.first(parentElement, "mapping-node") != null) {
// simple reference
Element mappingNode = XmlUtil.first(parentElement, "mapping-node");
final MappingConfig_SimpleRef mapping_SimpleRef = new MappingConfig_SimpleRef();
MappingConfig_SimpleRef result_wk2vdq_a3a3c0p = mapping_SimpleRef;
final String result_wk2vdq_a0a3a3c0p = mappingNode.getAttributeValue("modelUID");
result_wk2vdq_a3a3c0p.setModelUID(result_wk2vdq_a0a3a3c0p);
final String result_wk2vdq_a1a3a3c0p = mappingNode.getAttributeValue("nodeID");
result_wk2vdq_a3a3c0p.setNodeID(result_wk2vdq_a1a3a3c0p);
if (childOfGen) {
return mapping_SimpleRef;
}
return new _FunctionTypes._return_P0_E0<MappingConfig_ExternalRef>() {
public MappingConfig_ExternalRef invoke() {
final MappingConfig_ExternalRef result_wk2vdq_a0a7a3c0p = new MappingConfig_ExternalRef();
final SModuleReference result_wk2vdq_a0a0a7a3c0p = PersistenceFacade.getInstance().createModuleReference(genUID);
result_wk2vdq_a0a7a3c0p.setGenerator(result_wk2vdq_a0a0a7a3c0p);
final MappingConfig_AbstractRef result_wk2vdq_a1a0a7a3c0p = mapping_SimpleRef;
result_wk2vdq_a0a7a3c0p.setMappingConfig(result_wk2vdq_a1a0a7a3c0p);
return result_wk2vdq_a0a7a3c0p;
}
}.invoke();
}
// empty?
return new MappingConfig_AbstractRef();
}
}