Relocate QUICHE files into quiche/ directory within the quiche repo, and change the relative include paths accordingly.

PiperOrigin-RevId: 440164720
Change-Id: I64d8a975d08888a3a86f6c51908e63d5cd45fa35
diff --git a/quiche/common/platform/api/quiche_bug_tracker.h b/quiche/common/platform/api/quiche_bug_tracker.h
new file mode 100644
index 0000000..27ac0d2
--- /dev/null
+++ b/quiche/common/platform/api/quiche_bug_tracker.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2016 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_BUG_TRACKER_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_BUG_TRACKER_H_
+
+#include "quiche_platform_impl/quiche_bug_tracker_impl.h"
+
+#define QUICHE_BUG QUICHE_BUG_IMPL
+#define QUICHE_BUG_IF QUICHE_BUG_IF_IMPL
+#define QUICHE_PEER_BUG QUICHE_PEER_BUG_IMPL
+#define QUICHE_PEER_BUG_IF QUICHE_PEER_BUG_IF_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_BUG_TRACKER_H_
diff --git a/quiche/common/platform/api/quiche_client_stats.h b/quiche/common/platform/api/quiche_client_stats.h
new file mode 100644
index 0000000..5b1b08c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_client_stats.h
@@ -0,0 +1,88 @@
+// Copyright 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_CLIENT_STATS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_CLIENT_STATS_H_
+
+#include <string>
+
+#include "quiche_platform_impl/quiche_client_stats_impl.h"
+
+namespace quiche {
+
+//------------------------------------------------------------------------------
+// Enumeration histograms.
+//
+// Sample usage:
+//   // In Chrome, these values are persisted to logs. Entries should not be
+//   // renumbered and numeric values should never be reused.
+//   enum class MyEnum {
+//     FIRST_VALUE = 0,
+//     SECOND_VALUE = 1,
+//     ...
+//     FINAL_VALUE = N,
+//     COUNT
+//   };
+//   QUICHE_CLIENT_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
+//   MyEnum::COUNT, "Number of time $foo equals to some enum value");
+//
+// Note: The value in |sample| must be strictly less than |enum_size|.
+
+#define QUICHE_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
+  QUICHE_CLIENT_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring)
+
+//------------------------------------------------------------------------------
+// Histogram for boolean values.
+
+// Sample usage:
+//   QUICHE_CLIENT_HISTOGRAM_BOOL("My.Boolean", bool,
+//   "Number of times $foo is true or false");
+#define QUICHE_CLIENT_HISTOGRAM_BOOL(name, sample, docstring) \
+  QUICHE_CLIENT_HISTOGRAM_BOOL_IMPL(name, sample, docstring)
+
+//------------------------------------------------------------------------------
+// Timing histograms. These are used for collecting timing data (generally
+// latencies).
+
+// These macros create exponentially sized histograms (lengths of the bucket
+// ranges exponentially increase as the sample range increases). The units for
+// sample and max are unspecified, but they must be the same for one histogram.
+
+// Sample usage:
+//   QUICHE_CLIENT_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
+//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
+//       24), 100, "Time spent in doing operation.");
+#define QUICHE_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
+                                      docstring)                            \
+  QUICHE_CLIENT_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count,  \
+                                     docstring)
+
+//------------------------------------------------------------------------------
+// Count histograms. These are used for collecting numeric data.
+
+// These macros default to exponential histograms - i.e. the lengths of the
+// bucket ranges exponentially increase as the sample range increases.
+
+// All of these macros must be called with |name| as a runtime constant.
+
+// Any data outside the range here will be put in underflow and overflow
+// buckets. Min values should be >=1 as emitted 0s will still go into the
+// underflow bucket.
+
+// Sample usage:
+//   UMA_CLIENT_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100,
+//      "Counters of hitting certain code.");
+
+#define QUICHE_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
+                                       docstring)                            \
+  QUICHE_CLIENT_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count,  \
+                                      docstring)
+
+inline void QuicheClientSparseHistogram(const std::string& name, int sample) {
+  QuicheClientSparseHistogramImpl(name, sample);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_CLIENT_STATS_H_
diff --git a/quiche/common/platform/api/quiche_command_line_flags.h b/quiche/common/platform/api/quiche_command_line_flags.h
new file mode 100644
index 0000000..783dea6
--- /dev/null
+++ b/quiche/common/platform/api/quiche_command_line_flags.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_COMMAND_LINE_FLAGS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_COMMAND_LINE_FLAGS_H_
+
+#include <string>
+#include <vector>
+
+#include "quiche_platform_impl/quiche_command_line_flags_impl.h"
+
+// Define a command-line flag that can be automatically set via
+// QuicheParseCommandLineFlags().
+#define DEFINE_QUICHE_COMMAND_LINE_FLAG(type, name, default_value, help) \
+  DEFINE_QUICHE_COMMAND_LINE_FLAG_IMPL(type, name, default_value, help)
+
+namespace quiche {
+
+// Parses command-line flags, setting flag variables defined using
+// DEFINE_QUICHE_COMMAND_LINE_FLAG if they appear in the command line, and
+// returning a list of any non-flag arguments specified in the command line. If
+// the command line specifies '-h' or '--help', prints a usage message with flag
+// descriptions to stdout and exits with status 0. If a flag has an unparsable
+// value, writes an error message to stderr and exits with status 1.
+inline std::vector<std::string> QuicheParseCommandLineFlags(
+    const char* usage, int argc, const char* const* argv) {
+  return QuicheParseCommandLineFlagsImpl(usage, argc, argv);
+}
+
+// Prints a usage message with flag descriptions to stdout.
+inline void QuichePrintCommandLineFlagHelp(const char* usage) {
+  QuichePrintCommandLineFlagHelpImpl(usage);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_COMMAND_LINE_FLAGS_H_
diff --git a/quiche/common/platform/api/quiche_containers.h b/quiche/common/platform/api/quiche_containers.h
new file mode 100644
index 0000000..b3b929a
--- /dev/null
+++ b/quiche/common/platform/api/quiche_containers.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_CONTAINERS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_CONTAINERS_H_
+
+#include "quiche_platform_impl/quiche_containers_impl.h"
+
+namespace quiche {
+
+// An ordered container optimized for small sets.
+// An implementation with O(n) mutations might be chosen
+// in case it has better memory usage and/or faster access.
+//
+// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
+template <typename Key, typename Compare = std::less<Key>>
+using QuicheSmallOrderedSet = QuicheSmallOrderedSetImpl<Key, Compare>;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_CONTAINERS_H_
diff --git a/quiche/common/platform/api/quiche_default_proof_providers.h b/quiche/common/platform/api/quiche_default_proof_providers.h
new file mode 100644
index 0000000..9d5522e
--- /dev/null
+++ b/quiche/common/platform/api/quiche_default_proof_providers.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
+
+#include <memory>
+
+#include "quiche_platform_impl/quiche_default_proof_providers_impl.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+
+namespace quiche {
+
+// Provides a default proof verifier that can verify a cert chain for |host|.
+// The verifier has to do a good faith attempt at verifying the certificate
+// against a reasonable root store, and not just always return success.
+inline std::unique_ptr<quic::ProofVerifier> CreateDefaultProofVerifier(
+    const std::string& host) {
+  return CreateDefaultProofVerifierImpl(host);
+}
+
+// Provides a default proof source for CLI-based tools.  The actual certificates
+// used in the proof source should be confifgurable via command-line flags.
+inline std::unique_ptr<quic::ProofSource> CreateDefaultProofSource() {
+  return CreateDefaultProofSourceImpl();
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/quiche/common/platform/api/quiche_epoll.h b/quiche/common/platform/api/quiche_epoll.h
new file mode 100644
index 0000000..5fd470c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_epoll.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_H_
+
+#include "quiche_platform_impl/quiche_epoll_impl.h"
+
+namespace quiche {
+
+using QuicheEpollServer = QuicheEpollServerImpl;
+using QuicheEpollEvent = QuicheEpollEventImpl;
+using QuicheEpollAlarmBase = QuicheEpollAlarmBaseImpl;
+using QuicheEpollCallbackInterface = QuicheEpollCallbackInterfaceImpl;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_H_
diff --git a/quiche/common/platform/api/quiche_epoll_test_tools.h b/quiche/common/platform/api/quiche_epoll_test_tools.h
new file mode 100644
index 0000000..998ed83
--- /dev/null
+++ b/quiche/common/platform/api/quiche_epoll_test_tools.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_TEST_TOOLS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_TEST_TOOLS_H_
+
+#include "quiche_platform_impl/quiche_epoll_test_tools_impl.h"
+
+namespace quiche {
+
+using QuicheFakeEpollServer = QuicheFakeEpollServerImpl;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_EPOLL_TEST_TOOLS_H_
diff --git a/quiche/common/platform/api/quiche_expect_bug.h b/quiche/common/platform/api/quiche_expect_bug.h
new file mode 100644
index 0000000..02ba8d1
--- /dev/null
+++ b/quiche/common/platform/api/quiche_expect_bug.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_EXPECT_BUG_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_EXPECT_BUG_H_
+
+#include "quiche_platform_impl/quiche_expect_bug_impl.h"
+
+#define EXPECT_QUICHE_BUG EXPECT_QUICHE_BUG_IMPL
+#define EXPECT_QUICHE_PEER_BUG(statement, regex) \
+  EXPECT_QUICHE_PEER_BUG_IMPL(statement, regex)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_EXPECT_BUG_H_
diff --git a/quiche/common/platform/api/quiche_export.h b/quiche/common/platform/api/quiche_export.h
new file mode 100644
index 0000000..4f64819
--- /dev/null
+++ b/quiche/common/platform/api/quiche_export.h
@@ -0,0 +1,21 @@
+// Copyright 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_EXPORT_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_EXPORT_H_
+
+#include "quiche_platform_impl/quiche_export_impl.h"
+
+// QUICHE_EXPORT is not meant to be used.
+#define QUICHE_EXPORT QUICHE_EXPORT_IMPL
+
+// QUICHE_EXPORT_PRIVATE is meant for QUICHE functionality that is built in
+// Chromium as part of //net, and not fully contained in headers.
+#define QUICHE_EXPORT_PRIVATE QUICHE_EXPORT_PRIVATE_IMPL
+
+// QUICHE_NO_EXPORT is meant for QUICHE functionality that is either fully
+// defined in a header, or is built in Chromium as part of tests or tools.
+#define QUICHE_NO_EXPORT QUICHE_NO_EXPORT_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_EXPORT_H_
diff --git a/quiche/common/platform/api/quiche_file_utils.cc b/quiche/common/platform/api/quiche_file_utils.cc
new file mode 100644
index 0000000..6453ea2
--- /dev/null
+++ b/quiche/common/platform/api/quiche_file_utils.cc
@@ -0,0 +1,51 @@
+#include "quiche/common/platform/api/quiche_file_utils.h"
+
+#include "quiche_platform_impl/quiche_file_utils_impl.h"
+
+namespace quiche {
+
+std::string JoinPath(absl::string_view a, absl::string_view b) {
+  return JoinPathImpl(a, b);
+}
+
+absl::optional<std::string> ReadFileContents(absl::string_view file) {
+  return ReadFileContentsImpl(file);
+}
+
+bool EnumerateDirectory(absl::string_view path,
+                        std::vector<std::string>& directories,
+                        std::vector<std::string>& files) {
+  return EnumerateDirectoryImpl(path, directories, files);
+}
+
+bool EnumerateDirectoryRecursivelyInner(absl::string_view path,
+                                        int recursion_limit,
+                                        std::vector<std::string>& files) {
+  if (recursion_limit < 0) {
+    return false;
+  }
+
+  std::vector<std::string> local_files;
+  std::vector<std::string> directories;
+  if (!EnumerateDirectory(path, directories, local_files)) {
+    return false;
+  }
+  for (const std::string& directory : directories) {
+    if (!EnumerateDirectoryRecursivelyInner(JoinPath(path, directory),
+                                            recursion_limit - 1, files)) {
+      return false;
+    }
+  }
+  for (const std::string& file : local_files) {
+    files.push_back(JoinPath(path, file));
+  }
+  return true;
+}
+
+bool EnumerateDirectoryRecursively(absl::string_view path,
+                                   std::vector<std::string>& files) {
+  constexpr int kRecursionLimit = 20;
+  return EnumerateDirectoryRecursivelyInner(path, kRecursionLimit, files);
+}
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_file_utils.h b/quiche/common/platform/api/quiche_file_utils.h
new file mode 100644
index 0000000..47723d1
--- /dev/null
+++ b/quiche/common/platform/api/quiche_file_utils.h
@@ -0,0 +1,40 @@
+// 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 header contains basic filesystem functions for use in unit tests and CLI
+// tools.  Note that those are not 100% suitable for production use, as in, they
+// might be prone to race conditions and not always handle non-ASCII filenames
+// correctly.
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_FILE_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_FILE_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+
+namespace quiche {
+
+// Join two paths in a platform-specific way.  Returns |a| if |b| is empty, and
+// vice versa.
+std::string JoinPath(absl::string_view a, absl::string_view b);
+
+// Reads the entire file into the memory.
+absl::optional<std::string> ReadFileContents(absl::string_view file);
+
+// Lists all files and directories in the directory specified by |path|. Returns
+// true on success, false on failure.
+bool EnumerateDirectory(absl::string_view path,
+                        std::vector<std::string>& directories,
+                        std::vector<std::string>& files);
+
+// Recursively enumerates all of the files in the directory and all of the
+// internal subdirectories.  Has a fairly small recursion limit.
+bool EnumerateDirectoryRecursively(absl::string_view path,
+                                   std::vector<std::string>& files);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_FILE_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_file_utils_test.cc b/quiche/common/platform/api/quiche_file_utils_test.cc
new file mode 100644
index 0000000..68387a4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_file_utils_test.cc
@@ -0,0 +1,86 @@
+#include "quiche/common/platform/api/quiche_file_utils.h"
+
+#include <vector>
+
+#include "absl/algorithm/container.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/strip.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+using testing::UnorderedElementsAre;
+using testing::UnorderedElementsAreArray;
+
+TEST(QuicheFileUtilsTest, ReadFileContents) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/testfile");
+  absl::optional<std::string> contents = ReadFileContents(path);
+  ASSERT_TRUE(contents.has_value());
+  EXPECT_EQ(*contents, "This is a test file.");
+}
+
+TEST(QuicheFileUtilsTest, ReadFileContentsFileNotFound) {
+  std::string path =
+      absl::StrCat(QuicheGetCommonSourcePath(),
+                   "/platform/api/testdir/file-that-does-not-exist");
+  absl::optional<std::string> contents = ReadFileContents(path);
+  EXPECT_FALSE(contents.has_value());
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectory) {
+  std::string path =
+      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_TRUE(success);
+  EXPECT_THAT(files, UnorderedElementsAre("testfile", "README.md"));
+  EXPECT_THAT(dirs, UnorderedElementsAre("a"));
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryNoSuchDirectory) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/no-such-directory");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_FALSE(success);
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryNotADirectory) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/testfile");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_FALSE(success);
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryRecursively) {
+  std::vector<std::string> expected_paths = {"a/b/c/d/e", "a/subdir/testfile",
+                                             "a/z", "testfile", "README.md"};
+
+  std::string root_path =
+      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
+  for (std::string& path : expected_paths) {
+    // For Windows, use Windows path separators.
+    if (JoinPath("a", "b") == "a\\b") {
+      absl::c_replace(path, '/', '\\');
+    }
+
+    path = JoinPath(root_path, path);
+  }
+
+  std::vector<std::string> files;
+  bool success = EnumerateDirectoryRecursively(root_path, files);
+  EXPECT_TRUE(success);
+  EXPECT_THAT(files, UnorderedElementsAreArray(expected_paths));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_flag_utils.h b/quiche/common/platform/api/quiche_flag_utils.h
new file mode 100644
index 0000000..fcd6623
--- /dev/null
+++ b/quiche/common/platform/api/quiche_flag_utils.h
@@ -0,0 +1,19 @@
+// Copyright 2020 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_FLAG_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_FLAG_UTILS_H_
+
+#include "quiche_platform_impl/quiche_flag_utils_impl.h"
+
+#define QUICHE_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT_IMPL
+#define QUICHE_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N_IMPL
+
+#define QUICHE_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT_IMPL
+#define QUICHE_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N_IMPL
+
+#define QUICHE_CODE_COUNT QUICHE_CODE_COUNT_IMPL
+#define QUICHE_CODE_COUNT_N QUICHE_CODE_COUNT_N_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_FLAG_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_flags.h b/quiche/common/platform/api/quiche_flags.h
new file mode 100644
index 0000000..8b26edb
--- /dev/null
+++ b/quiche/common/platform/api/quiche_flags.h
@@ -0,0 +1,21 @@
+// Copyright 2020 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_FLAGS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_FLAGS_H_
+
+#include "quiche_platform_impl/quiche_flags_impl.h"
+
+#define GetQuicheReloadableFlag(module, flag) \
+  GetQuicheReloadableFlagImpl(module, flag)
+#define SetQuicheReloadableFlag(module, flag, value) \
+  SetQuicheReloadableFlagImpl(module, flag, value)
+#define GetQuicheRestartFlag(module, flag) \
+  GetQuicheRestartFlagImpl(module, flag)
+#define SetQuicheRestartFlag(module, flag, value) \
+  SetQuicheRestartFlagImpl(module, flag, value)
+#define GetQuicheFlag(flag) GetQuicheFlagImpl(flag)
+#define SetQuicheFlag(flag, value) SetQuicheFlagImpl(flag, value)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_FLAGS_H_
diff --git a/quiche/common/platform/api/quiche_hostname_utils.cc b/quiche/common/platform/api/quiche_hostname_utils.cc
new file mode 100644
index 0000000..19ac83e
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2017 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.
+
+#include "quiche/common/platform/api/quiche_hostname_utils.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "url/url_canon.h"
+#include "url/url_canon_stdstring.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+// TODO(vasilvv): the functions below are forked from Chromium's
+// net/base/url_util.h; those should be moved to googleurl.
+namespace {
+
+std::string CanonicalizeHost(absl::string_view host,
+                             url::CanonHostInfo* host_info) {
+  // Try to canonicalize the host.
+  const url::Component raw_host_component(0, static_cast<int>(host.length()));
+  std::string canon_host;
+  url::StdStringCanonOutput canon_host_output(&canon_host);
+  url::CanonicalizeHostVerbose(host.data(), raw_host_component,
+                               &canon_host_output, host_info);
+
+  if (host_info->out_host.is_nonempty() &&
+      host_info->family != url::CanonHostInfo::BROKEN) {
+    // Success!  Assert that there's no extra garbage.
+    canon_host_output.Complete();
+    QUICHE_DCHECK_EQ(host_info->out_host.len,
+                     static_cast<int>(canon_host.length()));
+  } else {
+    // Empty host, or canonicalization failed.  We'll return empty.
+    canon_host.clear();
+  }
+
+  return canon_host;
+}
+
+bool IsHostCharAlphanumeric(char c) {
+  // We can just check lowercase because uppercase characters have already been
+  // normalized.
+  return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
+}
+
+bool IsCanonicalizedHostCompliant(const std::string& host) {
+  if (host.empty()) {
+    return false;
+  }
+
+  bool in_component = false;
+  bool most_recent_component_started_alphanumeric = false;
+
+  for (char c : host) {
+    if (!in_component) {
+      most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c);
+      if (!most_recent_component_started_alphanumeric && (c != '-') &&
+          (c != '_')) {
+        return false;
+      }
+      in_component = true;
+    } else if (c == '.') {
+      in_component = false;
+    } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) {
+      return false;
+    }
+  }
+
+  return most_recent_component_started_alphanumeric;
+}
+
+}  // namespace
+
+// static
+bool QuicheHostnameUtils::IsValidSNI(absl::string_view sni) {
+  // TODO(rtenneti): Support RFC2396 hostname.
+  // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames
+  // based on the above spec, we may be losing some hostnames that windows
+  // would consider valid. By far the most common hostname character NOT
+  // accepted by the above spec is '_'.
+  url::CanonHostInfo host_info;
+  std::string canonicalized_host = CanonicalizeHost(sni, &host_info);
+  return !host_info.IsIPAddress() &&
+         IsCanonicalizedHostCompliant(canonicalized_host);
+}
+
+// static
+std::string QuicheHostnameUtils::NormalizeHostname(absl::string_view hostname) {
+  url::CanonHostInfo host_info;
+  std::string host = CanonicalizeHost(hostname, &host_info);
+
+  // Walk backwards over the string, stopping at the first trailing dot.
+  size_t host_end = host.length();
+  while (host_end != 0 && host[host_end - 1] == '.') {
+    host_end--;
+  }
+
+  // Erase the trailing dots.
+  if (host_end != host.length()) {
+    host.erase(host_end, host.length() - host_end);
+  }
+
+  return host;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_hostname_utils.h b/quiche/common/platform/api/quiche_hostname_utils.h
new file mode 100644
index 0000000..00c611f
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheHostnameUtils {
+ public:
+  QuicheHostnameUtils() = delete;
+
+  // Returns true if the sni is valid, false otherwise.
+  //  (1) disallow IP addresses;
+  //  (2) check that the hostname contains valid characters only; and
+  //  (3) contains at least one dot.
+  static bool IsValidSNI(absl::string_view sni);
+
+  // Canonicalizes the specified hostname.  This involves a wide variety of
+  // transformations, including lowercasing, removing trailing dots and IDNA
+  // conversion.
+  static std::string NormalizeHostname(absl::string_view hostname);
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_hostname_utils_test.cc b/quiche/common/platform/api/quiche_hostname_utils_test.cc
new file mode 100644
index 0000000..5d52c4f
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils_test.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2017 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.
+
+#include "quiche/common/platform/api/quiche_hostname_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class QuicheHostnameUtilsTest : public QuicheTest {};
+
+TEST_F(QuicheHostnameUtilsTest, IsValidSNI) {
+  // IP as SNI.
+  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI("192.168.0.1"));
+  // SNI without any dot.
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("somedomain"));
+  // Invalid by RFC2396 but unfortunately domains of this form exist.
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("some_domain.com"));
+  // An empty string must be invalid otherwise the QUIC client will try sending
+  // it.
+  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI(""));
+
+  // Valid SNI
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("test.google.com"));
+}
+
+TEST_F(QuicheHostnameUtilsTest, NormalizeHostname) {
+  // clang-format off
+  struct {
+    const char *input, *expected;
+  } tests[] = {
+      {
+          "www.google.com",
+          "www.google.com",
+      },
+      {
+          "WWW.GOOGLE.COM",
+          "www.google.com",
+      },
+      {
+          "www.google.com.",
+          "www.google.com",
+      },
+      {
+          "www.google.COM.",
+          "www.google.com",
+      },
+      {
+          "www.google.com..",
+          "www.google.com",
+      },
+      {
+          "www.google.com........",
+          "www.google.com",
+      },
+      {
+          "",
+          "",
+      },
+      {
+          ".",
+          "",
+      },
+      {
+          "........",
+          "",
+      },
+      {
+          "\xe5\x85\x89.google.com",
+          "xn--54q.google.com",
+      },
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); ++i) {
+    EXPECT_EQ(std::string(tests[i].expected),
+              QuicheHostnameUtils::NormalizeHostname(tests[i].input));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_iovec.h b/quiche/common/platform/api/quiche_iovec.h
new file mode 100644
index 0000000..351e627
--- /dev/null
+++ b/quiche/common/platform/api/quiche_iovec.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_IOVEC_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_IOVEC_H_
+
+#include <cstddef>
+#include <type_traits>
+
+#include "quiche_platform_impl/quiche_iovec_impl.h"
+
+// The impl header has to export struct iovec, or a POSIX-compatible polyfill.
+// Below, we mostly assert that what we have is appropriate.
+static_assert(std::is_standard_layout<struct iovec>::value,
+              "iovec has to be a standard-layout struct");
+
+static_assert(offsetof(struct iovec, iov_base) < sizeof(struct iovec),
+              "iovec has to have iov_base");
+static_assert(offsetof(struct iovec, iov_len) < sizeof(struct iovec),
+              "iovec has to have iov_len");
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_IOVEC_H_
diff --git a/quiche/common/platform/api/quiche_logging.h b/quiche/common/platform/api/quiche_logging.h
new file mode 100644
index 0000000..940d492
--- /dev/null
+++ b/quiche/common/platform/api/quiche_logging.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_LOGGING_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_LOGGING_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)).
+// Some platforms may not support QUICHE_LOG_FIRST_N or QUICHE_LOG_EVERY_N_SEC,
+// and they would simply be translated to LOG.
+
+#define QUICHE_DVLOG(verbose_level) QUICHE_DVLOG_IMPL(verbose_level)
+#define QUICHE_DVLOG_IF(verbose_level, condition) \
+  QUICHE_DVLOG_IF_IMPL(verbose_level, condition)
+#define QUICHE_DLOG(severity) QUICHE_DLOG_IMPL(severity)
+#define QUICHE_DLOG_IF(severity, condition) \
+  QUICHE_DLOG_IF_IMPL(severity, condition)
+#define QUICHE_VLOG(verbose_level) QUICHE_VLOG_IMPL(verbose_level)
+#define QUICHE_LOG(severity) QUICHE_LOG_IMPL(severity)
+#define QUICHE_LOG_FIRST_N(severity, n) QUICHE_LOG_FIRST_N_IMPL(severity, n)
+#define QUICHE_LOG_EVERY_N_SEC(severity, seconds) \
+  QUICHE_LOG_EVERY_N_SEC_IMPL(severity, seconds)
+#define QUICHE_LOG_IF(severity, condition) \
+  QUICHE_LOG_IF_IMPL(severity, condition)
+
+#define QUICHE_PREDICT_FALSE(x) QUICHE_PREDICT_FALSE_IMPL(x)
+#define QUICHE_PREDICT_TRUE(x) QUICHE_PREDICT_TRUE_IMPL(x)
+
+// This is a noop in release build.
+#define QUICHE_NOTREACHED() QUICHE_NOTREACHED_IMPL()
+
+#define QUICHE_PLOG(severity) QUICHE_PLOG_IMPL(severity)
+
+#define QUICHE_DLOG_INFO_IS_ON() QUICHE_DLOG_INFO_IS_ON_IMPL()
+#define QUICHE_LOG_INFO_IS_ON() QUICHE_LOG_INFO_IS_ON_IMPL()
+#define QUICHE_LOG_WARNING_IS_ON() QUICHE_LOG_WARNING_IS_ON_IMPL()
+#define QUICHE_LOG_ERROR_IS_ON() QUICHE_LOG_ERROR_IS_ON_IMPL()
+
+#define QUICHE_CHECK(condition) QUICHE_CHECK_IMPL(condition)
+#define QUICHE_CHECK_OK(condition) QUICHE_CHECK_OK_IMPL(condition)
+#define QUICHE_CHECK_EQ(val1, val2) QUICHE_CHECK_EQ_IMPL(val1, val2)
+#define QUICHE_CHECK_NE(val1, val2) QUICHE_CHECK_NE_IMPL(val1, val2)
+#define QUICHE_CHECK_LE(val1, val2) QUICHE_CHECK_LE_IMPL(val1, val2)
+#define QUICHE_CHECK_LT(val1, val2) QUICHE_CHECK_LT_IMPL(val1, val2)
+#define QUICHE_CHECK_GE(val1, val2) QUICHE_CHECK_GE_IMPL(val1, val2)
+#define QUICHE_CHECK_GT(val1, val2) QUICHE_CHECK_GT_IMPL(val1, val2)
+
+#define QUICHE_DCHECK(condition) QUICHE_DCHECK_IMPL(condition)
+#define QUICHE_DCHECK_EQ(val1, val2) QUICHE_DCHECK_EQ_IMPL(val1, val2)
+#define QUICHE_DCHECK_NE(val1, val2) QUICHE_DCHECK_NE_IMPL(val1, val2)
+#define QUICHE_DCHECK_LE(val1, val2) QUICHE_DCHECK_LE_IMPL(val1, val2)
+#define QUICHE_DCHECK_LT(val1, val2) QUICHE_DCHECK_LT_IMPL(val1, val2)
+#define QUICHE_DCHECK_GE(val1, val2) QUICHE_DCHECK_GE_IMPL(val1, val2)
+#define QUICHE_DCHECK_GT(val1, val2) QUICHE_DCHECK_GT_IMPL(val1, val2)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_LOGGING_H_
diff --git a/quiche/common/platform/api/quiche_lower_case_string.h b/quiche/common/platform/api/quiche_lower_case_string.h
new file mode 100644
index 0000000..dcaef3c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_lower_case_string.h
@@ -0,0 +1,16 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_LOWER_CASE_STRING_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_LOWER_CASE_STRING_H_
+
+#include "quiche_platform_impl/quiche_lower_case_string_impl.h"
+
+namespace quiche {
+
+using QuicheLowerCaseString = QuicheLowerCaseStringImpl;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_LOWER_CASE_STRING_H_
diff --git a/quiche/common/platform/api/quiche_mem_slice.h b/quiche/common/platform/api/quiche_mem_slice.h
new file mode 100644
index 0000000..bb703a4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mem_slice.h
@@ -0,0 +1,71 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
+
+#include <memory>
+
+#include "quiche_platform_impl/quiche_mem_slice_impl.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quiche {
+
+// QuicheMemSlice is a wrapper around a platform-specific I/O buffer type. It
+// may be reference counted, though QUICHE itself does not rely on that.
+class QUICHE_EXPORT_PRIVATE QuicheMemSlice {
+ public:
+  // Constructs a empty QuicheMemSlice with no underlying data.
+  QuicheMemSlice() = default;
+
+  // Constructs a QuicheMemSlice that takes ownership of |buffer|.  The length
+  // of the |buffer| must not be zero.  To construct an empty QuicheMemSlice,
+  // use the zero-argument constructor instead.
+  explicit QuicheMemSlice(QuicheBuffer buffer) : impl_(std::move(buffer)) {}
+
+  // Constructs a QuicheMemSlice that takes ownership of |buffer| allocated on
+  // heap.  |length| must not be zero.
+  QuicheMemSlice(std::unique_ptr<char[]> buffer, size_t length)
+      : impl_(std::move(buffer), length) {}
+
+  // Constructs QuicheMemSlice from |impl|. It takes the reference away from
+  // |impl|.
+  explicit QuicheMemSlice(QuicheMemSliceImpl impl) : impl_(std::move(impl)) {}
+
+  QuicheMemSlice(const QuicheMemSlice& other) = delete;
+  QuicheMemSlice& operator=(const QuicheMemSlice& other) = delete;
+
+  // Move constructors. |other| will not hold a reference to the data buffer
+  // after this call completes.
+  QuicheMemSlice(QuicheMemSlice&& other) = default;
+  QuicheMemSlice& operator=(QuicheMemSlice&& other) = default;
+
+  ~QuicheMemSlice() = default;
+
+  // Release the underlying reference. Further access the memory will result in
+  // undefined behavior.
+  void Reset() { impl_.Reset(); }
+
+  // Returns a const char pointer to underlying data buffer.
+  const char* data() const { return impl_.data(); }
+  // Returns the length of underlying data buffer.
+  size_t length() const { return impl_.length(); }
+  // Returns the representation of the underlying data as a string view.
+  absl::string_view AsStringView() const {
+    return absl::string_view(data(), length());
+  }
+
+  bool empty() const { return impl_.empty(); }
+
+  QuicheMemSliceImpl* impl() { return &impl_; }
+
+ private:
+  QuicheMemSliceImpl impl_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
diff --git a/quiche/common/platform/api/quiche_mem_slice_test.cc b/quiche/common/platform/api/quiche_mem_slice_test.cc
new file mode 100644
index 0000000..472dbe1
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mem_slice_test.cc
@@ -0,0 +1,76 @@
+// Copyright 2017 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.
+
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class QuicheMemSliceTest : public QuicheTest {
+ public:
+  QuicheMemSliceTest() {
+    size_t length = 1024;
+    slice_ = QuicheMemSlice(QuicheBuffer(&allocator_, length));
+    orig_data_ = slice_.data();
+    orig_length_ = slice_.length();
+  }
+
+  SimpleBufferAllocator allocator_;
+  QuicheMemSlice slice_;
+  const char* orig_data_;
+  size_t orig_length_;
+};
+
+TEST_F(QuicheMemSliceTest, MoveConstruct) {
+  QuicheMemSlice moved(std::move(slice_));
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+  EXPECT_TRUE(slice_.empty());
+}
+
+TEST_F(QuicheMemSliceTest, MoveAssign) {
+  QuicheMemSlice moved;
+  moved = std::move(slice_);
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+  EXPECT_TRUE(slice_.empty());
+}
+
+TEST_F(QuicheMemSliceTest, SliceAllocatedOnHeap) {
+  auto buffer = std::make_unique<char[]>(128);
+  char* orig_data = buffer.get();
+  size_t used_length = 105;
+  QuicheMemSlice slice = QuicheMemSlice(std::move(buffer), used_length);
+  QuicheMemSlice moved = std::move(slice);
+  EXPECT_EQ(moved.data(), orig_data);
+  EXPECT_EQ(moved.length(), used_length);
+}
+
+TEST_F(QuicheMemSliceTest, SliceFromBuffer) {
+  const absl::string_view kTestString =
+      "RFC 9000 Release Celebration Memorial Test String";
+  auto buffer = QuicheBuffer::Copy(&allocator_, kTestString);
+  QuicheMemSlice slice(std::move(buffer));
+
+  EXPECT_EQ(buffer.data(), nullptr);  // NOLINT(bugprone-use-after-move)
+  EXPECT_EQ(buffer.size(), 0u);
+  EXPECT_EQ(slice.AsStringView(), kTestString);
+  EXPECT_EQ(slice.length(), kTestString.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_mock_log.h b/quiche/common/platform/api/quiche_mock_log.h
new file mode 100644
index 0000000..37f25de
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mock_log.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MOCK_LOG_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_MOCK_LOG_H_
+
+#include "quiche_platform_impl/quiche_mock_log_impl.h"
+
+using QuicheMockLog = QuicheMockLogImpl;
+#define CREATE_QUICHE_MOCK_LOG(log) CREATE_QUICHE_MOCK_LOG_IMPL(log)
+
+#define EXPECT_QUICHE_LOG_CALL(log) EXPECT_QUICHE_LOG_CALL_IMPL(log)
+
+#define EXPECT_QUICHE_LOG_CALL_CONTAINS(log, level, content) \
+  EXPECT_QUICHE_LOG_CALL_CONTAINS_IMPL(log, level, content)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_MOCK_LOG_H_
diff --git a/quiche/common/platform/api/quiche_mutex.cc b/quiche/common/platform/api/quiche_mutex.cc
new file mode 100644
index 0000000..e6d4b0c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mutex.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2016 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.
+
+#include "quiche/common/platform/api/quiche_mutex.h"
+
+namespace quiche {
+
+void QuicheMutex::WriterLock() { impl_.WriterLock(); }
+
+void QuicheMutex::WriterUnlock() { impl_.WriterUnlock(); }
+
+void QuicheMutex::ReaderLock() { impl_.ReaderLock(); }
+
+void QuicheMutex::ReaderUnlock() { impl_.ReaderUnlock(); }
+
+void QuicheMutex::AssertReaderHeld() const { impl_.AssertReaderHeld(); }
+
+QuicheReaderMutexLock::QuicheReaderMutexLock(QuicheMutex* lock) : lock_(lock) {
+  lock->ReaderLock();
+}
+
+QuicheReaderMutexLock::~QuicheReaderMutexLock() { lock_->ReaderUnlock(); }
+
+QuicheWriterMutexLock::QuicheWriterMutexLock(QuicheMutex* lock) : lock_(lock) {
+  lock->WriterLock();
+}
+
+QuicheWriterMutexLock::~QuicheWriterMutexLock() { lock_->WriterUnlock(); }
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_mutex.h b/quiche/common/platform/api/quiche_mutex.h
new file mode 100644
index 0000000..ce982bc
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mutex.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2016 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_
+
+#include "quiche_platform_impl/quiche_mutex_impl.h"
+
+#define QUICHE_EXCLUSIVE_LOCKS_REQUIRED QUICHE_EXCLUSIVE_LOCKS_REQUIRED_IMPL
+#define QUICHE_GUARDED_BY QUICHE_GUARDED_BY_IMPL
+#define QUICHE_LOCKABLE QUICHE_LOCKABLE_IMPL
+#define QUICHE_LOCKS_EXCLUDED QUICHE_LOCKS_EXCLUDED_IMPL
+#define QUICHE_SHARED_LOCKS_REQUIRED QUICHE_SHARED_LOCKS_REQUIRED_IMPL
+#define QUICHE_EXCLUSIVE_LOCK_FUNCTION QUICHE_EXCLUSIVE_LOCK_FUNCTION_IMPL
+#define QUICHE_UNLOCK_FUNCTION QUICHE_UNLOCK_FUNCTION_IMPL
+#define QUICHE_SHARED_LOCK_FUNCTION QUICHE_SHARED_LOCK_FUNCTION_IMPL
+#define QUICHE_SCOPED_LOCKABLE QUICHE_SCOPED_LOCKABLE_IMPL
+#define QUICHE_ASSERT_SHARED_LOCK QUICHE_ASSERT_SHARED_LOCK_IMPL
+
+namespace quiche {
+
+// A class representing a non-reentrant mutex in QUIC.
+class QUICHE_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheMutex {
+ public:
+  QuicheMutex() = default;
+  QuicheMutex(const QuicheMutex&) = delete;
+  QuicheMutex& operator=(const QuicheMutex&) = delete;
+
+  // Block until this Mutex is free, then acquire it exclusively.
+  void WriterLock() QUICHE_EXCLUSIVE_LOCK_FUNCTION();
+
+  // Release this Mutex. Caller must hold it exclusively.
+  void WriterUnlock() QUICHE_UNLOCK_FUNCTION();
+
+  // Block until this Mutex is free or shared, then acquire a share of it.
+  void ReaderLock() QUICHE_SHARED_LOCK_FUNCTION();
+
+  // Release this Mutex. Caller could hold it in shared mode.
+  void ReaderUnlock() QUICHE_UNLOCK_FUNCTION();
+
+  // Returns immediately if current thread holds the Mutex in at least shared
+  // mode.  Otherwise, may report an error (typically by crashing with a
+  // diagnostic), or may return immediately.
+  void AssertReaderHeld() const QUICHE_ASSERT_SHARED_LOCK();
+
+ private:
+  QuicheLockImpl impl_;
+};
+
+// A helper class that acquires the given QuicheMutex shared lock while the
+// QuicheReaderMutexLock is in scope.
+class QUICHE_SCOPED_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheReaderMutexLock {
+ public:
+  explicit QuicheReaderMutexLock(QuicheMutex* lock)
+      QUICHE_SHARED_LOCK_FUNCTION(lock);
+  QuicheReaderMutexLock(const QuicheReaderMutexLock&) = delete;
+  QuicheReaderMutexLock& operator=(const QuicheReaderMutexLock&) = delete;
+
+  ~QuicheReaderMutexLock() QUICHE_UNLOCK_FUNCTION();
+
+ private:
+  QuicheMutex* const lock_;
+};
+
+// A helper class that acquires the given QuicheMutex exclusive lock while the
+// QuicheWriterMutexLock is in scope.
+class QUICHE_SCOPED_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheWriterMutexLock {
+ public:
+  explicit QuicheWriterMutexLock(QuicheMutex* lock)
+      QUICHE_EXCLUSIVE_LOCK_FUNCTION(lock);
+  QuicheWriterMutexLock(const QuicheWriterMutexLock&) = delete;
+  QuicheWriterMutexLock& operator=(const QuicheWriterMutexLock&) = delete;
+
+  ~QuicheWriterMutexLock() QUICHE_UNLOCK_FUNCTION();
+
+ private:
+  QuicheMutex* const lock_;
+};
+
+// A Notification allows threads to receive notification of a single occurrence
+// of a single event.
+class QUICHE_EXPORT_PRIVATE QuicheNotification {
+ public:
+  QuicheNotification() = default;
+  QuicheNotification(const QuicheNotification&) = delete;
+  QuicheNotification& operator=(const QuicheNotification&) = delete;
+
+  bool HasBeenNotified() { return impl_.HasBeenNotified(); }
+
+  void Notify() { impl_.Notify(); }
+
+  void WaitForNotification() { impl_.WaitForNotification(); }
+
+ private:
+  QuicheNotificationImpl impl_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_
diff --git a/quiche/common/platform/api/quiche_prefetch.h b/quiche/common/platform/api/quiche_prefetch.h
new file mode 100644
index 0000000..706a709
--- /dev/null
+++ b/quiche/common/platform/api/quiche_prefetch.h
@@ -0,0 +1,39 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_PREFETCH_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_PREFETCH_H_
+
+#include "quiche_platform_impl/quiche_prefetch_impl.h"
+
+namespace quiche {
+
+// Move data into the cache before it is read, or "prefetch" it.
+//
+// The value of `addr` is the address of the memory to prefetch. If
+// the target and compiler support it, data prefetch instructions are
+// generated. If the prefetch is done some time before the memory is
+// read, it may be in the cache by the time the read occurs.
+//
+// The function names specify the temporal locality heuristic applied,
+// using the names of Intel prefetch instructions:
+//
+//   T0 - high degree of temporal locality; data should be left in as
+//        many levels of the cache possible
+//   T1 - moderate degree of temporal locality
+//   T2 - low degree of temporal locality
+//   Nta - no temporal locality, data need not be left in the cache
+//         after the read
+//
+// Incorrect or gratuitous use of these functions can degrade
+// performance, so use them only when representative benchmarks show
+// an improvement.
+
+inline void QuichePrefetchT0(const void* addr) {
+  return QuichePrefetchT0Impl(addr);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_PREFETCH_H_
diff --git a/quiche/common/platform/api/quiche_reference_counted.h b/quiche/common/platform/api/quiche_reference_counted.h
new file mode 100644
index 0000000..a2cc296
--- /dev/null
+++ b/quiche/common/platform/api/quiche_reference_counted.h
@@ -0,0 +1,169 @@
+// Copyright (c) 2016 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.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
+
+#include "quiche_platform_impl/quiche_reference_counted_impl.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// Base class for explicitly reference-counted objects in QUIC.
+class QUICHE_EXPORT_PRIVATE QuicheReferenceCounted
+    : public QuicheReferenceCountedImpl {
+ public:
+  QuicheReferenceCounted() {}
+
+ protected:
+  ~QuicheReferenceCounted() override {}
+};
+
+// A class representing a reference counted pointer in QUIC.
+//
+// Construct or initialize QuicheReferenceCountedPointer from raw pointer. Here
+// raw pointer MUST be a newly created object. Reference count of a newly
+// created object is undefined, but that will be 1 after being added to
+// QuicheReferenceCountedPointer.
+// QuicheReferenceCountedPointer is used as a local variable.
+// QuicheReferenceCountedPointer<T> r_ptr(new T());
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr;
+// T* p = new T();
+// r_ptr = T;
+//
+// QuicheReferenceCountedPointer is used as a member variable:
+// MyClass::MyClass() : r_ptr(new T()) {}
+//
+// This is WRONG, since *p is not guaranteed to be newly created:
+// MyClass::MyClass(T* p) : r_ptr(p) {}
+//
+// Given an existing QuicheReferenceCountedPointer, create a duplicate that has
+// its own reference on the object:
+// QuicheReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
+//
+// Given an existing QuicheReferenceCountedPointer, create a
+// QuicheReferenceCountedPointer that adopts the reference:
+// QuicheReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);
+
+template <class T>
+class QUICHE_NO_EXPORT QuicheReferenceCountedPointer {
+ public:
+  QuicheReferenceCountedPointer() = default;
+
+  // Constructor from raw pointer |p|. This guarantees that the reference count
+  // of *p is 1. This should be only called when a new object is created.
+  // Calling this on an already existent object does not increase its reference
+  // count.
+  explicit QuicheReferenceCountedPointer(T* p) : impl_(p) {}
+
+  // Allows implicit conversion from nullptr.
+  QuicheReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {}  // NOLINT
+
+  // Copy and copy conversion constructors. It does not take the reference away
+  // from |other| and they each end up with their own reference.
+  template <typename U>
+  QuicheReferenceCountedPointer(  // NOLINT
+      const QuicheReferenceCountedPointer<U>& other)
+      : impl_(other.impl()) {}
+  QuicheReferenceCountedPointer(const QuicheReferenceCountedPointer& other)
+      : impl_(other.impl()) {}
+
+  // Move constructors. After move, it adopts the reference from |other|.
+  template <typename U>
+  QuicheReferenceCountedPointer(
+      QuicheReferenceCountedPointer<U>&& other)  // NOLINT
+      : impl_(std::move(other.impl())) {}
+  QuicheReferenceCountedPointer(QuicheReferenceCountedPointer&& other)
+      : impl_(std::move(other.impl())) {}
+
+  ~QuicheReferenceCountedPointer() = default;
+
+  // Copy assignments.
+  QuicheReferenceCountedPointer& operator=(
+      const QuicheReferenceCountedPointer& other) {
+    impl_ = other.impl();
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointer<T>& operator=(
+      const QuicheReferenceCountedPointer<U>& other) {
+    impl_ = other.impl();
+    return *this;
+  }
+
+  // Move assignments.
+  QuicheReferenceCountedPointer& operator=(
+      QuicheReferenceCountedPointer&& other) {
+    impl_ = std::move(other.impl());
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointer<T>& operator=(
+      QuicheReferenceCountedPointer<U>&& other) {
+    impl_ = std::move(other.impl());
+    return *this;
+  }
+
+  // Accessors for the referenced object.
+  // operator*() and operator->() will assert() if there is no current object.
+  T& operator*() const { return *impl_; }
+  T* operator->() const { return impl_.get(); }
+
+  explicit operator bool() const { return static_cast<bool>(impl_); }
+
+  // Assignment operator on raw pointer. Drops a reference to current pointee,
+  // if any, and replaces it with |p|. This guarantees that the reference count
+  // of *p is 1. This should only be used when a new object is created.  Calling
+  // this on an already existent object is undefined behavior.
+  QuicheReferenceCountedPointer<T>& operator=(T* p) {
+    impl_ = p;
+    return *this;
+  }
+
+  // Returns the raw pointer with no change in reference count.
+  T* get() const { return impl_.get(); }
+
+  QuicheReferenceCountedPointerImpl<T>& impl() { return impl_; }
+  const QuicheReferenceCountedPointerImpl<T>& impl() const { return impl_; }
+
+  // Comparisons against same type.
+  friend bool operator==(const QuicheReferenceCountedPointer& a,
+                         const QuicheReferenceCountedPointer& b) {
+    return a.get() == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointer& a,
+                         const QuicheReferenceCountedPointer& b) {
+    return a.get() != b.get();
+  }
+
+  // Comparisons against nullptr.
+  friend bool operator==(const QuicheReferenceCountedPointer& a,
+                         std::nullptr_t) {
+    return a.get() == nullptr;
+  }
+  friend bool operator==(std::nullptr_t,
+                         const QuicheReferenceCountedPointer& b) {
+    return nullptr == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointer& a,
+                         std::nullptr_t) {
+    return a.get() != nullptr;
+  }
+  friend bool operator!=(std::nullptr_t,
+                         const QuicheReferenceCountedPointer& b) {
+    return nullptr != b.get();
+  }
+
+ private:
+  QuicheReferenceCountedPointerImpl<T> impl_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
diff --git a/quiche/common/platform/api/quiche_reference_counted_test.cc b/quiche/common/platform/api/quiche_reference_counted_test.cc
new file mode 100644
index 0000000..7c05d7a
--- /dev/null
+++ b/quiche/common/platform/api/quiche_reference_counted_test.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2016 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.
+
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class Base : public QuicheReferenceCounted {
+ public:
+  explicit Base(bool* destroyed) : destroyed_(destroyed) {
+    *destroyed_ = false;
+  }
+
+ protected:
+  ~Base() override { *destroyed_ = true; }
+
+ private:
+  bool* destroyed_;
+};
+
+class Derived : public Base {
+ public:
+  explicit Derived(bool* destroyed) : Base(destroyed) {}
+
+ private:
+  ~Derived() override {}
+};
+
+class QuicheReferenceCountedTest : public QuicheTest {};
+
+TEST_F(QuicheReferenceCountedTest, DefaultConstructor) {
+  QuicheReferenceCountedPointer<Base> a;
+  EXPECT_EQ(nullptr, a);
+  EXPECT_EQ(nullptr, a.get());
+  EXPECT_FALSE(a);
+}
+
+TEST_F(QuicheReferenceCountedTest, ConstructFromRawPointer) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, RawPointerAssignment) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a;
+    Base* rct = new Base(&destroyed);
+    a = rct;
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopy) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b(a);
+      EXPECT_EQ(a, b);
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyAssignment) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b = a;
+      EXPECT_EQ(a, b);
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyFromOtherType) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b(a);
+      EXPECT_EQ(a.get(), b.get());
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyAssignmentFromOtherType) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b = a;
+      EXPECT_EQ(a.get(), b.get());
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMove) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b(std::move(a));
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveAssignment) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b = std::move(a);
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveFromOtherType) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b(std::move(a));
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveAssignmentFromOtherType) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b = std::move(a);
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_server_stats.h b/quiche/common/platform/api/quiche_server_stats.h
new file mode 100644
index 0000000..e8ad499
--- /dev/null
+++ b/quiche/common/platform/api/quiche_server_stats.h
@@ -0,0 +1,82 @@
+// Copyright 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_SERVER_STATS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_SERVER_STATS_H_
+
+#include "quiche_platform_impl/quiche_server_stats_impl.h"
+
+namespace quiche {
+
+//------------------------------------------------------------------------------
+// Enumeration histograms.
+//
+// Sample usage:
+//   // In Chrome, these values are persisted to logs. Entries should not be
+//   // renumbered and numeric values should never be reused.
+//   enum class MyEnum {
+//     FIRST_VALUE = 0,
+//     SECOND_VALUE = 1,
+//     ...
+//     FINAL_VALUE = N,
+//     COUNT
+//   };
+//   QUICHE_SERVER_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
+//   MyEnum::COUNT, "Number of time $foo equals to some enum value");
+//
+// Note: The value in |sample| must be strictly less than |enum_size|.
+
+#define QUICHE_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
+  QUICHE_SERVER_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring)
+
+//------------------------------------------------------------------------------
+// Histogram for boolean values.
+
+// Sample usage:
+//   QUICHE_SERVER_HISTOGRAM_BOOL("My.Boolean", bool,
+//   "Number of times $foo is true or false");
+#define QUICHE_SERVER_HISTOGRAM_BOOL(name, sample, docstring) \
+  QUICHE_SERVER_HISTOGRAM_BOOL_IMPL(name, sample, docstring)
+
+//------------------------------------------------------------------------------
+// Timing histograms. These are used for collecting timing data (generally
+// latencies).
+
+// These macros create exponentially sized histograms (lengths of the bucket
+// ranges exponentially increase as the sample range increases). The units for
+// sample and max are unspecified, but they must be the same for one histogram.
+
+// Sample usage:
+//   QUICHE_SERVER_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
+//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
+//       24), 100, "Time spent in doing operation.");
+#define QUICHE_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
+                                      docstring)                            \
+  QUICHE_SERVER_HISTOGRAM_TIMES_IMPL(name, sample, min, max, bucket_count,  \
+                                     docstring)
+
+//------------------------------------------------------------------------------
+// Count histograms. These are used for collecting numeric data.
+
+// These macros default to exponential histograms - i.e. the lengths of the
+// bucket ranges exponentially increase as the sample range increases.
+
+// All of these macros must be called with |name| as a runtime constant.
+
+// Any data outside the range here will be put in underflow and overflow
+// buckets. Min values should be >=1 as emitted 0s will still go into the
+// underflow bucket.
+
+// Sample usage:
+//   QUICHE_SERVER_SERVER_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000,
+//   100, "Counters of hitting certian code.");
+
+#define QUICHE_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
+                                       docstring)                            \
+  QUICHE_SERVER_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, bucket_count,  \
+                                      docstring)
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_SERVER_STATS_H_
diff --git a/quiche/common/platform/api/quiche_stack_trace.h b/quiche/common/platform/api/quiche_stack_trace.h
new file mode 100644
index 0000000..876cc98
--- /dev/null
+++ b/quiche/common/platform/api/quiche_stack_trace.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_STACK_TRACE_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_STACK_TRACE_H_
+
+#include <string>
+
+#include "quiche_platform_impl/quiche_stack_trace_impl.h"
+
+namespace quiche {
+
+inline std::string QuicheStackTrace() { return QuicheStackTraceImpl(); }
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_STACK_TRACE_H_
diff --git a/quiche/common/platform/api/quiche_stream_buffer_allocator.h b/quiche/common/platform/api/quiche_stream_buffer_allocator.h
new file mode 100644
index 0000000..16e5e7c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_stream_buffer_allocator.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_STREAM_BUFFER_ALLOCATOR_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_STREAM_BUFFER_ALLOCATOR_H_
+
+#include "quiche_platform_impl/quiche_stream_buffer_allocator_impl.h"
+
+namespace quiche {
+
+using QuicheStreamBufferAllocator = QuicheStreamBufferAllocatorImpl;
+
+}
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/quiche/common/platform/api/quiche_system_event_loop.h b/quiche/common/platform/api/quiche_system_event_loop.h
new file mode 100644
index 0000000..41ed45a
--- /dev/null
+++ b/quiche/common/platform/api/quiche_system_event_loop.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_SYSTEM_EVENT_LOOP_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_SYSTEM_EVENT_LOOP_H_
+
+#include "quiche_platform_impl/quiche_system_event_loop_impl.h"
+
+namespace quiche {
+
+inline void QuicheRunSystemEventLoopIteration() {
+  QuicheRunSystemEventLoopIterationImpl();
+}
+
+using QuicheSystemEventLoop = QuicheSystemEventLoopImpl;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_SYSTEM_EVENT_LOOP_H_
diff --git a/quiche/common/platform/api/quiche_test.h b/quiche/common/platform/api/quiche_test.h
new file mode 100644
index 0000000..afc298a
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_H_
+
+#include "quiche_platform_impl/quiche_test_impl.h"
+
+using QuicheTest = quiche::test::QuicheTest;
+
+template <class T>
+using QuicheTestWithParam = quiche::test::QuicheTestWithParamImpl<T>;
+
+using QuicheFlagSaver = QuicheFlagSaverImpl;
+
+// Class which needs to be instantiated in tests which use threads.
+using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl;
+
+inline std::string QuicheGetTestMemoryCachePath() {
+  return QuicheGetTestMemoryCachePathImpl();
+}
+
+namespace quiche {
+namespace test {
+
+// Returns the path to quiche/common directory where the test data could be
+// located.
+inline std::string QuicheGetCommonSourcePath() {
+  return QuicheGetCommonSourcePathImpl();
+}
+
+}  // namespace test
+}  // namespace quiche
+
+#define EXPECT_QUICHE_DEBUG_DEATH(condition, message) \
+  EXPECT_QUICHE_DEBUG_DEATH_IMPL(condition, message)
+
+#define QUICHE_TEST_DISABLED_IN_CHROME(name) \
+  QUICHE_TEST_DISABLED_IN_CHROME_IMPL(name)
+
+#define QUICHE_SLOW_TEST(test) QUICHE_SLOW_TEST_IMPL(test)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_H_
diff --git a/quiche/common/platform/api/quiche_test_helpers.h b/quiche/common/platform/api/quiche_test_helpers.h
new file mode 100644
index 0000000..2dbe611
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_helpers.h
@@ -0,0 +1,8 @@
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_HELPERS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_HELPERS_H_
+
+#include "quiche_platform_impl/quiche_test_helpers_impl.h"
+
+#define EXPECT_QUICHE_BUG EXPECT_QUICHE_BUG_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_HELPERS_H_
diff --git a/quiche/common/platform/api/quiche_test_loopback.cc b/quiche/common/platform/api/quiche_test_loopback.cc
new file mode 100644
index 0000000..07d3ccf
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_loopback.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2017 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.
+
+#include "quiche/common/platform/api/quiche_test_loopback.h"
+
+namespace quiche {
+
+quic::IpAddressFamily AddressFamilyUnderTest() {
+  return AddressFamilyUnderTestImpl();
+}
+
+quic::QuicIpAddress TestLoopback4() { return TestLoopback4Impl(); }
+
+quic::QuicIpAddress TestLoopback6() { return TestLoopback6Impl(); }
+
+quic::QuicIpAddress TestLoopback() { return TestLoopbackImpl(); }
+
+quic::QuicIpAddress TestLoopback(int index) { return TestLoopbackImpl(index); }
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_test_loopback.h b/quiche/common/platform/api/quiche_test_loopback.h
new file mode 100644
index 0000000..b493ca4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_loopback.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
+
+#include "quiche_platform_impl/quiche_test_loopback_impl.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quiche {
+
+// Returns the address family (IPv4 or IPv6) used to run test under.
+quic::IpAddressFamily AddressFamilyUnderTest();
+
+// Returns an IPv4 loopback address.
+quic::QuicIpAddress TestLoopback4();
+
+// Returns the only IPv6 loopback address.
+quic::QuicIpAddress TestLoopback6();
+
+// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
+// test's environment.
+quic::QuicIpAddress TestLoopback();
+
+// If address family under test is IPv4, returns an indexed IPv4 loopback
+// address. If address family under test is IPv6, the address returned is
+// platform-dependent.
+quic::QuicIpAddress TestLoopback(int index);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
diff --git a/quiche/common/platform/api/quiche_test_output.h b/quiche/common/platform/api/quiche_test_output.h
new file mode 100644
index 0000000..b28a8a7
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_output.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_OUTPUT_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_OUTPUT_H_
+
+#include "quiche_platform_impl/quiche_test_output_impl.h"
+#include "absl/strings/string_view.h"
+
+namespace quiche {
+
+// Save |data| into ${QUICHE_TEST_OUTPUT_DIR}/filename. If a file with the same
+// path already exists, overwrite it.
+inline void QuicheSaveTestOutput(absl::string_view filename,
+                                 absl::string_view data) {
+  QuicheSaveTestOutputImpl(filename, data);
+}
+
+// Load the content of ${QUICHE_TEST_OUTPUT_DIR}/filename into |*data|.
+// Return whether it is successfully loaded.
+inline bool QuicheLoadTestOutput(absl::string_view filename,
+                                 std::string* data) {
+  return QuicheLoadTestOutputImpl(filename, data);
+}
+
+// Records a QUIC trace file(.qtr) into a directory specified by the
+// QUICHE_TEST_OUTPUT_DIR environment variable.  Assumes that it's called from a
+// unit test.
+//
+// The |identifier| is a human-readable identifier that will be combined with
+// the name of the unit test and a timestamp.  |data| is the serialized
+// quic_trace.Trace protobuf that is being recorded into the file.
+inline void QuicheRecordTrace(absl::string_view identifier,
+                              absl::string_view data) {
+  QuicheRecordTraceImpl(identifier, data);
+}
+
+}  // namespace quiche
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_OUTPUT_H_
diff --git a/quiche/common/platform/api/quiche_testvalue.h b/quiche/common/platform/api/quiche_testvalue.h
new file mode 100644
index 0000000..ec50cd9
--- /dev/null
+++ b/quiche/common/platform/api/quiche_testvalue.h
@@ -0,0 +1,25 @@
+// Copyright 2020 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TESTVALUE_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TESTVALUE_H_
+
+#include "quiche_platform_impl/quiche_testvalue_impl.h"
+#include "absl/strings/string_view.h"
+
+namespace quiche {
+
+// Interface allowing injection of test-specific code in production codepaths.
+// |label| is an arbitrary value identifying the location, and |var| is a
+// pointer to the value to be modified.
+//
+// Note that this method does nothing in Chromium.
+template <class T>
+void AdjustTestValue(absl::string_view label, T* var) {
+  AdjustTestValueImpl(label, var);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TESTVALUE_H_
diff --git a/quiche/common/platform/api/quiche_thread.h b/quiche/common/platform/api/quiche_thread.h
new file mode 100644
index 0000000..96a596b
--- /dev/null
+++ b/quiche/common/platform/api/quiche_thread.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
+
+#include <string>
+
+#include "quiche_platform_impl/quiche_thread_impl.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// A class representing a thread of execution in QUIC.
+class QUICHE_EXPORT_PRIVATE QuicheThread : public QuicheThreadImpl {
+ public:
+  QuicheThread(const std::string& string) : QuicheThreadImpl(string) {}
+  QuicheThread(const QuicheThread&) = delete;
+  QuicheThread& operator=(const QuicheThread&) = delete;
+
+  // Impl defines a virtual void Run() method which subclasses
+  // must implement.
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
diff --git a/quiche/common/platform/api/quiche_thread_local.h b/quiche/common/platform/api/quiche_thread_local.h
new file mode 100644
index 0000000..c2d58e1
--- /dev/null
+++ b/quiche/common/platform/api/quiche_thread_local.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_LOCAL_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_LOCAL_H_
+
+#include "quiche_platform_impl/quiche_thread_local_impl.h"
+
+// Define a thread local |type*| with |name|. Conceptually, this is a
+//
+//  static thread_local type* name = nullptr;
+//
+// It is wrapped in a macro because the thread_local keyword is banned from
+// Chromium.
+#define DEFINE_QUICHE_THREAD_LOCAL_POINTER(name, type) \
+  DEFINE_QUICHE_THREAD_LOCAL_POINTER_IMPL(name, type)
+
+// Get the value of |name| for the current thread.
+#define GET_QUICHE_THREAD_LOCAL_POINTER(name) \
+  GET_QUICHE_THREAD_LOCAL_POINTER_IMPL(name)
+
+// Set the |value| of |name| for the current thread.
+#define SET_QUICHE_THREAD_LOCAL_POINTER(name, value) \
+  SET_QUICHE_THREAD_LOCAL_POINTER_IMPL(name, value)
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_LOCAL_H_
diff --git a/quiche/common/platform/api/quiche_time_utils.h b/quiche/common/platform/api/quiche_time_utils.h
new file mode 100644
index 0000000..9a957b0
--- /dev/null
+++ b/quiche/common/platform/api/quiche_time_utils.h
@@ -0,0 +1,31 @@
+// Copyright 2020 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+
+#include <cstdint>
+
+#include "quiche_platform_impl/quiche_time_utils_impl.h"
+
+namespace quiche {
+
+// Converts a civil time specified in UTC into a number of seconds since the
+// Unix epoch.  This function is strict about validity of accepted dates.  For
+// instance, it will reject February 29 on non-leap years, or 25 hours in a day.
+// As a notable exception, 60 seconds is accepted to deal with potential leap
+// seconds.  If the date predates Unix epoch, nullopt will be returned.
+inline absl::optional<int64_t> QuicheUtcDateTimeToUnixSeconds(int year,
+                                                              int month,
+                                                              int day,
+                                                              int hour,
+                                                              int minute,
+                                                              int second) {
+  return QuicheUtcDateTimeToUnixSecondsImpl(year, month, day, hour, minute,
+                                            second);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_time_utils_test.cc b/quiche/common/platform/api/quiche_time_utils_test.cc
new file mode 100644
index 0000000..5d09004
--- /dev/null
+++ b/quiche/common/platform/api/quiche_time_utils_test.cc
@@ -0,0 +1,51 @@
+// Copyright 2020 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.
+
+#include "quiche/common/platform/api/quiche_time_utils.h"
+
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+TEST(QuicheTimeUtilsTest, Basic) {
+  EXPECT_EQ(1, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 0, 1));
+  EXPECT_EQ(365 * 86400, QuicheUtcDateTimeToUnixSeconds(1971, 1, 1, 0, 0, 0));
+  // Some arbitrary timestamps closer to the present, compared to the output of
+  // "Date(...).getTime()" from the JavaScript console.
+  EXPECT_EQ(1152966896,
+            QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56));
+  EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21));
+
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1));
+  EXPECT_NE(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1));
+}
+
+TEST(QuicheTimeUtilsTest, Bounds) {
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0));
+}
+
+TEST(QuicheTimeUtilsTest, LeapSecond) {
+  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 23, 59, 60),
+            QuicheUtcDateTimeToUnixSeconds(2015, 7, 1, 0, 0, 0));
+  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 25, 59, 60),
+            absl::nullopt);
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_udp_socket_platform_api.h b/quiche/common/platform/api/quiche_udp_socket_platform_api.h
new file mode 100644
index 0000000..474e89d
--- /dev/null
+++ b/quiche/common/platform/api/quiche_udp_socket_platform_api.h
@@ -0,0 +1,29 @@
+// Copyright 2019 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_UDP_SOCKET_PLATFORM_API_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_UDP_SOCKET_PLATFORM_API_H_
+
+#include "quiche_platform_impl/quiche_udp_socket_platform_impl.h"
+
+namespace quiche {
+
+const size_t kCmsgSpaceForGooglePacketHeader =
+    kCmsgSpaceForGooglePacketHeaderImpl;
+
+inline bool GetGooglePacketHeadersFromControlMessage(
+    struct ::cmsghdr* cmsg,
+    char** packet_headers,
+    size_t* packet_headers_len) {
+  return GetGooglePacketHeadersFromControlMessageImpl(cmsg, packet_headers,
+                                                      packet_headers_len);
+}
+
+inline void SetGoogleSocketOptions(int fd) {
+  SetGoogleSocketOptionsImpl(fd);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_UDP_SOCKET_PLATFORM_API_H_
diff --git a/quiche/common/platform/api/quiche_url_utils.h b/quiche/common/platform/api/quiche_url_utils.h
new file mode 100644
index 0000000..e6c9fc9
--- /dev/null
+++ b/quiche/common/platform/api/quiche_url_utils.h
@@ -0,0 +1,38 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_URL_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_URL_UTILS_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche_platform_impl/quiche_url_utils_impl.h"
+
+namespace quiche {
+
+// Produces concrete URLs in |target| from templated ones in |uri_template|.
+// Parameters are URL-encoded. Collects the names of any expanded variables in
+// |vars_found|. Returns true if the template was parseable, false if it was
+// malformed.
+inline bool ExpandURITemplate(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    std::string* target,
+    absl::flat_hash_set<std::string>* vars_found = nullptr) {
+  return ExpandURITemplateImpl(uri_template, parameters, target, vars_found);
+}
+
+// Decodes a URL-encoded string and converts it to ASCII. If the decoded input
+// contains non-ASCII characters, decoding fails and absl::nullopt is returned.
+inline absl::optional<std::string> AsciiUrlDecode(absl::string_view input) {
+  return AsciiUrlDecodeImpl(input);
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_URL_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_url_utils_test.cc b/quiche/common/platform/api/quiche_url_utils_test.cc
new file mode 100644
index 0000000..33a30ec
--- /dev/null
+++ b/quiche/common/platform/api/quiche_url_utils_test.cc
@@ -0,0 +1,80 @@
+// 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.
+
+#include "quiche/common/platform/api/quiche_url_utils.h"
+
+#include <set>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+void ValidateExpansion(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    const std::string& expected_expansion,
+    const absl::flat_hash_set<std::string>& expected_vars_found) {
+  absl::flat_hash_set<std::string> vars_found;
+  std::string target;
+  ASSERT_TRUE(
+      ExpandURITemplate(uri_template, parameters, &target, &vars_found));
+  EXPECT_EQ(expected_expansion, target);
+  EXPECT_EQ(vars_found, expected_vars_found);
+}
+
+TEST(QuicheUrlUtilsTest, Basic) {
+  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456/", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, ExtraParameter) {
+  ValidateExpansion("/{foo}/{bar}/{baz}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456//", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, MissingParameter) {
+  ValidateExpansion("/{foo}/{baz}/", {{"foo", "123"}, {"bar", "456"}}, "/123//",
+                    {"foo"});
+}
+
+TEST(QuicheUrlUtilsTest, RepeatedParameter) {
+  ValidateExpansion("/{foo}/{bar}/{foo}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456/123/", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, URLEncoding) {
+  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", ":"}},
+                    "/123/%3A/", {"foo", "bar"});
+}
+
+void ValidateUrlDecode(const std::string& input,
+                       const absl::optional<std::string>& expected_output) {
+  absl::optional<std::string> decode_result = AsciiUrlDecode(input);
+  if (!expected_output.has_value()) {
+    EXPECT_FALSE(decode_result.has_value());
+    return;
+  }
+  ASSERT_TRUE(decode_result.has_value());
+  EXPECT_EQ(decode_result.value(), expected_output);
+}
+
+TEST(QuicheUrlUtilsTest, DecodeNoChange) {
+  ValidateUrlDecode("foobar", "foobar");
+}
+
+TEST(QuicheUrlUtilsTest, DecodeReplace) {
+  ValidateUrlDecode("%7Bfoobar%7D", "{foobar}");
+}
+
+TEST(QuicheUrlUtilsTest, DecodeFail) {
+  ValidateUrlDecode("%FF", absl::nullopt);
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
new file mode 100644
index 0000000..df2c88e
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
@@ -0,0 +1,29 @@
+// Copyright 2014 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.
+
+#include "quiche_platform_impl/quic_flags_impl.h"
+
+#define DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE(type, flag, value, doc) \
+  type FLAGS_##flag = value;
+
+#define DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES(type, flag, internal_value, \
+                                             external_value, doc)        \
+  type FLAGS_##flag = external_value;
+
+// Preprocessor macros can only have one definition.
+// Select the right macro based on the number of arguments.
+#define GET_6TH_ARG(arg1, arg2, arg3, arg4, arg5, arg6, ...) arg6
+#define QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(...)                    \
+  GET_6TH_ARG(__VA_ARGS__, DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES, \
+              DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE)
+#define QUIC_PROTOCOL_FLAG(...) \
+  QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
+
+#include "quiche/quic/core/quic_protocol_flags_list.h"
+
+#undef QUIC_PROTOCOL_FLAG
+#undef QUIC_PROTOCOL_FLAG_MACRO_CHOOSER
+#undef GET_6TH_ARG
+#undef DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES
+#undef DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE
diff --git a/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h
new file mode 100644
index 0000000..2d7af12
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
+
+#include <string>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_flags.h"
+
+#define QUIC_PROTOCOL_FLAG(type, flag, ...) \
+  QUICHE_EXPORT_PRIVATE extern type FLAGS_##flag;
+#include "quiche/quic/core/quic_protocol_flags_list.h"
+#undef QUIC_PROTOCOL_FLAG
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
new file mode 100644
index 0000000..913300f
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
@@ -0,0 +1,15 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+#define QUICHE_BUG_IMPL(b) QUICHE_LOG(DFATAL)
+#define QUICHE_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
+#define QUICHE_PEER_BUG_IMPL(b) QUICHE_LOG(DFATAL)
+#define QUICHE_PEER_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h
new file mode 100644
index 0000000..fde75f7
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h
@@ -0,0 +1,44 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CLIENT_STATS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CLIENT_STATS_IMPL_H_
+
+#include <string>
+
+namespace quiche {
+
+// Use namespace qualifier in case the macro is used outside the quiche
+// namespace.
+
+#define QUICHE_CLIENT_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring) \
+  do {                                                                        \
+    quiche::QuicheClientSparseHistogramImpl(name, static_cast<int>(sample));  \
+  } while (0)
+
+#define QUICHE_CLIENT_HISTOGRAM_BOOL_IMPL(name, sample, docstring) \
+  do {                                                             \
+    (void)sample; /* Workaround for -Wunused-variable. */          \
+  } while (0)
+
+#define QUICHE_CLIENT_HISTOGRAM_TIMES_IMPL(name, sample, min, max, \
+                                           num_buckets, docstring) \
+  do {                                                             \
+    (void)sample; /* Workaround for -Wunused-variable. */          \
+  } while (0)
+
+#define QUICHE_CLIENT_HISTOGRAM_COUNTS_IMPL(name, sample, min, max, \
+                                            num_buckets, docstring) \
+  do {                                                              \
+    quiche::QuicheClientSparseHistogramImpl(name, sample);          \
+  } while (0)
+
+inline void QuicheClientSparseHistogramImpl(const std::string& /*name*/,
+                                            int /*sample*/) {
+  // No-op.
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CLIENT_STATS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h
new file mode 100644
index 0000000..56ce474
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CONTAINERS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CONTAINERS_IMPL_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "absl/container/btree_set.h"
+
+#pragma clang diagnostic pop
+
+namespace quiche {
+
+template <typename Key, typename Compare>
+using QuicheSmallOrderedSetImpl = absl::btree_set<Key, Compare>;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_CONTAINERS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h
new file mode 100644
index 0000000..d97748b
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h
@@ -0,0 +1,10 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
+
+// These macros are documented in: quiche/quic/platform/api/quic_export.h
+
+#define QUICHE_EXPORT_IMPL
+#define QUICHE_EXPORT_PRIVATE_IMPL
+#define QUICHE_NO_EXPORT_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc
new file mode 100644
index 0000000..65965b2
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc
@@ -0,0 +1,182 @@
+// 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.
+
+#include "quiche_platform_impl/quiche_file_utils_impl.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#else
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif  // defined(_WIN32)
+
+#include <fstream>
+#include <ios>
+#include <iostream>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+#include "absl/types/optional.h"
+
+namespace quiche {
+
+#if defined(_WIN32)
+std::string JoinPathImpl(absl::string_view a, absl::string_view b) {
+  if (a.empty()) {
+    return std::string(b);
+  }
+  if (b.empty()) {
+    return std::string(a);
+  }
+  // Win32 actually provides two different APIs for combining paths; one of them
+  // has issues that could potentially lead to buffer overflow, and another is
+  // not supported in Windows 7, which is why we're doing it manually.
+  a = absl::StripSuffix(a, "/");
+  a = absl::StripSuffix(a, "\\");
+  return absl::StrCat(a, "\\", b);
+}
+#else
+std::string JoinPathImpl(absl::string_view a, absl::string_view b) {
+  if (a.empty()) {
+    return std::string(b);
+  }
+  if (b.empty()) {
+    return std::string(a);
+  }
+  return absl::StrCat(absl::StripSuffix(a, "/"), "/", b);
+}
+#endif  // defined(_WIN32)
+
+absl::optional<std::string> ReadFileContentsImpl(absl::string_view file) {
+  std::ifstream input_file(std::string{file}, std::ios::binary);
+  if (!input_file || !input_file.is_open()) {
+    return absl::nullopt;
+  }
+
+  input_file.seekg(0, std::ios_base::end);
+  auto file_size = input_file.tellg();
+  if (!input_file) {
+    return absl::nullopt;
+  }
+  input_file.seekg(0, std::ios_base::beg);
+
+  std::string output;
+  output.resize(file_size);
+  input_file.read(&output[0], file_size);
+  if (!input_file) {
+    return absl::nullopt;
+  }
+
+  return output;
+}
+
+#if defined(_WIN32)
+
+class ScopedDir {
+ public:
+  ScopedDir(HANDLE dir) : dir_(dir) {}
+  ~ScopedDir() {
+    if (dir_ != INVALID_HANDLE_VALUE) {
+      // The API documentation explicitly says that CloseHandle() should not be
+      // used on directory search handles.
+      FindClose(dir_);
+      dir_ = INVALID_HANDLE_VALUE;
+    }
+  }
+
+  HANDLE get() { return dir_; }
+
+ private:
+  HANDLE dir_;
+};
+
+bool EnumerateDirectoryImpl(absl::string_view path,
+                            std::vector<std::string>& directories,
+                            std::vector<std::string>& files) {
+  std::string path_owned(path);
+
+  // Explicitly check that the directory we are trying to search is in fact a
+  // directory.
+  DWORD attributes = GetFileAttributesA(path_owned.c_str());
+  if (attributes == INVALID_FILE_ATTRIBUTES) {
+    return false;
+  }
+  if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
+    return false;
+  }
+
+  std::string search_path = JoinPathImpl(path, "*");
+  WIN32_FIND_DATAA file_data;
+  ScopedDir dir(FindFirstFileA(search_path.c_str(), &file_data));
+  if (dir.get() == INVALID_HANDLE_VALUE) {
+    return GetLastError() == ERROR_FILE_NOT_FOUND;
+  }
+  do {
+    std::string filename(file_data.cFileName);
+    if (filename == "." || filename == "..") {
+      continue;
+    }
+    if ((file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+      directories.push_back(std::move(filename));
+    } else {
+      files.push_back(std::move(filename));
+    }
+  } while (FindNextFileA(dir.get(), &file_data));
+  return GetLastError() == ERROR_NO_MORE_FILES;
+}
+
+#else  // defined(_WIN32)
+
+class ScopedDir {
+ public:
+  ScopedDir(DIR* dir) : dir_(dir) {}
+  ~ScopedDir() {
+    if (dir_ != nullptr) {
+      closedir(dir_);
+      dir_ = nullptr;
+    }
+  }
+
+  DIR* get() { return dir_; }
+
+ private:
+  DIR* dir_;
+};
+
+bool EnumerateDirectoryImpl(absl::string_view path,
+                            std::vector<std::string>& directories,
+                            std::vector<std::string>& files) {
+  std::string path_owned(path);
+  ScopedDir dir(opendir(path_owned.c_str()));
+  if (dir.get() == nullptr) {
+    return false;
+  }
+
+  dirent* entry;
+  while ((entry = readdir(dir.get()))) {
+    const std::string filename(entry->d_name);
+    if (filename == "." || filename == "..") {
+      continue;
+    }
+
+    const std::string entry_path = JoinPathImpl(path, filename);
+    struct stat stat_entry;
+    if (stat(entry_path.c_str(), &stat_entry) != 0) {
+      return false;
+    }
+    if (S_ISREG(stat_entry.st_mode)) {
+      files.push_back(std::move(filename));
+    } else if (S_ISDIR(stat_entry.st_mode)) {
+      directories.push_back(std::move(filename));
+    }
+  }
+  return true;
+}
+
+#endif  // defined(_WIN32)
+
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h
new file mode 100644
index 0000000..ad5ff1a
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FILE_UTILS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FILE_UTILS_IMPL_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+
+namespace quiche {
+
+std::string JoinPathImpl(absl::string_view a, absl::string_view b);
+
+absl::optional<std::string> ReadFileContentsImpl(absl::string_view file);
+
+bool EnumerateDirectoryImpl(absl::string_view path,
+                            std::vector<std::string>& directories,
+                            std::vector<std::string>& files);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FILE_UTILS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
new file mode 100644
index 0000000..c38f75c
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
@@ -0,0 +1,29 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAG_UTILS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAG_UTILS_IMPL_H_
+
+#define QUICHE_RELOADABLE_FLAG_COUNT_IMPL(flag) \
+  do {                                          \
+  } while (0)
+#define QUICHE_RELOADABLE_FLAG_COUNT_N_IMPL(flag, instance, total) \
+  do {                                                             \
+  } while (0)
+
+#define QUICHE_RESTART_FLAG_COUNT_IMPL(flag) \
+  do {                                       \
+  } while (0)
+#define QUICHE_RESTART_FLAG_COUNT_N_IMPL(flag, instance, total) \
+  do {                                                          \
+  } while (0)
+
+#define QUICHE_CODE_COUNT_IMPL(name) \
+  do {                               \
+  } while (0)
+#define QUICHE_CODE_COUNT_N_IMPL(name, instance, total) \
+  do {                                                  \
+  } while (0)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAG_UTILS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
new file mode 100644
index 0000000..6a8e1ca
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
@@ -0,0 +1,9 @@
+// Copyright 2020 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.
+
+#include "quiche_platform_impl/quiche_flags_impl.h"
+
+#define QUIC_FLAG(flag, value) bool flag = value;
+#include "quiche/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
new file mode 100644
index 0000000..a1eba51
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
@@ -0,0 +1,42 @@
+// Copyright 2020 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+#define QUIC_FLAG(flag, value) QUICHE_EXPORT_PRIVATE extern bool flag;
+#include "quiche/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
+
+inline bool GetQuicheFlagImpl(bool flag) { return flag; }
+inline int32_t GetQuicheFlagImpl(int32_t flag) { return flag; }
+inline int64_t GetQuicheFlagImpl(int64_t flag) { return flag; }
+inline uint64_t GetQuicheFlagImpl(uint64_t flag) { return flag; }
+inline double GetQuicheFlagImpl(double flag) { return flag; }
+inline std::string GetQuicheFlagImpl(const std::string& flag) { return flag; }
+#define SetQuicheFlagImpl(flag, value) ((flag) = (value))
+
+// ------------------------------------------------------------------------
+// QUIC feature flags implementation.
+// ------------------------------------------------------------------------
+#define QUICHE_RELOADABLE_FLAG(flag) FLAGS_quic_reloadable_flag_##flag
+#define QUICHE_RESTART_FLAG(flag) FLAGS_quic_restart_flag_##flag
+#define GetQuicheReloadableFlagImpl(module, flag) \
+  GetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag))
+#define SetQuicheReloadableFlagImpl(module, flag, value) \
+  SetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag), value)
+#define GetQuicheRestartFlagImpl(module, flag) \
+  GetQuicheFlag(QUICHE_RESTART_FLAG(flag))
+#define SetQuicheRestartFlagImpl(module, flag, value) \
+  SetQuicheFlag(QUICHE_RESTART_FLAG(flag), value)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
new file mode 100644
index 0000000..32f0678
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
@@ -0,0 +1,24 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+#if defined(_WIN32)
+
+// See <https://pubs.opengroup.org/onlinepubs/009604599/basedefs/sys/uio.h.html>
+struct QUICHE_EXPORT_PRIVAATE iovec {
+  void* iov_base;
+  size_t iov_len;
+};
+
+#else
+
+#include <sys/uio.h>  // IWYU pragma: export
+
+#endif  // defined(_WIN32)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
new file mode 100644
index 0000000..4b414e7
--- /dev/null
+++ b/quiche/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_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
new file mode 100644
index 0000000..a40fa94
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
@@ -0,0 +1,46 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheMemSliceImpl {
+ public:
+  QuicheMemSliceImpl() = default;
+
+  explicit QuicheMemSliceImpl(QuicheBuffer buffer)
+      : buffer_(std::move(buffer)) {}
+
+  QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length)
+      : buffer_(
+            QuicheBuffer(QuicheUniqueBufferPtr(
+                             buffer.release(),
+                             QuicheBufferDeleter(SimpleBufferAllocator::Get())),
+                         length)) {}
+
+  QuicheMemSliceImpl(const QuicheMemSliceImpl& other) = delete;
+  QuicheMemSliceImpl& operator=(const QuicheMemSliceImpl& other) = delete;
+
+  // Move constructors. |other| will not hold a reference to the data buffer
+  // after this call completes.
+  QuicheMemSliceImpl(QuicheMemSliceImpl&& other) = default;
+  QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& other) = default;
+
+  ~QuicheMemSliceImpl() = default;
+
+  void Reset() { buffer_ = QuicheBuffer(); }
+
+  const char* data() const { return buffer_.data(); }
+  size_t length() const { return buffer_.size(); }
+  bool empty() const { return buffer_.empty(); }
+
+ private:
+  QuicheBuffer buffer_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
new file mode 100644
index 0000000..78ca926
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
@@ -0,0 +1,15 @@
+#include "quiche_platform_impl/quiche_mutex_impl.h"
+
+namespace quiche {
+
+void QuicheLockImpl::WriterLock() { mu_.WriterLock(); }
+
+void QuicheLockImpl::WriterUnlock() { mu_.WriterUnlock(); }
+
+void QuicheLockImpl::ReaderLock() { mu_.ReaderLock(); }
+
+void QuicheLockImpl::ReaderUnlock() { mu_.ReaderUnlock(); }
+
+void QuicheLockImpl::AssertReaderHeld() const { mu_.AssertReaderHeld(); }
+
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
new file mode 100644
index 0000000..e358c2b
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
@@ -0,0 +1,68 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
+
+#include "absl/synchronization/mutex.h"
+#include "absl/synchronization/notification.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+#define QUICHE_EXCLUSIVE_LOCKS_REQUIRED_IMPL ABSL_EXCLUSIVE_LOCKS_REQUIRED
+#define QUICHE_GUARDED_BY_IMPL ABSL_GUARDED_BY
+#define QUICHE_LOCKABLE_IMPL ABSL_LOCKABLE
+#define QUICHE_LOCKS_EXCLUDED_IMPL ABSL_LOCKS_EXCLUDED
+#define QUICHE_SHARED_LOCKS_REQUIRED_IMPL ABSL_SHARED_LOCKS_REQUIRED
+#define QUICHE_EXCLUSIVE_LOCK_FUNCTION_IMPL ABSL_EXCLUSIVE_LOCK_FUNCTION
+#define QUICHE_UNLOCK_FUNCTION_IMPL ABSL_UNLOCK_FUNCTION
+#define QUICHE_SHARED_LOCK_FUNCTION_IMPL ABSL_SHARED_LOCK_FUNCTION
+#define QUICHE_SCOPED_LOCKABLE_IMPL ABSL_SCOPED_LOCKABLE
+#define QUICHE_ASSERT_SHARED_LOCK_IMPL ABSL_ASSERT_SHARED_LOCK
+
+namespace quiche {
+
+// A class wrapping a non-reentrant mutex.
+class ABSL_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheLockImpl {
+ public:
+  QuicheLockImpl() = default;
+  QuicheLockImpl(const QuicheLockImpl&) = delete;
+  QuicheLockImpl& operator=(const QuicheLockImpl&) = delete;
+
+  // Block until mu_ is free, then acquire it exclusively.
+  void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION();
+
+  // Release mu_. Caller must hold it exclusively.
+  void WriterUnlock() ABSL_UNLOCK_FUNCTION();
+
+  // Block until mu_ is free or shared, then acquire a share of it.
+  void ReaderLock() ABSL_SHARED_LOCK_FUNCTION();
+
+  // Release mu_. Caller could hold it in shared mode.
+  void ReaderUnlock() ABSL_UNLOCK_FUNCTION();
+
+  // Returns immediately if current thread holds mu_ in at least shared
+  // mode.  Otherwise, reports an error by crashing with a diagnostic.
+  void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();
+
+ private:
+  absl::Mutex mu_;
+};
+
+// A Notification allows threads to receive notification of a single occurrence
+// of a single event.
+class QUICHE_EXPORT_PRIVATE QuicheNotificationImpl {
+ public:
+  QuicheNotificationImpl() = default;
+  QuicheNotificationImpl(const QuicheNotificationImpl&) = delete;
+  QuicheNotificationImpl& operator=(const QuicheNotificationImpl&) = delete;
+
+  bool HasBeenNotified() { return notification_.HasBeenNotified(); }
+
+  void Notify() { notification_.Notify(); }
+
+  void WaitForNotification() { notification_.WaitForNotification(); }
+
+ private:
+  absl::Notification notification_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
new file mode 100644
index 0000000..8945481
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
@@ -0,0 +1,28 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_PREFETCH_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_PREFETCH_IMPL_H_
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+namespace quiche {
+
+inline void QuichePrefetchT0Impl(const void* addr) {
+#if !defined(DISABLE_BUILTIN_PREFETCH)
+#if defined(__GNUC__) || (defined(_M_ARM64) && defined(__clang__))
+  __builtin_prefetch(addr, 0, 3);
+#elif defined(_MSC_VER)
+  _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0);
+#else
+  (void*)addr;
+#endif
+#endif  // !defined(DISABLE_BUILTIN_PREFETCH)
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_PREFETCH_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
new file mode 100644
index 0000000..8f8a514
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
@@ -0,0 +1,190 @@
+// Copyright (c) 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
+
+#include <atomic>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheReferenceCountedImpl {
+ public:
+  virtual ~QuicheReferenceCountedImpl() { QUICHE_DCHECK_EQ(ref_count_, 0); }
+
+  void AddReference() { ref_count_.fetch_add(1, std::memory_order_relaxed); }
+
+  // Returns true if the objects needs to be deleted.
+  ABSL_MUST_USE_RESULT bool RemoveReference() {
+    int new_count = ref_count_.fetch_sub(1, std::memory_order_acq_rel) - 1;
+    QUICHE_DCHECK_GE(new_count, 0);
+    return new_count == 0;
+  }
+
+  bool HasUniqueReference() const {
+    return ref_count_.load(std::memory_order_acquire) == 1;
+  }
+
+ private:
+  std::atomic<int> ref_count_ = 1;
+};
+
+template <class T>
+class QUICHE_NO_EXPORT QuicheReferenceCountedPointerImpl {
+ public:
+  QuicheReferenceCountedPointerImpl() = default;
+  ~QuicheReferenceCountedPointerImpl() { RemoveReference(); }
+
+  // Constructor from raw pointer |p|. This guarantees that the reference count
+  // of *p is 1. This should be only called when a new object is created.
+  explicit QuicheReferenceCountedPointerImpl(T* p) : object_(p) {
+    if (p != nullptr) {
+      QUICHE_DCHECK(p->HasUniqueReference());
+    }
+  }
+
+  explicit QuicheReferenceCountedPointerImpl(std::nullptr_t)
+      : object_(nullptr) {}
+
+  // Copy and copy conversion constructors.
+  QuicheReferenceCountedPointerImpl(
+      const QuicheReferenceCountedPointerImpl& other) {
+    AssignObject(other.get());
+    AddReference();
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl(  // NOLINT
+      const QuicheReferenceCountedPointerImpl<U>& other) {
+    AssignObject(other.get());
+    AddReference();
+  }
+
+  // Move constructors.
+  QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl&& other) {
+    object_ = other.object_;
+    other.object_ = nullptr;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl(
+      QuicheReferenceCountedPointerImpl<U>&& other) {  // NOLINT
+    // We can't access other.object_ since other has different T and object_ is
+    // private.
+    object_ = other.get();
+    AddReference();
+    other = nullptr;
+  }
+
+  // Copy assignments.
+  QuicheReferenceCountedPointerImpl& operator=(
+      const QuicheReferenceCountedPointerImpl& other) {
+    AssignObject(other.object_);
+    AddReference();
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl<T>& operator=(
+      const QuicheReferenceCountedPointerImpl<U>& other) {
+    AssignObject(other.object_);
+    AddReference();
+    return *this;
+  }
+
+  // Move assignments.
+  QuicheReferenceCountedPointerImpl& operator=(
+      QuicheReferenceCountedPointerImpl&& other) {
+    AssignObject(other.object_);
+    other.object_ = nullptr;
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl<T>& operator=(
+      QuicheReferenceCountedPointerImpl<U>&& other) {
+    AssignObject(other.get());
+    AddReference();
+    other = nullptr;
+    return *this;
+  }
+
+  T& operator*() const { return *object_; }
+  T* operator->() const { return object_; }
+
+  explicit operator bool() const { return object_ != nullptr; }
+
+  // Assignment operator on raw pointer.  Behaves similar to the raw pointer
+  // constructor.
+  QuicheReferenceCountedPointerImpl<T>& operator=(T* p) {
+    AssignObject(p);
+    if (p != nullptr) {
+      QUICHE_DCHECK(p->HasUniqueReference());
+    }
+    return *this;
+  }
+
+  // Returns the raw pointer with no change in reference count.
+  T* get() const { return object_; }
+
+  // Comparisons against same type.
+  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return a.get() == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return a.get() != b.get();
+  }
+
+  // Comparisons against nullptr.
+  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
+                         std::nullptr_t) {
+    return a.get() == nullptr;
+  }
+  friend bool operator==(std::nullptr_t,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return nullptr == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
+                         std::nullptr_t) {
+    return a.get() != nullptr;
+  }
+  friend bool operator!=(std::nullptr_t,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return nullptr != b.get();
+  }
+
+ private:
+  void AddReference() {
+    if (object_ == nullptr) {
+      return;
+    }
+    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
+    implicitly_cast_object->AddReference();
+  }
+
+  void RemoveReference() {
+    if (object_ == nullptr) {
+      return;
+    }
+    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
+    if (implicitly_cast_object->RemoveReference()) {
+      delete implicitly_cast_object;
+    }
+    object_ = nullptr;
+  }
+
+  void AssignObject(T* new_object) {
+    RemoveReference();
+    object_ = new_object;
+  }
+
+  T* object_ = nullptr;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h
new file mode 100644
index 0000000..289c599
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h
@@ -0,0 +1,26 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SERVER_STATS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SERVER_STATS_IMPL_H_
+
+#define QUICHE_SERVER_HISTOGRAM_ENUM_IMPL(name, sample, enum_size, docstring) \
+  do {                                                                        \
+  } while (0)
+
+#define QUICHE_SERVER_HISTOGRAM_BOOL_IMPL(name, sample, docstring) \
+  do {                                                             \
+  } while (0)
+
+#define QUICHE_SERVER_HISTOGRAM_TIMES_IMPL(name, sample, min, max,  \
+                                           bucket_count, docstring) \
+  do {                                                              \
+  } while (0)
+
+#define QUICHE_SERVER_HISTOGRAM_COUNTS_IMPL(name, sample, min, max,  \
+                                            bucket_count, docstring) \
+  do {                                                               \
+  } while (0)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SERVER_STATS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
new file mode 100644
index 0000000..ec56ba5
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+
+using QuicheStreamBufferAllocatorImpl = quiche::SimpleBufferAllocator;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
new file mode 100644
index 0000000..c3305c2
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
@@ -0,0 +1,24 @@
+// Copyright 2022 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+inline void QuicheRunSystemEventLoopIterationImpl() {}
+
+class QUICHE_EXPORT_PRIVATE QuicheSystemEventLoopImpl {
+ public:
+  QuicheSystemEventLoopImpl(std::string context_name) {
+    QUICHE_LOG(INFO) << "Starting event loop for " << context_name;
+  }
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h
new file mode 100644
index 0000000..e88283f
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h
@@ -0,0 +1,13 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_TESTVALUE_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_TESTVALUE_IMPL_H_
+
+#include "absl/strings/string_view.h"
+
+namespace quiche {
+
+template <class T>
+void AdjustTestValueImpl(absl::string_view /*label*/, T* /*var*/) {}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_TESTVALUE_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h
new file mode 100644
index 0000000..5ebea4c
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_THREAD_LOCAL_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_THREAD_LOCAL_IMPL_H_
+
+#define DEFINE_QUICHE_THREAD_LOCAL_POINTER_IMPL(name, type) \
+  struct QuicheThreadLocalPointer_##name {                  \
+    static type** Instance() {                              \
+      static thread_local type* instance = nullptr;         \
+      return &instance;                                     \
+    }                                                       \
+    static type* Get() { return *Instance(); }              \
+    static void Set(type* ptr) { *Instance() = ptr; }       \
+  }
+
+#define GET_QUICHE_THREAD_LOCAL_POINTER_IMPL(name) \
+  QuicheThreadLocalPointer_##name::Get()
+
+#define SET_QUICHE_THREAD_LOCAL_POINTER_IMPL(name, value) \
+  QuicheThreadLocalPointer_##name::Set(value)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_THREAD_LOCAL_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc
new file mode 100644
index 0000000..1c6889f
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc
@@ -0,0 +1,52 @@
+// 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.
+
+#include "quiche_platform_impl/quiche_time_utils_impl.h"
+
+#include "absl/time/civil_time.h"
+#include "absl/time/time.h"
+
+namespace quiche {
+
+namespace {
+absl::optional<int64_t> QuicheUtcDateTimeToUnixSecondsInner(int year,
+                                                            int month,
+                                                            int day,
+                                                            int hour,
+                                                            int minute,
+                                                            int second) {
+  const absl::CivilSecond civil_time(year, month, day, hour, minute, second);
+  if (second != 60 &&
+      (civil_time.year() != year || civil_time.month() != month ||
+       civil_time.day() != day || civil_time.hour() != hour ||
+       civil_time.minute() != minute || civil_time.second() != second)) {
+    return absl::nullopt;
+  }
+
+  const absl::Time time = absl::FromCivil(civil_time, absl::UTCTimeZone());
+  return absl::ToUnixSeconds(time);
+}
+}  // namespace
+
+absl::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
+                                                           int month,
+                                                           int day,
+                                                           int hour,
+                                                           int minute,
+                                                           int second) {
+  // Handle leap seconds without letting any other irregularities happen.
+  if (second == 60) {
+    auto previous_second = QuicheUtcDateTimeToUnixSecondsInner(
+        year, month, day, hour, minute, second - 1);
+    if (!previous_second.has_value()) {
+      return absl::nullopt;
+    }
+    return *previous_second + 1;
+  }
+
+  return QuicheUtcDateTimeToUnixSecondsInner(year, month, day, hour, minute,
+                                             second);
+}
+
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h
new file mode 100644
index 0000000..56a08db
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
+
+#include <cstdint>
+
+#include "absl/types/optional.h"
+
+namespace quiche {
+
+absl::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
+                                                           int month,
+                                                           int day,
+                                                           int hour,
+                                                           int minute,
+                                                           int second);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc
new file mode 100644
index 0000000..bcdfa9b
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "quiche_platform_impl/quiche_url_utils_impl.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_replace.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "url/url_canon.h"
+#include "url/url_util.h"
+
+namespace quiche {
+
+bool ExpandURITemplateImpl(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    std::string* target, absl::flat_hash_set<std::string>* vars_found) {
+  absl::flat_hash_set<std::string> found;
+  std::string result = uri_template;
+  for (const auto& pair : parameters) {
+    const std::string& name = pair.first;
+    const std::string& value = pair.second;
+    std::string name_input = absl::StrCat("{", name, "}");
+    url::RawCanonOutputT<char> canon_value;
+    url::EncodeURIComponent(value.c_str(), value.length(), &canon_value);
+    std::string encoded_value(canon_value.data(), canon_value.length());
+    int num_replaced =
+        absl::StrReplaceAll({{name_input, encoded_value}}, &result);
+    if (num_replaced > 0) {
+      found.insert(name);
+    }
+  }
+  // Remove any remaining variables that were not present in |parameters|.
+  while (true) {
+    size_t start = result.find('{');
+    if (start == std::string::npos) {
+      break;
+    }
+    size_t end = result.find('}');
+    if (end == std::string::npos || end <= start) {
+      return false;
+    }
+    result.erase(start, (end - start) + 1);
+  }
+  if (vars_found != nullptr) {
+    *vars_found = found;
+  }
+  *target = result;
+  return true;
+}
+
+absl::optional<std::string> AsciiUrlDecodeImpl(absl::string_view input) {
+  std::string input_encoded = std::string(input);
+  url::RawCanonOutputW<1024> canon_output;
+  url::DecodeURLEscapeSequences(input_encoded.c_str(), input_encoded.length(),
+                                &canon_output);
+  std::string output;
+  output.reserve(canon_output.length());
+  for (int i = 0; i < canon_output.length(); i++) {
+    const uint16_t c = reinterpret_cast<uint16_t*>(canon_output.data())[i];
+    if (c > std::numeric_limits<signed char>::max()) {
+      return absl::nullopt;
+    }
+    output += static_cast<char>(c);
+  }
+  return output;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
new file mode 100644
index 0000000..dd042a3
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// Produces concrete URLs in |target| from templated ones in |uri_template|.
+// Parameters are URL-encoded. Collects the names of any expanded variables in
+// |vars_found|. Supports level 1 templates as specified in RFC 6570. Returns
+// true if the template was parseable, false if it was malformed.
+QUICHE_EXPORT_PRIVATE bool ExpandURITemplateImpl(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    std::string* target,
+    absl::flat_hash_set<std::string>* vars_found = nullptr);
+
+// Decodes a URL-encoded string and converts it to ASCII. If the decoded input
+// contains non-ASCII characters, decoding fails and absl::nullopt is returned.
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> AsciiUrlDecodeImpl(
+    absl::string_view input);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_