internal override SourceLocation GetLocation(int position) { if (position < 0 || position > _document.Length) { throw new IndexOutOfRangeException(nameof(position)); } var index = Array.BinarySearch <int>(_lineStarts, position); if (index >= 0) { // We have an exact match for the start of a line. Debug.Assert(_lineStarts[index] == position); return(new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex: 0)); } // Index is the complement of the line *after* the one we want, because BinarySearch tells // us where we'd put position *if* it were the start of a line. index = (~index) - 1; if (index == -1) { // There's no preceding line, so it's based on the start of the string return(new SourceLocation(_document.GetFilePathForDisplay(), position, 0, position)); } else { var characterIndex = position - _lineStarts[index]; return(new SourceLocation(_document.GetFilePathForDisplay(), position, index, characterIndex)); } }