[clangd] Upgrade logging facilities with levels and formatv.

Summary:
log() is split into four functions:
 - elog()/log()/vlog() have different severity levels, allowing filtering
 - dlog() is a lazy macro which uses LLVM_DEBUG - it logs to the logger, but
   conditionally based on -debug-only flag and is omitted in release builds

All logging functions use formatv-style format strings now, e.g:
  log("Could not resolve URI {0}: {1}", URI, Result.takeError());

Existing log sites have been split between elog/log/vlog by best guess.

This includes a workaround for passing Error to formatv that can be
simplified when D49170 or similar lands.

Subscribers: ilya-biryukov, javed.absar, ioeric, MaskRay, jkorous, cfe-commits

Differential Revision: https://reviews.llvm.org/D49008

llvm-svn: 336785
diff --git a/clang-tools-extra/clangd/JSONRPCDispatcher.cpp b/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
index f81af3d..d273577 100644
--- a/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
+++ b/clang-tools-extra/clangd/JSONRPCDispatcher.cpp
@@ -14,6 +14,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Chrono.h"
 #include "llvm/Support/Errno.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/SourceMgr.h"
 #include <istream>
@@ -68,14 +69,18 @@
     Outs << "Content-Length: " << S.size() << "\r\n\r\n" << S;
     Outs.flush();
   }
-  log(llvm::Twine("--> ") + S + "\n");
+  vlog("--> {0}\n", S);
 }
 
-void JSONOutput::log(const Twine &Message) {
+void JSONOutput::log(Logger::Level Level,
+                     const llvm::formatv_object_base &Message) {
+  if (Level < MinLevel)
+    return;
   llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
   trace::log(Message);
   std::lock_guard<std::mutex> Guard(StreamMutex);
-  Logs << llvm::formatv("[{0:%H:%M:%S.%L}] {1}\n", Timestamp, Message);
+  Logs << llvm::formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level),
+                        Timestamp, Message);
   Logs.flush();
 }
 
@@ -90,7 +95,7 @@
 void clangd::reply(json::Value &&Result) {
   auto ID = Context::current().get(RequestID);
   if (!ID) {
-    log("Attempted to reply to a notification!");
+    elog("Attempted to reply to a notification!");
     return;
   }
   RequestSpan::attach([&](json::Object &Args) { Args["Reply"] = Result; });
@@ -104,7 +109,7 @@
 }
 
 void clangd::replyError(ErrorCode code, const llvm::StringRef &Message) {
-  log("Error " + Twine(static_cast<int>(code)) + ": " + Message);
+  elog("Error {0}: {1}", static_cast<int>(code), Message);
   RequestSpan::attach([&](json::Object &Args) {
     Args["Error"] = json::Object{{"code", static_cast<int>(code)},
                                  {"message", Message.str()}};
@@ -230,9 +235,9 @@
     // Content-Length is a mandatory header, and the only one we handle.
     if (LineRef.consume_front("Content-Length: ")) {
       if (ContentLength != 0) {
-        log("Warning: Duplicate Content-Length header received. "
-            "The previous value for this message (" +
-            llvm::Twine(ContentLength) + ") was ignored.");
+        elog("Warning: Duplicate Content-Length header received. "
+             "The previous value for this message ({0}) was ignored.",
+             ContentLength);
       }
       llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength);
       continue;
@@ -248,8 +253,9 @@
 
   // The fuzzer likes crashing us by sending "Content-Length: 9999999999999999"
   if (ContentLength > 1 << 30) { // 1024M
-    log("Refusing to read message with long Content-Length: " +
-        Twine(ContentLength) + ". Expect protocol errors.");
+    elog("Refusing to read message with long Content-Length: {0}. "
+         "Expect protocol errors",
+         ContentLength);
     return llvm::None;
   }
   if (ContentLength == 0) {
@@ -264,8 +270,8 @@
                                        ContentLength - Pos, In);
     Out.mirrorInput(StringRef(&JSON[Pos], Read));
     if (Read == 0) {
-      log("Input was aborted. Read only " + llvm::Twine(Pos) +
-          " bytes of expected " + llvm::Twine(ContentLength) + ".");
+      elog("Input was aborted. Read only {0} bytes of expected {1}.", Pos,
+           ContentLength);
       return llvm::None;
     }
     clearerr(In); // If we're done, the error was transient. If we're not done,
@@ -297,7 +303,7 @@
   }
 
   if (ferror(In)) {
-    log("Input error while reading message!");
+    elog("Input error while reading message!");
     return llvm::None;
   } else { // Including EOF
     Out.mirrorInput(
@@ -321,21 +327,20 @@
       (InputStyle == Delimited) ? readDelimitedMessage : readStandardMessage;
   while (!IsDone && !feof(In)) {
     if (ferror(In)) {
-      log("IO error: " + llvm::sys::StrError());
+      elog("IO error: {0}", llvm::sys::StrError());
       return;
     }
     if (auto JSON = ReadMessage(In, Out)) {
       if (auto Doc = json::parse(*JSON)) {
         // Log the formatted message.
-        log(llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));
+        vlog(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc);
         // Finally, execute the action for this JSON message.
         if (!Dispatcher.call(*Doc, Out))
-          log("JSON dispatch failed!");
+          elog("JSON dispatch failed!");
       } else {
         // Parse error. Log the raw message.
-        log(llvm::formatv("<-- {0}\n" , *JSON));
-        log(llvm::Twine("JSON parse error: ") +
-            llvm::toString(Doc.takeError()));
+        vlog("<-- {0}\n", *JSON);
+        elog("JSON parse error: {0}", llvm::toString(Doc.takeError()));
       }
     }
   }