Provide a default implementation of QUICHE logging.

PiperOrigin-RevId: 355477784
Change-Id: I82cbe99757761a5c2e4bca71ad44fbe1567c7005
diff --git a/common/platform/api/quiche_logging.h b/common/platform/api/quiche_logging.h
index 6a3e43c..e3278eb 100644
--- a/common/platform/api/quiche_logging.h
+++ b/common/platform/api/quiche_logging.h
@@ -5,7 +5,7 @@
 #ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_LOGGING_H_
 #define QUICHE_COMMON_PLATFORM_API_QUICHE_LOGGING_H_
 
-#include "net/quiche/common/platform/impl/quiche_logging_impl.h"
+#include "quiche_platform_impl/quiche_logging_impl.h"
 
 // Please note following QUICHE_LOG are platform dependent:
 // INFO severity can be degraded (to VLOG(1) or DVLOG(1)).
diff --git a/common/platform/default/quiche_platform_impl/quiche_logging_impl.h b/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
new file mode 100644
index 0000000..4b414e7
--- /dev/null
+++ b/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
@@ -0,0 +1,122 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file does not actually implement logging, it merely provides enough of
+// logging code for QUICHE to compile.  QUICHE embedders are encouraged to
+// override this file with their own logic.  If at some point logging becomes a
+// part of Abseil, this file will likely start using that instead.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
+
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "absl/base/attributes.h"
+
+namespace quiche {
+
+// NoopLogSink provides a log sink that does not put the data that it logs
+// anywhere.
+class NoopLogSink {
+ public:
+  NoopLogSink() {}
+
+  template <typename T>
+  constexpr NoopLogSink(const T&) {}
+
+  template <typename T1, typename T2>
+  constexpr NoopLogSink(const T1&, const T2&) {}
+
+  constexpr std::ostream& stream() { return stream_; }
+
+  // This operator has lower precedence than << but higher than ?:, which is
+  // useful for implementing QUICHE_DISREGARD_LOG_STREAM below.
+  void operator&(std::ostream&) {}
+
+ private:
+  std::stringstream stream_;
+};
+
+// We need to actually implement LOG(FATAL), otherwise some functions will fail
+// to compile due to the "failed to return value from non-void function" error.
+class FatalLogSink : public NoopLogSink {
+ public:
+  ABSL_ATTRIBUTE_NORETURN ~FatalLogSink() { abort(); }
+};
+
+}  // namespace quiche
+
+#define QUICHE_DVLOG_IMPL(verbose_level) \
+  ::quiche::NoopLogSink(#verbose_level).stream()
+#define QUICHE_DVLOG_IF_IMPL(verbose_level, condition) \
+  ::quiche::NoopLogSink(#verbose_level, condition).stream()
+#define QUICHE_DLOG_IMPL(severity) ::quiche::NoopLogSink(#severity).stream()
+#define QUICHE_DLOG_IF_IMPL(severity, condition) \
+  ::quiche::NoopLogSink(#severity, condition).stream()
+#define QUICHE_VLOG_IMPL(verbose_level) \
+  ::quiche::NoopLogSink(#verbose_level).stream()
+#define QUICHE_LOG_FIRST_N_IMPL(severity, n) \
+  ::quiche::NoopLogSink(#severity, n).stream()
+#define QUICHE_LOG_EVERY_N_SEC_IMPL(severity, seconds) \
+  ::quiche::NoopLogSink(#severity, seconds).stream()
+#define QUICHE_LOG_IF_IMPL(severity, condition) \
+  ::quiche::NoopLogSink(#severity, condition).stream()
+
+#define QUICHE_LOG_IMPL(severity) QUICHE_LOG_IMPL_##severity()
+#define QUICHE_LOG_IMPL_FATAL() ::quiche::FatalLogSink().stream()
+#define QUICHE_LOG_IMPL_DFATAL() ::quiche::NoopLogSink().stream()
+#define QUICHE_LOG_IMPL_ERROR() ::quiche::NoopLogSink().stream()
+#define QUICHE_LOG_IMPL_WARNING() ::quiche::NoopLogSink().stream()
+#define QUICHE_LOG_IMPL_INFO() ::quiche::NoopLogSink().stream()
+
+#define QUICHE_PREDICT_FALSE_IMPL(x) (x)
+#define QUICHE_PREDICT_TRUE_IMPL(x) (x)
+
+#define QUICHE_PLOG_IMPL(severity) ::quiche::NoopLogSink(#severity)
+
+#define QUICHE_DLOG_INFO_IS_ON_IMPL() false
+#define QUICHE_LOG_INFO_IS_ON_IMPL() false
+#define QUICHE_LOG_WARNING_IS_ON_IMPL() false
+#define QUICHE_LOG_ERROR_IS_ON_IMPL() false
+
+// This is necessary because we sometimes call QUICHE_DCHECK inside constexpr
+// functions, and then write non-constexpr expressions into the resulting log.
+#define QUICHE_DISREGARD_LOG_STREAM(stream) \
+  true ? (void)0 : ::quiche::NoopLogSink() & (stream)
+
+#define QUICHE_CHECK_IMPL(condition) ::quiche::NoopLogSink(condition).stream()
+#define QUICHE_CHECK_EQ_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_CHECK_NE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_CHECK_LE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_CHECK_LT_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_CHECK_GE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_CHECK_GT_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+
+#define QUICHE_DCHECK_IMPL(condition) \
+  QUICHE_DISREGARD_LOG_STREAM(::quiche::NoopLogSink(condition).stream())
+#define QUICHE_DCHECK_EQ_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_DCHECK_NE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_DCHECK_LE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_DCHECK_LT_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_DCHECK_GE_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+#define QUICHE_DCHECK_GT_IMPL(val1, val2) \
+  ::quiche::NoopLogSink(val1, val2).stream()
+
+#define QUICHE_NOTREACHED_IMPL() QUICHE_DCHECK_IMPL(false)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_