TokenProcessor (int startIndex, @NotNull SegmentArrayWithData segments, @NotNull CharSequence text) { MappingSegments mappingSegments = (MappingSegments)segments; return new TokenProcessor() { final Map<Mapper, LightMapper> docTexts = FactoryMap.create(key -> { MappedRange predecessor = key.findPredecessor(startIndex, mappingSegments); return new LightMapper(key, predecessor != null ? predecessor.range.getEndOffset() : 0); }); @Override public void addToken(int tokenIndex, int startOffset, int endOffset, int data, @NotNull IElementType tokenType) { mappingSegments.setElementLight(tokenIndex, startOffset, endOffset, data); Mapper mapper = mappingSegments.getMappingDocument(tokenType); if (mapper != null) { docTexts.get(mapper).addToken(text.subSequence(startOffset, endOffset), tokenType, tokenIndex); } } @Override public void finish() { docTexts.keySet().forEach(mapper -> mappingSegments.freezeHighlighter(mapper)); for (LightMapper mapper : docTexts.values()) { mapper.finish(); } } }; }