<div dir="ltr"><div dir="ltr"><div>After implementing option 2, I've changed my mind and I think we should remove the check. <br></div><div><br></div><div>Right now, DraftStore::UpdateDraft takes the start position and end position of the LSP message (specified in UTF-16 code units) and calculates the length of the range in bytes. What we'd be doing with option 2 is converting that length back to UTF-16 code units and checking whether it's equal to the rangeLength of the LSP message. This is nothing more than a really complicated check to see whether 'LSP.end - LSP.start == LSP.rangeLength'. The check could just as easily done without the conversion to bytes, but then we're really only checking whether the client calculated the rangeLength correctly. Since the rangeLength isn't used by the rest of clangd I propose to just ignore it. rangeLength seems to be redundant since we just calculate it ourselves. I also found an issue about this in the LSP repository: <a href="https://github.com/Microsoft/language-server-protocol/issues/9">https://github.com/Microsoft/language-server-protocol/issues/9</a>.</div><div><br></div><div>Regards,</div><div><br></div><div>Daan<br></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 22 Oct 2018 at 13:48, Sam McCall <<a href="mailto:sammccall@google.com">sammccall@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Mon, Oct 22, 2018 at 1:32 PM Daan De Meyer <<a href="mailto:daan.j.demeyer@gmail.com" target="_blank">daan.j.demeyer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br></div><div>My only concern is that we'll break clients that 
make the equal and opposite mistake (sending byte lengths instead of 
UTF-16 lengths).</div><div>Maybe we should also downgrade this error to a
 log message, since we can presumably trust the length from the string. 
What do you think?</div></blockquote><div><br></div><div>I think the check is useful just to verify if the client and server are on the same page so I'm partial to option 2 as well. Downgrading to a log message avoids outright breaking existing clients so that seems like the way to go. As soon as Github is back up I'll make an issue asking to clarify the unit of rangeLength in the lsp repository as well.</div></div></div></blockquote><div>Thanks!</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>Assuming we go with option 2 (including downgrading to an error message), I have two more questions:</div><div><br></div><div>1. Which header should I put the utf16Len function in (from SourceCode.cpp)? I tried searching for an existing header with UTF functions but I didn't immediately find one.</div></div></div></blockquote><div>I think SourceCode.h is a reasonable fit within clangd. (There are some UTF libraries in llvm/support, but it's not clear this belongs there and it'd be a bunch of work).</div><div><br></div><div>Consider renaming it something like `lspLength()` or so and keeping the bits about UTF-16 in the function comment.</div><div>That's kind of a low-level detail.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>2. How do I go about downgrading to a log message? Do I just write to errs()?<br></div></div></div></blockquote><div>We use the log() functions in clangd/Logger.h. (Abstracts the destination, handles locking, does formatting).</div><div><br></div><div>This one is scary+rare enough it should probably be an error log.</div><div>The functions use formatv syntax, so something like:</div><div>  elog("bad TextDocumentContentChangeEvent: rangeLength={0} but computed length {1} for {2}",</div><div>       *change.rangeLength, Len, change.text);</div><div><br></div><div>Cheers, Sam</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div>
</blockquote></div></div>
</blockquote></div>