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(); } }