in src/ulsp/internal/protocol/mapper.go [58:99]
func (m *TextOffsetMapper) PositionOffset(p protocol.Position) (int, error) {
m.initLines()
// Validate line number.
if p.Line > uint32(len(m.lineStart)) {
return 0, fmt.Errorf("line number %d out of range 0-%d", p.Line, len(m.lineStart))
} else if p.Line == uint32(len(m.lineStart)) {
if p.Character == 0 {
return len(m.Content), nil // EOF
}
return 0, fmt.Errorf("column is beyond end of file")
}
offset := m.lineStart[p.Line]
content := m.Content[offset:] // rest of file from start of enclosing line
// Advance bytes up to the required number of UTF-16 codes.
col8 := 0
for col16 := 0; col16 < int(p.Character); col16++ {
r, sz := utf8.DecodeRune(content)
if sz == 0 {
return 0, fmt.Errorf("column is beyond end of file")
}
if r == '\n' {
return 0, fmt.Errorf("column is beyond end of line")
}
if sz == 1 && r == utf8.RuneError {
return 0, fmt.Errorf("buffer contains invalid UTF-8 text")
}
content = content[sz:]
if r >= 0x10000 {
col16++ // rune was encoded by a pair of surrogate UTF-16 codes
if col16 == int(p.Character) {
break // requested position is in the middle of a rune
}
}
col8 += sz
}
return offset + col8, nil
}