package jetbrains.mps.vcs.diff.ui; /*Generated by MPS */ import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.vcs.diff.merge.MergeTemporaryModel; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.vcs.diff.ui.common.DiffModelUtil; import jetbrains.mps.extapi.model.SModelBase; import org.jetbrains.mps.openapi.model.SNodeId; import org.jetbrains.mps.openapi.persistence.PersistenceFacade; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations; import jetbrains.mps.extapi.model.GeneratableSModel; import org.jetbrains.mps.openapi.language.SLanguage; import jetbrains.mps.internal.collections.runtime.CollectionSequence; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; import org.jetbrains.mps.openapi.module.SModuleReference; import org.jetbrains.mps.openapi.model.SModelReference; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations; import jetbrains.mps.smodel.adapter.structure.language.SLanguageAdapter; import org.jetbrains.mps.openapi.model.EditableSModel; import java.util.Set; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.LinkedHashSet; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.internal.collections.runtime.IVisitor; public class MetadataUtil { public MetadataUtil() { } public static SModel createMetadataModel(SModel model, String version, boolean editable) { MergeTemporaryModel metadataModel = new MergeTemporaryModel(model.getReference(), !(editable)); metadataModel.addLanguage(MetaAdapterFactory.getLanguage(0x6df0089f32884998L, 0x9d57e698e7c8e145L, "jetbrains.mps.ide.vcs.modelmetadata")); metadataModel.addLanguage(MetaAdapterFactory.getLanguage(0x86ef829012bb4ca7L, 0x947f093788f263a9L, "jetbrains.mps.lang.project")); createModelRoot(metadataModel, model); DiffModelUtil.renameModelAndRegister(metadataModel, version); // XXX it looks isChanged used as indication whether there's anything in the model to apply. // If yes, why not use dedicated flag in MergeTemporaryModel, and cease being EditableSModel? metadataModel.setChanged(false); return metadataModel; } public static void dispose(SModel model) { DiffModelUtil.unregisterModel(model); } private static void createModelRoot(SModel target, SModel origin) { SModelBase modelBase = (SModelBase) origin; SNodeId nodeId = PersistenceFacade.getInstance().createNodeId("~root"); SNode root = SModelOperations.createNewNode(target, nodeId, MetaAdapterFactory.getConcept(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, "jetbrains.mps.ide.vcs.modelmetadata.structure.Model")); SPropertyOperations.set(root, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x7439be589a4e11e6L, "longname"), SModelOperations.getModelName(origin)); if (origin instanceof GeneratableSModel) { SPropertyOperations.set(root, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x7439be589a4e11f4L, "donotgenerate"), "" + (check_ca1g54_a0a0e0d(((GeneratableSModel) origin)))); } for (SLanguage language : CollectionSequence.fromCollection(modelBase.importedLanguageIds())) { ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d80188636L, "language"))).addElement(createLanguageNode(language)); } for (SLanguage genlanguage : CollectionSequence.fromCollection(modelBase.getLanguagesEngagedOnGeneration())) { ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d80188638L, "languageEngagedOnGeneration"))).addElement(createLanguageNode(genlanguage)); } for (SModuleReference devkit : ListSequence.fromList(modelBase.importedDevkits())) { ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d8018863bL, "devkit"))).addElement(createModuleRefNode(devkit)); } for (SModelReference impmodel : ListSequence.fromList(jetbrains.mps.smodel.SModelOperations.getImportedModelUIDs(modelBase))) { ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d8018863fL, "import"))).addElement(createModelRefNode(impmodel)); } SPropertyOperations.set(root, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"), "Model Properties"); SModelOperations.addRootNode(target, root); } private static SNode createLanguageNode(SLanguage lang) { SNode rv = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x660570953ee5d6b9L, "jetbrains.mps.ide.vcs.modelmetadata.structure.LanguageDependency")); // XXX it's bad to cast to implementation class, but it's MPS internal code and this is fastest approach // (although the right way is to extract part of smodel language related to metadata handling, like LanguageIdentity // into separate language and re-use it here). // After all, there's be no need in all concepts but Model in mps.ide.vcs.modelmetadata language. SPropertyOperations.set(rv, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x660570953ee5d6b9L, 0x660570953ee5dadfL, "value"), ((SLanguageAdapter) lang).serialize()); // see createModuleRefNode, below, for explanation why we need custom id ((jetbrains.mps.smodel.SNode) rv).setId(new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + SPropertyOperations.getString(rv, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x660570953ee5d6b9L, 0x660570953ee5dadfL, "value")))); return rv; } private static SLanguage getLanguage(SNode node) { return SLanguageAdapter.deserialize(SPropertyOperations.getString(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x660570953ee5d6b9L, 0x660570953ee5dadfL, "value"))); } private static SNode createModuleRefNode(SModuleReference module) { SNode node = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafe1L, "jetbrains.mps.ide.vcs.modelmetadata.structure.ModuleReference")); SPropertyOperations.set(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafe1L, 0x39c8ca3b79aaafe2L, "stringValue"), PersistenceFacade.getInstance().asString(module)); // The purpose of custom node id here is to have identical IDs for the same imports in different models // That's why don't we rely on automatic node id. // FIXME keep model as instance field and use model.new node smodel clause, with id set at construction time, without cast to SNode impl ((jetbrains.mps.smodel.SNode) node).setId(new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + SPropertyOperations.getString(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafe1L, 0x39c8ca3b79aaafe2L, "stringValue")))); return node; } private static SModuleReference getModuleReference(SNode node) { return PersistenceFacade.getInstance().createModuleReference(SPropertyOperations.getString(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafe1L, 0x39c8ca3b79aaafe2L, "stringValue"))); } private static SNode createModelRefNode(SModelReference modelReference) { SNode node = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafdeL, "jetbrains.mps.ide.vcs.modelmetadata.structure.ModelReference")); SPropertyOperations.set(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafdeL, 0x39c8ca3b79aaafdfL, "stringValue"), PersistenceFacade.getInstance().asString(modelReference)); ((jetbrains.mps.smodel.SNode) node).setId(new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + SPropertyOperations.getString(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafdeL, 0x39c8ca3b79aaafdfL, "stringValue")))); return node; } private static SModelReference getModelReference(SNode node) { return PersistenceFacade.getInstance().createModelReference(SPropertyOperations.getString(node, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x39c8ca3b79aaafdeL, 0x39c8ca3b79aaafdfL, "stringValue"))); } public static void applyMetadataChanges(SModel model, SModel metadataModel) { if (!(((EditableSModel) metadataModel).isChanged())) { return; } final SModelBase modelBase = (SModelBase) model; SNode root = ListSequence.fromList(SModelOperations.roots(metadataModel, MetaAdapterFactory.getConcept(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, "jetbrains.mps.ide.vcs.modelmetadata.structure.Model"))).first(); if (model instanceof GeneratableSModel) { ((GeneratableSModel) model).setDoNotGenerate(SPropertyOperations.getBoolean(root, MetaAdapterFactory.getProperty(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x7439be589a4e11f4L, "donotgenerate"))); } Set<SLanguage> oldImpLang = SetSequence.fromSetWithValues(new LinkedHashSet<SLanguage>(), modelBase.importedLanguageIds()); Set<SLanguage> impLang = SetSequence.fromSetWithValues(new LinkedHashSet<SLanguage>(), ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d80188636L, "language"))).select(new ISelector<SNode, SLanguage>() { public SLanguage select(SNode it) { return getLanguage(it); } })); SetSequence.fromSet(oldImpLang).subtract(SetSequence.fromSet(impLang)).visitAll(new IVisitor<SLanguage>() { public void visit(SLanguage it) { modelBase.deleteLanguageId(it); } }); SetSequence.fromSet(impLang).subtract(SetSequence.fromSet(oldImpLang)).visitAll(new IVisitor<SLanguage>() { public void visit(SLanguage it) { modelBase.addLanguage(it); } }); Set<SLanguage> oldGenLang = SetSequence.fromSetWithValues(new LinkedHashSet<SLanguage>(), modelBase.getLanguagesEngagedOnGeneration()); Set<SLanguage> genLang = SetSequence.fromSetWithValues(new LinkedHashSet<SLanguage>(), ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d80188638L, "languageEngagedOnGeneration"))).select(new ISelector<SNode, SLanguage>() { public SLanguage select(SNode it) { return getLanguage(it); } })); SetSequence.fromSet(oldGenLang).subtract(SetSequence.fromSet(genLang)).visitAll(new IVisitor<SLanguage>() { public void visit(SLanguage it) { modelBase.removeEngagedOnGenerationLanguage(it); } }); SetSequence.fromSet(genLang).subtract(SetSequence.fromSet(oldGenLang)).visitAll(new IVisitor<SLanguage>() { public void visit(SLanguage it) { modelBase.addEngagedOnGenerationLanguage(it); } }); Set<SModuleReference> oldDevkit = SetSequence.fromSetWithValues(new LinkedHashSet<SModuleReference>(), modelBase.importedDevkits()); Set<SModuleReference> devkit = SetSequence.fromSetWithValues(new LinkedHashSet<SModuleReference>(), ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d8018863bL, "devkit"))).select(new ISelector<SNode, SModuleReference>() { public SModuleReference select(SNode it) { return getModuleReference(it); } })); SetSequence.fromSet(oldDevkit).subtract(SetSequence.fromSet(devkit)).visitAll(new IVisitor<SModuleReference>() { public void visit(SModuleReference it) { modelBase.deleteDevKit(it); } }); SetSequence.fromSet(devkit).subtract(SetSequence.fromSet(oldDevkit)).visitAll(new IVisitor<SModuleReference>() { public void visit(SModuleReference it) { modelBase.addDevKit(it); } }); Set<SModelReference> oldImports = SetSequence.fromSetWithValues(new LinkedHashSet<SModelReference>(), jetbrains.mps.smodel.SModelOperations.getImportedModelUIDs(model)); Set<SModelReference> imports = SetSequence.fromSetWithValues(new LinkedHashSet<SModelReference>(), ListSequence.fromList(SLinkOperations.getChildren(root, MetaAdapterFactory.getContainmentLink(0x6df0089f32884998L, 0x9d57e698e7c8e145L, 0x7439be589a4e116dL, 0x4104ff8d8018863fL, "import"))).select(new ISelector<SNode, SModelReference>() { public SModelReference select(SNode it) { return getModelReference(it); } })); SetSequence.fromSet(oldImports).subtract(SetSequence.fromSet(imports)).visitAll(new IVisitor<SModelReference>() { public void visit(SModelReference it) { modelBase.deleteModelImport(it); } }); SetSequence.fromSet(imports).subtract(SetSequence.fromSet(oldImports)).visitAll(new IVisitor<SModelReference>() { public void visit(SModelReference it) { modelBase.addModelImport(it, false); } }); ((EditableSModel) metadataModel).setChanged(false); } private static boolean check_ca1g54_a0a0e0d(GeneratableSModel checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.isDoNotGenerate(); } return false; } }