/* * Copyright 2000-2012 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 com.intellij.psi; import com.intellij.lang.Language; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.LightVirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; /** * Manages language-specific access to PSI for a single file. * <p/> * Custom providers are registered via {@link FileViewProviderFactory}. * <p/> * Please see <a href="http://confluence.jetbrains.net/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview">IntelliJ IDEA Architectural Overview </a> * for high-level overview. * * @see PsiFile#getViewProvider() * @see PsiManager#findViewProvider(VirtualFile) */ public interface FileViewProvider extends Cloneable, UserDataHolder { /** * @return this project's PsiManager */ @NotNull PsiManager getManager(); /** * @return the document corresponding to this file. Can be null for binary or files without events enabled. * * @see FileType#isBinary() * @see PsiBinaryFile * @see #isEventSystemEnabled() */ @Nullable Document getDocument(); /** * @return the contents of this file view provider, which are parsed into PSI trees. May or may not be equal * to the contents of the corresponding document. The latter happens for non-committed documents. * If the document is modified but not yet committed, the result is equivalent to {@link PsiDocumentManager#getLastCommittedText(Document)}. * * @see #getDocument() * @see PsiDocumentManager#isUncommited(Document) */ @NotNull CharSequence getContents(); /** * @return the virtual file corresponding to this view provider. Physical or an instance of {@link LightVirtualFile} for most non-physical files. */ @NotNull VirtualFile getVirtualFile(); /** * @return the language of the main PSI tree (or the only one in a single-tree view providers). Used when returning a PsiFile from * {@link PsiManager#findFile(VirtualFile)}, * {@link PsiDocumentManager#getPsiFile(Document)} etc. */ @NotNull Language getBaseLanguage(); /** * @return all languages this file supports, in no particular order. * * @see #getPsi(com.intellij.lang.Language) */ @NotNull Set<Language> getLanguages(); /** * @param target target language * @return PsiFile for given language, or {@code null} if the language not present */ PsiFile getPsi(@NotNull Language target); /** * @return all PSI files for this view provider. In most cases, just one main file. For multi-root languages, several files. The files' languages * should be the same as {@link #getLanguages()}. The main file which corresponds to {@link #getBaseLanguage()}, should be the first one. Otherwise * the order is non-deterministic and should not be relied upon. */ @NotNull List<PsiFile> getAllFiles(); /** * @return whether PSI events are fired when changes occur inside PSI in this view provider. True for physical files and for some non-physical as well. * * @see PsiTreeChangeListener * @see PsiFileFactory#createFileFromText(String, FileType, CharSequence, long, boolean) * @see PsiFile#isPhysical() */ boolean isEventSystemEnabled(); /** * @return whether this file corresponds to a file on a disk. For such files, {@link PsiFile#getVirtualFile()} returns non-null. * Not to be confused with {@link PsiFile#isPhysical()} which (for historical reasons) returns {@code getViewProvider().isEventSystemEnabled()} * * @see #isEventSystemEnabled() * @see PsiFile#isPhysical() */ boolean isPhysical(); /** * @return a number to quickly check if contents of this view provider have diverged from the corresponding {@link VirtualFile} or {@link Document}. * If a document is modified but not yet committed, the result is the same as {@link PsiDocumentManager#getLastCommittedStamp(Document)} * * @see VirtualFile#getModificationStamp() * @see Document#getModificationStamp() */ long getModificationStamp(); /** * @param rootLanguage one of the root languages * @return whether the PSI file with the specified root language supports incremental reparse. * * @see #getLanguages() */ boolean supportsIncrementalReparse(@NotNull Language rootLanguage); /** * Invoked when any PSI change happens in any of the PSI files corresponding to this view provider. * @param psiFile the file where PSI has just been changed. */ void rootChanged(@NotNull PsiFile psiFile); /** * Invoked before document or VFS changes are processed that affect PSI inside the corresponding file. */ void beforeContentsSynchronized(); /** * Invoked after PSI in the corresponding file is synchronized with the corresponding document, which can happen * after VFS, document or PSI changes.<p/> * * Multi-language file view providers may override this method to recalculate template data languages. * * @see #getLanguages() */ void contentsSynchronized(); /** * @return a copy of this view provider, built on a {@link LightVirtualFile}, not physical and with PSI events disabled. * * @see #isPhysical() * @see #isEventSystemEnabled() * @see #createCopy(VirtualFile) */ FileViewProvider clone(); /** * @param offset an offset in the file * @return the deepest (leaf) PSI element in the main PSI tree at the specified offset. * * @see #getBaseLanguage() * @see #findElementAt(int, Class) * @see #findElementAt(int, com.intellij.lang.Language) * @see PsiFile#findElementAt(int) */ @Nullable PsiElement findElementAt(int offset); /** * @param offset an offset in the file * @return a reference in the main PSI tree at the specified offset. * * @see #getBaseLanguage() * @see PsiFile#findReferenceAt(int) * @see #findReferenceAt(int, com.intellij.lang.Language) */ @Nullable PsiReference findReferenceAt(int offset); /** * @param offset an offset in the file * @return the deepest (leaf) PSI element in the PSI tree with the specified root language at the specified offset. * * @see #getBaseLanguage() * @see #findElementAt(int) */ @Nullable PsiElement findElementAt(int offset, @NotNull Language language); /** * @param offset an offset in the file * @return the deepest (leaf) PSI element in the PSI tree with the specified root language class at the specified offset. * * @see #getBaseLanguage() * @see #findElementAt(int) */ @Nullable PsiElement findElementAt(int offset, @NotNull Class<? extends Language> lang); /** * @param offsetInElement an offset in the file * @return a reference in the PSI tree with the specified root language at the specified offset. * * @see #getBaseLanguage() * @see PsiFile#findReferenceAt(int) * @see #findReferenceAt(int) */ @Nullable PsiReference findReferenceAt(int offsetInElement, @NotNull Language language); /** * Creates a copy of this view provider linked with the give (typically light) file. * The result provider is required to be NOT event-system-enabled. * * @see LightVirtualFile * @see #isEventSystemEnabled() */ @NotNull FileViewProvider createCopy(@NotNull VirtualFile copy); /** * @return the PSI root for which stubs are to be built if supported. By default it's the main root. * * @see #getBaseLanguage() */ @NotNull PsiFile getStubBindingRoot(); /** * @return the same as {@code getVirtualFile().getFileType()}, but cached. */ @NotNull FileType getFileType(); }