private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event) {
    if (!toProcessPsiEvent()) return;
    final PsiFile psiFile = event.getFile();
    if (!(psiFile instanceof PsiFileEx) || !((PsiFileEx) psiFile).isContentsLoaded()) return;

    final Document document = myPsiDocumentManager.getCachedDocument(psiFile);
    if (document != null && myPsiDocumentManager.isUncommited(document)) {
      throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
    }
  }
  public boolean commitTransaction(final Document document) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DocumentChangeTransaction documentChangeTransaction = removeTransaction(document);
    if (documentChangeTransaction == null) return false;
    final PsiFile changeScope = documentChangeTransaction.myChangeScope;
    try {
      mySyncDocument = document;

      final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
      fakeEvent.setParent(changeScope);
      fakeEvent.setFile(changeScope);
      checkPsiModificationAllowed(fakeEvent);
      doSync(
          fakeEvent,
          true,
          new DocSyncAction() {
            @Override
            public void syncDocument(
                @NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
              doCommitTransaction(document, documentChangeTransaction);
            }
          });
      myBus
          .syncPublisher(PsiDocumentTransactionListener.TOPIC)
          .transactionCompleted(document, changeScope);
    } catch (Throwable e) {
      myPsiDocumentManager.forceReload(
          changeScope.getViewProvider().getVirtualFile(), changeScope.getViewProvider());
      ExceptionUtil.rethrowAllAsUnchecked(e);
    } finally {
      mySyncDocument = null;
    }
    return true;
  }
 private DocumentEx getCachedDocument(PsiFile psiFile, boolean force) {
   final DocumentEx document = (DocumentEx) myPsiDocumentManager.getCachedDocument(psiFile);
   if (document == null
       || document instanceof DocumentWindow
       || !force && getTransaction(document) == null) {
     return null;
   }
   return document;
 }
  private void doSync(
      @NotNull final PsiTreeChangeEvent event,
      boolean force,
      @NotNull final DocSyncAction syncAction) {
    if (!toProcessPsiEvent()) return;
    final PsiFile psiFile = event.getFile();
    if (psiFile == null || psiFile.getNode() == null) return;

    final DocumentEx document = (DocumentEx) myPsiDocumentManager.getCachedDocument(psiFile);
    if (document == null || document instanceof DocumentWindow) return;
    if (!force && getTransaction(document) == null) {
      return;
    }

    TextBlock textBlock = TextBlock.get(psiFile);

    if (!textBlock.isEmpty()) {
      throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
    }

    textBlock.performAtomically(
        new Runnable() {
          @Override
          public void run() {
            syncAction.syncDocument(document, (PsiTreeChangeEventImpl) event);
          }
        });

    final boolean insideTransaction = myTransactionsMap.containsKey(document);
    if (!insideTransaction) {
      document.setModificationStamp(psiFile.getViewProvider().getModificationStamp());
      if (LOG.isDebugEnabled()) {
        PsiDocumentManagerBase.checkConsistency(psiFile, document);
      }
    }

    psiFile.getViewProvider().contentsSynchronized();
  }
 public boolean toProcessPsiEvent() {
   return !myIgnorePsiEvents
       && !myPsiDocumentManager.isCommitInProgress()
       && !ApplicationManager.getApplication().hasWriteAction(IgnorePsiEventsMarker.class);
 }