@NotNull
  private static XmlFileHeader calcXmlFileHeader(final XmlFile file) {

    if (file instanceof PsiFileEx
        && ((PsiFileEx) file).isContentsLoaded()
        && file.getNode().isParsed()) {
      return computeHeaderByPsi(file);
    }

    if (!XmlUtil.isStubBuilding() && file.getFileType() == XmlFileType.INSTANCE) {
      VirtualFile virtualFile = file.getVirtualFile();
      if (virtualFile instanceof VirtualFileWithId) {
        ObjectStubTree tree =
            StubTreeLoader.getInstance().readFromVFile(file.getProject(), virtualFile);
        if (tree != null) {
          Stub root = tree.getRoot();
          if (root instanceof FileStub) {
            return ((FileStub) root).getHeader();
          }
        }
      }
    }

    if (!file.isValid()) return XmlFileHeader.EMPTY;

    return NanoXmlUtil.parseHeader(file);
  }
 @Override
 @NotNull
 public XmlFileHeader getXmlFileHeader(XmlFile file) {
   return file.isValid()
       ? ourRootTagCache.get(ROOT_TAG_NS_KEY, file, null).getValue()
       : XmlFileHeader.EMPTY;
 }
 protected CachedValue<XmlFileHeader> compute(final XmlFile file, final Object o) {
   return CachedValuesManager.getManager(file.getProject())
       .createCachedValue(
           new CachedValueProvider<XmlFileHeader>() {
             public Result<XmlFileHeader> compute() {
               return new Result<XmlFileHeader>(calcXmlFileHeader(file), file);
             }
           },
           false);
 }
  private static XmlFileHeader computeHeaderByPsi(XmlFile file) {
    final XmlDocument document = file.getDocument();
    if (document == null) {
      return XmlFileHeader.EMPTY;
    }

    String publicId = null;
    String systemId = null;
    final XmlProlog prolog = document.getProlog();
    if (prolog != null) {
      final XmlDoctype doctype = prolog.getDoctype();
      if (doctype != null) {
        publicId = doctype.getPublicId();
        systemId = doctype.getSystemId();
        if (systemId == null) {
          systemId = doctype.getDtdUri();
        }
      }
    }

    final XmlTag tag = document.getRootTag();
    if (tag == null) {
      return XmlFileHeader.EMPTY;
    }

    String localName = tag.getLocalName();
    if (StringUtil.isNotEmpty(localName)) {
      if (tag.getPrevSibling() instanceof PsiErrorElement) {
        return XmlFileHeader.EMPTY;
      }

      String psiNs = tag.getNamespace();
      return new XmlFileHeader(
          localName,
          psiNs == XmlUtil.EMPTY_URI || Comparing.equal(psiNs, systemId) ? null : psiNs,
          publicId,
          systemId);
    }
    return XmlFileHeader.EMPTY;
  }