package com.thoughtworks.gauge.stub;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.IOUtil;
import com.intellij.util.io.KeyDescriptor;
import com.thoughtworks.gauge.language.ConceptFileType;
import com.thoughtworks.gauge.language.SpecFileType;
import com.thoughtworks.gauge.language.psi.impl.ConceptStepImpl;
import com.thoughtworks.gauge.language.psi.impl.SpecStepImpl;
import com.thoughtworks.gauge.util.GaugeUtil;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class FileStub extends FileBasedIndexExtension<String, Set<Integer>> {
@NonNls
public static final ID<String, Set<Integer>> NAME = ID.create("FormClassIndex");
@NotNull
@Override
public ID<String, Set<Integer>> getName() {
return NAME;
}
@NotNull
@Override
public DataIndexer<String, Set<Integer>, FileContent> getIndexer() {
return fileContent -> {
Set<Integer> offsets = new HashSet<>();
List<PsiElement> steps = new ArrayList<>();
PsiFile psiFile;
try {
psiFile = ((FileContentImpl) fileContent).createFileFromText(FileUtils.readFileToString(new File(fileContent.getFile().getPath())));
} catch (IOException e) {
return Collections.emptyMap();
}
if (fileContent.getFileType() instanceof SpecFileType)
steps = new ArrayList<>(PsiTreeUtil.collectElementsOfType(psiFile, SpecStepImpl.class));
else if (fileContent.getFileType() instanceof ConceptFileType)
steps = new ArrayList<>(PsiTreeUtil.collectElementsOfType(psiFile, ConceptStepImpl.class));
steps.forEach((s) -> offsets.add(s.getTextOffset()));
return Collections.singletonMap(fileContent.getFile().getPath(), offsets);
};
}
@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new KeyDescriptor<String>() {
@Override
public int getHashCode(String s) {
return s.hashCode();
}
@Override
public boolean isEqual(String s, String t1) {
return s.equals(t1);
}
@Override
public void save(@NotNull DataOutput dataOutput, String s) throws IOException {
IOUtil.writeUTF(dataOutput, s);
}
@Override
public String read(@NotNull DataInput dataInput) throws IOException {
return IOUtil.readUTF(dataInput);
}
};
}
@NotNull
@Override
public DataExternalizer<Set<Integer>> getValueExternalizer() {
return new DataExternalizer<Set<Integer>>() {
@Override
public void save(@NotNull DataOutput dataOutput, Set<Integer> integers) throws IOException {
String offsets = "";
for (Integer integer : integers) offsets += integer.toString() + ",";
IOUtil.writeUTF(dataOutput, offsets);
}
@Override
public Set<Integer> read(@NotNull DataInput dataInput) throws IOException {
Set<Integer> offsets = new HashSet<>();
String s = IOUtil.readUTF(dataInput);
for (String offset : s.split(","))
if (!offset.equals(""))
offsets.add(Integer.parseInt(offset));
return offsets;
}
};
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new FileBasedIndex.FileTypeSpecificInputFilter() {
@Override
public void registerFileTypesUsedForIndexing(@NotNull Consumer<FileType> consumer) {
consumer.consume(SpecFileType.INSTANCE);
consumer.consume(ConceptFileType.INSTANCE);
}
@Override
public boolean acceptInput(@NotNull VirtualFile virtualFile) {
return virtualFile.getExtension() != null && GaugeUtil.isGaugeFile(virtualFile);
}
};
}
@Override
public boolean dependsOnFileContent() {
return true;
}
@Override
public int getVersion() {
return 0;
}
}