// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.devkit.dom.index;

import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.indexing.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.dom.IdeaPlugin;
import org.jetbrains.idea.devkit.util.DescriptorUtil;

import java.util.Collections;
import java.util.Map;

abstract class PluginXmlIndexBase<K, V> extends FileBasedIndexExtension<K, V> {

  protected abstract Map<K, V> performIndexing(IdeaPlugin plugin);

  @Override
  public boolean dependsOnFileContent() {
    return true;
  }

  @NotNull
  @Override
  public FileBasedIndex.InputFilter getInputFilter() {
    return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML);
  }

  @NotNull
  @Override
  public DataIndexer<K, V, FileContent> getIndexer() {
    return new DataIndexer<K, V, FileContent>() {
      @NotNull
      @Override
      public Map<K, V> map(@NotNull FileContent inputData) {
        IdeaPlugin plugin = obtainIdeaPlugin(inputData);
        if (plugin == null) return Collections.emptyMap();

        return performIndexing(plugin);
      }
    };
  }

  @Nullable
  private static IdeaPlugin obtainIdeaPlugin(@NotNull FileContent content) {
    PsiFile file = content.getPsiFile();
    if (!(file instanceof XmlFile)) return null;

    return DescriptorUtil.getIdeaPlugin((XmlFile)file);
  }
}

@@ -339,16 +339,61 @@
 xing.*;%0A
+import com.intellij.util.text.CharArrayUtil;%0A
 import o
@@ -1485,24 +1485,80 @@
  content) %7B%0A
+    if (!looksLikeIdeaPluginXml(content)) return null;%0A%0A
     PsiFile 
@@ -1695,11 +1695,572 @@
 le);%0A  %7D
+%0A%0A  private static boolean looksLikeIdeaPluginXml(@NotNull FileContent content) %7B%0A    CharSequence text = content.getContentAsText();%0A    int idx = 0;%0A%0A    while (true) %7B%0A      // find open tag%0A      idx = CharArrayUtil.indexOf(text, %22%3C%22, idx);%0A      if (idx == -1) return false;%0A%0A      // ignore processing & comment tags%0A      if (CharArrayUtil.regionMatches(text, idx, %22%3C!--%22) %7C%7C%0A          CharArrayUtil.regionMatches(text, idx, %22%3C?%22)) %7B%0A        idx++;%0A        continue;%0A      %7D%0A%0A      return CharArrayUtil.regionMatches(text, idx, %22%3Cidea-plugin%22);%0A    %7D%0A  %7D
 %0A%7D%0A

add fine-grained text based optimization to skip dom loading by PluginXmlIndex-es