/*
* 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.idea.core.psi;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import com.intellij.psi.SingleRootFileViewProvider;
import jetbrains.mps.fileTypes.MPSLanguage;
import jetbrains.mps.ide.project.ProjectHelper;
import jetbrains.mps.idea.core.psi.impl.MPSPsiProvider;
import jetbrains.mps.idea.core.psi.impl.MPSPsiRootNode;
import jetbrains.mps.nodefs.MPSNodeVirtualFile;
import jetbrains.mps.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SRepository;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Created by danilla on 12/19/14.
*/
public class MPSNodeFileViewProvider extends SingleRootFileViewProvider {
private final static boolean EVENT_SYSTEM_ENABLED = false;
private final static Language LANGUAGE = MPSLanguage.INSTANCE;
private static final String emptyString = "";
private final PsiManager myManager;
public MPSNodeFileViewProvider(@NotNull PsiManager manager, @NotNull MPSNodeVirtualFile nodeFile) {
super(manager, nodeFile, EVENT_SYSTEM_ENABLED, LANGUAGE);
myManager = manager;
}
@NotNull
@Override
public PsiManager getManager() {
return myManager;
}
@Nullable
@Override
public Document getDocument() {
return null;
}
@NotNull
@Override
public CharSequence getContents() {
return emptyString;
}
@NotNull
@Override
public Language getBaseLanguage() {
return LANGUAGE;
}
@NotNull
@Override
public Set<Language> getLanguages() {
return Collections.singleton(getBaseLanguage());
}
@Override
public PsiFile getPsiInner(@NotNull Language target) {
// todo assert idea read
if (target != getBaseLanguage()) {
return null;
}
Project p = ProjectHelper.fromIdeaProject(getManager().getProject());
assert p != null;
final SRepository repo = p.getRepository();
final Ref<PsiElement> result = new Ref<>(null);
// todo use MPSNodeVirtualFile.getNode() (rewrite it to project repo)
repo.getModelAccess().runReadAction(() -> {
SNode sNode = ((MPSNodeVirtualFile)getVirtualFile()).getSNodePointer().resolve(repo);
if (sNode != null) {
result.set(MPSPsiProvider.getInstance(getManager().getProject()).getPsi(sNode));
}
});
if (result.get() == null) {
return null;
}
PsiFile psiFile = result.get().getContainingFile();
assert psiFile instanceof MPSPsiRootNode;
return psiFile;
}
@NotNull
@Override
public List<PsiFile> getAllFiles() {
return Collections.singletonList(getPsi(getBaseLanguage()));
}
@Override
public boolean isEventSystemEnabled() {
return EVENT_SYSTEM_ENABLED;
}
@Override
public boolean isPhysical() {
return false;
}
@Override
public long getModificationStamp() {
// TODO: check if we need to override this method.
// We relay on file modification instead of content.
return getVirtualFile().getModificationStamp();
}
@Override
public boolean supportsIncrementalReparse(@NotNull Language rootLanguage) {
return false;
}
@Override
public void rootChanged(@NotNull PsiFile psiFile) {
}
@Override
public void beforeContentsSynchronized() {
}
@Override
public void contentsSynchronized() {
}
@Override
public FileViewProvider clone() {
throw new IllegalStateException("mps file view provider -> clone()");
}
@Nullable
@Override
public PsiElement findElementAt(int offset) {
return null;
}
@Nullable
@Override
public PsiReference findReferenceAt(int offset) {
return null;
}
@Nullable
@Override
public PsiElement findElementAt(int offset, @NotNull Language language) {
return null;
}
@Nullable
@Override
public PsiElement findElementAt(int offset, @NotNull Class<? extends Language> lang) {
return null;
}
@Nullable
@Override
public PsiReference findReferenceAt(int offsetInElement, @NotNull Language language) {
return null;
}
@NotNull
@Override
public SingleRootFileViewProvider createCopy(@NotNull VirtualFile copy) {
if (!(copy instanceof MPSNodeVirtualFile)) {
throw new IllegalStateException();
}
return new MPSNodeFileViewProvider(getManager(), (MPSNodeVirtualFile) copy);
}
@NotNull
@Override
public PsiFile getStubBindingRoot() {
PsiFile psi = getPsi(getBaseLanguage());
assert psi != null;
return psi;
}
@Nullable
@Override
public <T> T getUserData(@NotNull Key<T> key) {
return null;
}
@Override
public <T> void putUserData(@NotNull Key<T> key, T value) {
}
}