package cz.juzna.latte.file;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.LanguageSubstitutors;
import com.intellij.psi.MultiplePsiFilesPerDocumentFileViewProvider;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings;
import com.intellij.psi.templateLanguages.TemplateLanguage;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import cz.juzna.latte.LatteLanguage;
import cz.juzna.latte.lexer.LatteTokenTypes;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
public class LatteFileViewProvider extends MultiplePsiFilesPerDocumentFileViewProvider implements TemplateLanguageFileViewProvider {
// main language of the file (HTML)
private final Language myTemplateDataLanguage;
// default constructor from parent
public LatteFileViewProvider(PsiManager manager, VirtualFile file, boolean physical) {
super(manager, file, physical);
// get the main language of the file
Language dataLang = TemplateDataLanguageMappings.getInstance(manager.getProject()).getMapping(file);
if(dataLang == null) dataLang = StdFileTypes.HTML.getLanguage();
// some magic?
if(dataLang instanceof TemplateLanguage) {
myTemplateDataLanguage = PlainTextLanguage.INSTANCE;
} else {
myTemplateDataLanguage = LanguageSubstitutors.INSTANCE.substituteLanguage(dataLang, file, manager.getProject());
}
}
// constructor to be used by self
public LatteFileViewProvider(PsiManager psiManager, VirtualFile virtualFile, boolean physical, Language myTemplateDataLanguage) {
super(psiManager, virtualFile, physical);
this.myTemplateDataLanguage = myTemplateDataLanguage;
}
@NotNull
@Override
public Language getBaseLanguage() {
return LatteLanguage.LATTE_LANGUAGE;
}
@NotNull
@Override
public Language getTemplateDataLanguage() {
return myTemplateDataLanguage;
}
@NotNull
@Override
public Set<Language> getLanguages() {
return new THashSet<Language>(Arrays.asList(new Language[]{ LatteLanguage.LATTE_LANGUAGE, myTemplateDataLanguage }));
}
@Override
protected MultiplePsiFilesPerDocumentFileViewProvider cloneInner(VirtualFile virtualFile) {
return new LatteFileViewProvider(getManager(), virtualFile, false, myTemplateDataLanguage);
}
@Override
protected PsiFile createFile(Language lang) {
// creating file for main lang (HTML)
if(lang == myTemplateDataLanguage) {
PsiFileImpl file = (PsiFileImpl) LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);
file.setContentElementType(LatteTokenTypes.TEMPLATE_DATA);
return file;
} else if(lang == LatteLanguage.LATTE_LANGUAGE) {
return LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);
} else {
return null;
}
}
}