private @Nullable String getTextAtOffset(
      @MagicConstant(intValues = {AccessibleText.CHARACTER, AccessibleText.WORD, AccessibleText.SENTENCE})
      int type,
      int offset,
      @MagicConstant(intValues = {BEFORE, HERE, AFTER})
      int direction) {
      DocumentEx document = editor.getDocument();
      if (offset < 0 || offset >= document.getTextLength()) {
        return null;
      }
      switch (type) {
        case AccessibleText.CHARACTER: {
          if (offset + direction < document.getTextLength() && offset + direction >= 0) {
            int startOffset = offset + direction;
            return document.getCharsSequence().subSequence(startOffset, startOffset + 1).toString();
          }
          break;
        }

        case AccessibleText.WORD: {
          var word = getWordOrLexeme(offset, direction);
          return word == null ? null : word.text;
        }

        case AccessibleText.SENTENCE: {
          int lineStart = getLineAtOffsetStart(offset, direction);
          int lineEnd = getLineAtOffsetEnd(offset, direction);
          if (lineStart == -1 || lineEnd == -1) {
            return null;
          }
          return document.getCharsSequence().subSequence(lineStart, lineEnd).toString();
        }

        case AccessibleExtendedText.LINE:
        case AccessibleExtendedText.ATTRIBUTE_RUN:
          // Not expected to be called in this method!
          assert false : type;

        default:
          break;
      }

      return null;
    }
private @Nullable String getTextAtOffset(
      @MagicConstant(intValues = {AccessibleText.CHARACTER, AccessibleText.WORD, AccessibleText.SENTENCE})
      int type,
      int offset,
      @MagicConstant(intValues = {BEFORE, HERE, AFTER})
      int direction)