public final <T, S extends PsiFileStub<?>> T withGreenStubOrAst(
    Class<S> stubClass,
    Function<S, T> stubProcessor,
    Function<FileElement, T> astProcessor
  ) {
    Pair<@Nullable StubTree, @Nullable FileElement> result = getStubTreeOrFileElement();
    StubElement<?> stubElement = result.first != null ? result.first.getRoot() : null;
    if (stubElement != null && !stubClass.isAssignableFrom(stubElement.getClass())) {
      IStubFileElementType<?> elementType = getElementTypeForStubBuilder();
      String elementTypeName = elementType != null ? elementType.getExternalId() : null;
      Logger.getInstance(PsiFileImpl.class).error("stub: " + stubElement.getClass().getName() + "; file: " + elementTypeName);
      stubElement = null;
    }
    if (stubElement != null) {
      //noinspection unchecked
      return stubProcessor.apply((S)stubElement);
    }
    FileElement fileElement = result.second;
    if (fileElement == null) {
      fileElement = calcTreeElement();
    }
    return astProcessor.apply(fileElement);
  }
public final <T, S extends PsiFileStub<?>> T withGreenStubOrAst(
    Class<S> stubClass,
    Function<S, T> stubProcessor,
    Function<FileElement, T> astProcessor
  )