about summary refs log tree commit diff
path: root/third_party/abseil_cpp/absl/flags/internal
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/abseil_cpp/absl/flags/internal')
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/commandlineflag.h68
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/flag.cc568
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/flag.h770
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/parse.h59
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/path_util.h62
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/path_util_test.cc46
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc65
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h61
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/program_name.cc60
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/program_name.h50
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/program_name_test.cc61
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/registry.h89
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/usage.cc391
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/usage.h81
-rw-r--r--third_party/abseil_cpp/absl/flags/internal/usage_test.cc409
15 files changed, 2840 insertions, 0 deletions
diff --git a/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h b/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h
new file mode 100644
index 000000000000..cb46fe2e979d
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h
@@ -0,0 +1,68 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_
+#define ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_
+
+#include "absl/base/config.h"
+#include "absl/base/internal/fast_type_id.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// An alias for flag fast type id. This value identifies the flag value type
+// simialarly to typeid(T), without relying on RTTI being available. In most
+// cases this id is enough to uniquely identify the flag's value type. In a few
+// cases we'll have to resort to using actual RTTI implementation if it is
+// available.
+using FlagFastTypeId = absl::base_internal::FastTypeIdType;
+
+// Options that control SetCommandLineOptionWithMode.
+enum FlagSettingMode {
+  // update the flag's value unconditionally (can call this multiple times).
+  SET_FLAGS_VALUE,
+  // update the flag's value, but *only if* it has not yet been updated
+  // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+  SET_FLAG_IF_DEFAULT,
+  // set the flag's default value to this.  If the flag has not been updated
+  // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+  // change the flag's current value to the new default value as well.
+  SET_FLAGS_DEFAULT
+};
+
+// Options that control ParseFrom: Source of a value.
+enum ValueSource {
+  // Flag is being set by value specified on a command line.
+  kCommandLine,
+  // Flag is being set by value specified in the code.
+  kProgrammaticChange,
+};
+
+// Handle to FlagState objects. Specific flag state objects will restore state
+// of a flag produced this flag state from method CommandLineFlag::SaveState().
+class FlagStateInterface {
+ public:
+  virtual ~FlagStateInterface();
+
+  // Restores the flag originated this object to the saved state.
+  virtual void Restore() const = 0;
+};
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/flag.cc b/third_party/abseil_cpp/absl/flags/internal/flag.cc
new file mode 100644
index 000000000000..1502e7f11d36
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/flag.cc
@@ -0,0 +1,568 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/flag.h"
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <array>
+#include <atomic>
+#include <memory>
+#include <new>
+#include <string>
+#include <typeinfo>
+
+#include "absl/base/call_once.h"
+#include "absl/base/casts.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/flags/config.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/usage_config.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/synchronization/mutex.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// The help message indicating that the commandline flag has been
+// 'stripped'. It will not show up when doing "-help" and its
+// variants. The flag is stripped if ABSL_FLAGS_STRIP_HELP is set to 1
+// before including absl/flags/flag.h
+const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
+
+namespace {
+
+// Currently we only validate flag values for user-defined flag types.
+bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) {
+#define DONT_VALIDATE(T, _) \
+  if (flag_type_id == base_internal::FastTypeId<T>()) return false;
+  ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE)
+#undef DONT_VALIDATE
+
+  return true;
+}
+
+// RAII helper used to temporarily unlock and relock `absl::Mutex`.
+// This is used when we need to ensure that locks are released while
+// invoking user supplied callbacks and then reacquired, since callbacks may
+// need to acquire these locks themselves.
+class MutexRelock {
+ public:
+  explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); }
+  ~MutexRelock() { mu_.Lock(); }
+
+  MutexRelock(const MutexRelock&) = delete;
+  MutexRelock& operator=(const MutexRelock&) = delete;
+
+ private:
+  absl::Mutex& mu_;
+};
+
+}  // namespace
+
+///////////////////////////////////////////////////////////////////////////////
+// Persistent state of the flag data.
+
+class FlagImpl;
+
+class FlagState : public flags_internal::FlagStateInterface {
+ public:
+  template <typename V>
+  FlagState(FlagImpl& flag_impl, const V& v, bool modified,
+            bool on_command_line, int64_t counter)
+      : flag_impl_(flag_impl),
+        value_(v),
+        modified_(modified),
+        on_command_line_(on_command_line),
+        counter_(counter) {}
+
+  ~FlagState() override {
+    if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer)
+      return;
+    flags_internal::Delete(flag_impl_.op_, value_.heap_allocated);
+  }
+
+ private:
+  friend class FlagImpl;
+
+  // Restores the flag to the saved state.
+  void Restore() const override {
+    if (!flag_impl_.RestoreState(*this)) return;
+
+    ABSL_INTERNAL_LOG(INFO,
+                      absl::StrCat("Restore saved value of ", flag_impl_.Name(),
+                                   " to: ", flag_impl_.CurrentValue()));
+  }
+
+  // Flag and saved flag data.
+  FlagImpl& flag_impl_;
+  union SavedValue {
+    explicit SavedValue(void* v) : heap_allocated(v) {}
+    explicit SavedValue(int64_t v) : one_word(v) {}
+    explicit SavedValue(flags_internal::AlignedTwoWords v) : two_words(v) {}
+
+    void* heap_allocated;
+    int64_t one_word;
+    flags_internal::AlignedTwoWords two_words;
+  } value_;
+  bool modified_;
+  bool on_command_line_;
+  int64_t counter_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag implementation, which does not depend on flag value type.
+
+DynValueDeleter::DynValueDeleter(FlagOpFn op_arg) : op(op_arg) {}
+
+void DynValueDeleter::operator()(void* ptr) const {
+  if (op == nullptr) return;
+
+  Delete(op, ptr);
+}
+
+void FlagImpl::Init() {
+  new (&data_guard_) absl::Mutex;
+
+  auto def_kind = static_cast<FlagDefaultKind>(def_kind_);
+
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer:
+      // For this storage kind the default_value_ always points to gen_func
+      // during initialization.
+      assert(def_kind == FlagDefaultKind::kGenFunc);
+      (*default_value_.gen_func)(AlignedBufferValue());
+      break;
+    case FlagValueStorageKind::kOneWordAtomic: {
+      alignas(int64_t) std::array<char, sizeof(int64_t)> buf{};
+      if (def_kind == FlagDefaultKind::kGenFunc) {
+        (*default_value_.gen_func)(buf.data());
+      } else {
+        assert(def_kind != FlagDefaultKind::kDynamicValue);
+        std::memcpy(buf.data(), &default_value_, Sizeof(op_));
+      }
+      OneWordValue().store(absl::bit_cast<int64_t>(buf),
+                           std::memory_order_release);
+      break;
+    }
+    case FlagValueStorageKind::kTwoWordsAtomic: {
+      // For this storage kind the default_value_ always points to gen_func
+      // during initialization.
+      assert(def_kind == FlagDefaultKind::kGenFunc);
+      alignas(AlignedTwoWords) std::array<char, sizeof(AlignedTwoWords)> buf{};
+      (*default_value_.gen_func)(buf.data());
+      auto atomic_value = absl::bit_cast<AlignedTwoWords>(buf);
+      TwoWordsValue().store(atomic_value, std::memory_order_release);
+      break;
+    }
+  }
+}
+
+absl::Mutex* FlagImpl::DataGuard() const {
+  absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init,
+                  const_cast<FlagImpl*>(this));
+
+  // data_guard_ is initialized inside Init.
+  return reinterpret_cast<absl::Mutex*>(&data_guard_);
+}
+
+void FlagImpl::AssertValidType(FlagFastTypeId rhs_type_id,
+                               const std::type_info* (*gen_rtti)()) const {
+  FlagFastTypeId lhs_type_id = flags_internal::FastTypeId(op_);
+
+  // `rhs_type_id` is the fast type id corresponding to the declaration
+  // visibile at the call site. `lhs_type_id` is the fast type id
+  // corresponding to the type specified in flag definition. They must match
+  //  for this operation to be well-defined.
+  if (ABSL_PREDICT_TRUE(lhs_type_id == rhs_type_id)) return;
+
+  const std::type_info* lhs_runtime_type_id =
+      flags_internal::RuntimeTypeId(op_);
+  const std::type_info* rhs_runtime_type_id = (*gen_rtti)();
+
+  if (lhs_runtime_type_id == rhs_runtime_type_id) return;
+
+#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI)
+  if (*lhs_runtime_type_id == *rhs_runtime_type_id) return;
+#endif
+
+  ABSL_INTERNAL_LOG(
+      FATAL, absl::StrCat("Flag '", Name(),
+                          "' is defined as one type and declared as another"));
+}
+
+std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const {
+  void* res = nullptr;
+  switch (DefaultKind()) {
+    case FlagDefaultKind::kDynamicValue:
+      res = flags_internal::Clone(op_, default_value_.dynamic_value);
+      break;
+    case FlagDefaultKind::kGenFunc:
+      res = flags_internal::Alloc(op_);
+      (*default_value_.gen_func)(res);
+      break;
+    default:
+      res = flags_internal::Clone(op_, &default_value_);
+      break;
+  }
+  return {res, DynValueDeleter{op_}};
+}
+
+void FlagImpl::StoreValue(const void* src) {
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer:
+      Copy(op_, src, AlignedBufferValue());
+      break;
+    case FlagValueStorageKind::kOneWordAtomic: {
+      int64_t one_word_val = 0;
+      std::memcpy(&one_word_val, src, Sizeof(op_));
+      OneWordValue().store(one_word_val, std::memory_order_release);
+      break;
+    }
+    case FlagValueStorageKind::kTwoWordsAtomic: {
+      AlignedTwoWords two_words_val{0, 0};
+      std::memcpy(&two_words_val, src, Sizeof(op_));
+      TwoWordsValue().store(two_words_val, std::memory_order_release);
+      break;
+    }
+  }
+
+  modified_ = true;
+  ++counter_;
+  InvokeCallback();
+}
+
+absl::string_view FlagImpl::Name() const { return name_; }
+
+std::string FlagImpl::Filename() const {
+  return flags_internal::GetUsageConfig().normalize_filename(filename_);
+}
+
+std::string FlagImpl::Help() const {
+  return HelpSourceKind() == FlagHelpKind::kLiteral ? help_.literal
+                                                    : help_.gen_func();
+}
+
+FlagFastTypeId FlagImpl::TypeId() const {
+  return flags_internal::FastTypeId(op_);
+}
+
+bool FlagImpl::IsSpecifiedOnCommandLine() const {
+  absl::MutexLock l(DataGuard());
+  return on_command_line_;
+}
+
+std::string FlagImpl::DefaultValue() const {
+  absl::MutexLock l(DataGuard());
+
+  auto obj = MakeInitValue();
+  return flags_internal::Unparse(op_, obj.get());
+}
+
+std::string FlagImpl::CurrentValue() const {
+  auto* guard = DataGuard();  // Make sure flag initialized
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer: {
+      absl::MutexLock l(guard);
+      return flags_internal::Unparse(op_, AlignedBufferValue());
+    }
+    case FlagValueStorageKind::kOneWordAtomic: {
+      const auto one_word_val =
+          absl::bit_cast<std::array<char, sizeof(int64_t)>>(
+              OneWordValue().load(std::memory_order_acquire));
+      return flags_internal::Unparse(op_, one_word_val.data());
+    }
+    case FlagValueStorageKind::kTwoWordsAtomic: {
+      const auto two_words_val =
+          absl::bit_cast<std::array<char, sizeof(AlignedTwoWords)>>(
+              TwoWordsValue().load(std::memory_order_acquire));
+      return flags_internal::Unparse(op_, two_words_val.data());
+    }
+  }
+
+  return "";
+}
+
+void FlagImpl::SetCallback(const FlagCallbackFunc mutation_callback) {
+  absl::MutexLock l(DataGuard());
+
+  if (callback_ == nullptr) {
+    callback_ = new FlagCallback;
+  }
+  callback_->func = mutation_callback;
+
+  InvokeCallback();
+}
+
+void FlagImpl::InvokeCallback() const {
+  if (!callback_) return;
+
+  // Make a copy of the C-style function pointer that we are about to invoke
+  // before we release the lock guarding it.
+  FlagCallbackFunc cb = callback_->func;
+
+  // If the flag has a mutation callback this function invokes it. While the
+  // callback is being invoked the primary flag's mutex is unlocked and it is
+  // re-locked back after call to callback is completed. Callback invocation is
+  // guarded by flag's secondary mutex instead which prevents concurrent
+  // callback invocation. Note that it is possible for other thread to grab the
+  // primary lock and update flag's value at any time during the callback
+  // invocation. This is by design. Callback can get a value of the flag if
+  // necessary, but it might be different from the value initiated the callback
+  // and it also can be different by the time the callback invocation is
+  // completed. Requires that *primary_lock be held in exclusive mode; it may be
+  // released and reacquired by the implementation.
+  MutexRelock relock(*DataGuard());
+  absl::MutexLock lock(&callback_->guard);
+  cb();
+}
+
+std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() {
+  absl::MutexLock l(DataGuard());
+
+  bool modified = modified_;
+  bool on_command_line = on_command_line_;
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer: {
+      return absl::make_unique<FlagState>(
+          *this, flags_internal::Clone(op_, AlignedBufferValue()), modified,
+          on_command_line, counter_);
+    }
+    case FlagValueStorageKind::kOneWordAtomic: {
+      return absl::make_unique<FlagState>(
+          *this, OneWordValue().load(std::memory_order_acquire), modified,
+          on_command_line, counter_);
+    }
+    case FlagValueStorageKind::kTwoWordsAtomic: {
+      return absl::make_unique<FlagState>(
+          *this, TwoWordsValue().load(std::memory_order_acquire), modified,
+          on_command_line, counter_);
+    }
+  }
+  return nullptr;
+}
+
+bool FlagImpl::RestoreState(const FlagState& flag_state) {
+  absl::MutexLock l(DataGuard());
+
+  if (flag_state.counter_ == counter_) {
+    return false;
+  }
+
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer:
+      StoreValue(flag_state.value_.heap_allocated);
+      break;
+    case FlagValueStorageKind::kOneWordAtomic:
+      StoreValue(&flag_state.value_.one_word);
+      break;
+    case FlagValueStorageKind::kTwoWordsAtomic:
+      StoreValue(&flag_state.value_.two_words);
+      break;
+  }
+
+  modified_ = flag_state.modified_;
+  on_command_line_ = flag_state.on_command_line_;
+
+  return true;
+}
+
+template <typename StorageT>
+StorageT* FlagImpl::OffsetValue() const {
+  char* p = reinterpret_cast<char*>(const_cast<FlagImpl*>(this));
+  // The offset is deduced via Flag value type specific op_.
+  size_t offset = flags_internal::ValueOffset(op_);
+
+  return reinterpret_cast<StorageT*>(p + offset);
+}
+
+void* FlagImpl::AlignedBufferValue() const {
+  assert(ValueStorageKind() == FlagValueStorageKind::kAlignedBuffer);
+  return OffsetValue<void>();
+}
+
+std::atomic<int64_t>& FlagImpl::OneWordValue() const {
+  assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic);
+  return OffsetValue<FlagOneWordValue>()->value;
+}
+
+std::atomic<AlignedTwoWords>& FlagImpl::TwoWordsValue() const {
+  assert(ValueStorageKind() == FlagValueStorageKind::kTwoWordsAtomic);
+  return OffsetValue<FlagTwoWordsValue>()->value;
+}
+
+// Attempts to parse supplied `value` string using parsing routine in the `flag`
+// argument. If parsing successful, this function replaces the dst with newly
+// parsed value. In case if any error is encountered in either step, the error
+// message is stored in 'err'
+std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse(
+    absl::string_view value, std::string& err) const {
+  std::unique_ptr<void, DynValueDeleter> tentative_value = MakeInitValue();
+
+  std::string parse_err;
+  if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) {
+    absl::string_view err_sep = parse_err.empty() ? "" : "; ";
+    err = absl::StrCat("Illegal value '", value, "' specified for flag '",
+                       Name(), "'", err_sep, parse_err);
+    return nullptr;
+  }
+
+  return tentative_value;
+}
+
+void FlagImpl::Read(void* dst) const {
+  auto* guard = DataGuard();  // Make sure flag initialized
+  switch (ValueStorageKind()) {
+    case FlagValueStorageKind::kAlignedBuffer: {
+      absl::MutexLock l(guard);
+      flags_internal::CopyConstruct(op_, AlignedBufferValue(), dst);
+      break;
+    }
+    case FlagValueStorageKind::kOneWordAtomic: {
+      const int64_t one_word_val =
+          OneWordValue().load(std::memory_order_acquire);
+      std::memcpy(dst, &one_word_val, Sizeof(op_));
+      break;
+    }
+    case FlagValueStorageKind::kTwoWordsAtomic: {
+      const AlignedTwoWords two_words_val =
+          TwoWordsValue().load(std::memory_order_acquire);
+      std::memcpy(dst, &two_words_val, Sizeof(op_));
+      break;
+    }
+  }
+}
+
+void FlagImpl::Write(const void* src) {
+  absl::MutexLock l(DataGuard());
+
+  if (ShouldValidateFlagValue(flags_internal::FastTypeId(op_))) {
+    std::unique_ptr<void, DynValueDeleter> obj{flags_internal::Clone(op_, src),
+                                               DynValueDeleter{op_}};
+    std::string ignored_error;
+    std::string src_as_str = flags_internal::Unparse(op_, src);
+    if (!flags_internal::Parse(op_, src_as_str, obj.get(), &ignored_error)) {
+      ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(),
+                                            "' to invalid value ", src_as_str));
+    }
+  }
+
+  StoreValue(src);
+}
+
+// Sets the value of the flag based on specified string `value`. If the flag
+// was successfully set to new value, it returns true. Otherwise, sets `err`
+// to indicate the error, leaves the flag unchanged, and returns false. There
+// are three ways to set the flag's value:
+//  * Update the current flag value
+//  * Update the flag's default value
+//  * Update the current flag value if it was never set before
+// The mode is selected based on 'set_mode' parameter.
+bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode,
+                         ValueSource source, std::string& err) {
+  absl::MutexLock l(DataGuard());
+
+  switch (set_mode) {
+    case SET_FLAGS_VALUE: {
+      // set or modify the flag's value
+      auto tentative_value = TryParse(value, err);
+      if (!tentative_value) return false;
+
+      StoreValue(tentative_value.get());
+
+      if (source == kCommandLine) {
+        on_command_line_ = true;
+      }
+      break;
+    }
+    case SET_FLAG_IF_DEFAULT: {
+      // set the flag's value, but only if it hasn't been set by someone else
+      if (modified_) {
+        // TODO(rogeeff): review and fix this semantic. Currently we do not fail
+        // in this case if flag is modified. This is misleading since the flag's
+        // value is not updated even though we return true.
+        // *err = absl::StrCat(Name(), " is already set to ",
+        //                     CurrentValue(), "\n");
+        // return false;
+        return true;
+      }
+      auto tentative_value = TryParse(value, err);
+      if (!tentative_value) return false;
+
+      StoreValue(tentative_value.get());
+      break;
+    }
+    case SET_FLAGS_DEFAULT: {
+      auto tentative_value = TryParse(value, err);
+      if (!tentative_value) return false;
+
+      if (DefaultKind() == FlagDefaultKind::kDynamicValue) {
+        void* old_value = default_value_.dynamic_value;
+        default_value_.dynamic_value = tentative_value.release();
+        tentative_value.reset(old_value);
+      } else {
+        default_value_.dynamic_value = tentative_value.release();
+        def_kind_ = static_cast<uint8_t>(FlagDefaultKind::kDynamicValue);
+      }
+
+      if (!modified_) {
+        // Need to set both default value *and* current, in this case.
+        StoreValue(default_value_.dynamic_value);
+        modified_ = false;
+      }
+      break;
+    }
+  }
+
+  return true;
+}
+
+void FlagImpl::CheckDefaultValueParsingRoundtrip() const {
+  std::string v = DefaultValue();
+
+  absl::MutexLock lock(DataGuard());
+
+  auto dst = MakeInitValue();
+  std::string error;
+  if (!flags_internal::Parse(op_, v, dst.get(), &error)) {
+    ABSL_INTERNAL_LOG(
+        FATAL,
+        absl::StrCat("Flag ", Name(), " (from ", Filename(),
+                     "): string form of default value '", v,
+                     "' could not be parsed; error=", error));
+  }
+
+  // We do not compare dst to def since parsing/unparsing may make
+  // small changes, e.g., precision loss for floating point types.
+}
+
+bool FlagImpl::ValidateInputValue(absl::string_view value) const {
+  absl::MutexLock l(DataGuard());
+
+  auto obj = MakeInitValue();
+  std::string ignored_error;
+  return flags_internal::Parse(op_, value, obj.get(), &ignored_error);
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/third_party/abseil_cpp/absl/flags/internal/flag.h b/third_party/abseil_cpp/absl/flags/internal/flag.h
new file mode 100644
index 000000000000..2cc44e00f762
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/flag.h
@@ -0,0 +1,770 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_FLAG_H_
+#define ABSL_FLAGS_INTERNAL_FLAG_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <atomic>
+#include <cstring>
+#include <memory>
+#include <new>
+#include <string>
+#include <type_traits>
+#include <typeinfo>
+
+#include "absl/base/attributes.h"
+#include "absl/base/call_once.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/config.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/internal/registry.h"
+#include "absl/flags/marshalling.h"
+#include "absl/meta/type_traits.h"
+#include "absl/strings/string_view.h"
+#include "absl/synchronization/mutex.h"
+#include "absl/utility/utility.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+///////////////////////////////////////////////////////////////////////////////
+// Forward declaration of absl::Flag<T> public API.
+namespace flags_internal {
+template <typename T>
+class Flag;
+}  // namespace flags_internal
+
+#if defined(_MSC_VER) && !defined(__clang__)
+template <typename T>
+class Flag;
+#else
+template <typename T>
+using Flag = flags_internal::Flag<T>;
+#endif
+
+template <typename T>
+ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag);
+
+template <typename T>
+void SetFlag(absl::Flag<T>* flag, const T& v);
+
+template <typename T, typename V>
+void SetFlag(absl::Flag<T>* flag, const V& v);
+
+template <typename U>
+const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<U>& f);
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag value type operations, eg., parsing, copying, etc. are provided
+// by function specific to that type with a signature matching FlagOpFn.
+
+namespace flags_internal {
+
+enum class FlagOp {
+  kAlloc,
+  kDelete,
+  kCopy,
+  kCopyConstruct,
+  kSizeof,
+  kFastTypeId,
+  kRuntimeTypeId,
+  kParse,
+  kUnparse,
+  kValueOffset,
+};
+using FlagOpFn = void* (*)(FlagOp, const void*, void*, void*);
+
+// Forward declaration for Flag value specific operations.
+template <typename T>
+void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3);
+
+// Allocate aligned memory for a flag value.
+inline void* Alloc(FlagOpFn op) {
+  return op(FlagOp::kAlloc, nullptr, nullptr, nullptr);
+}
+// Deletes memory interpreting obj as flag value type pointer.
+inline void Delete(FlagOpFn op, void* obj) {
+  op(FlagOp::kDelete, nullptr, obj, nullptr);
+}
+// Copies src to dst interpreting as flag value type pointers.
+inline void Copy(FlagOpFn op, const void* src, void* dst) {
+  op(FlagOp::kCopy, src, dst, nullptr);
+}
+// Construct a copy of flag value in a location pointed by dst
+// based on src - pointer to the flag's value.
+inline void CopyConstruct(FlagOpFn op, const void* src, void* dst) {
+  op(FlagOp::kCopyConstruct, src, dst, nullptr);
+}
+// Makes a copy of flag value pointed by obj.
+inline void* Clone(FlagOpFn op, const void* obj) {
+  void* res = flags_internal::Alloc(op);
+  flags_internal::CopyConstruct(op, obj, res);
+  return res;
+}
+// Returns true if parsing of input text is successfull.
+inline bool Parse(FlagOpFn op, absl::string_view text, void* dst,
+                  std::string* error) {
+  return op(FlagOp::kParse, &text, dst, error) != nullptr;
+}
+// Returns string representing supplied value.
+inline std::string Unparse(FlagOpFn op, const void* val) {
+  std::string result;
+  op(FlagOp::kUnparse, val, &result, nullptr);
+  return result;
+}
+// Returns size of flag value type.
+inline size_t Sizeof(FlagOpFn op) {
+  // This sequence of casts reverses the sequence from
+  // `flags_internal::FlagOps()`
+  return static_cast<size_t>(reinterpret_cast<intptr_t>(
+      op(FlagOp::kSizeof, nullptr, nullptr, nullptr)));
+}
+// Returns fast type id coresponding to the value type.
+inline FlagFastTypeId FastTypeId(FlagOpFn op) {
+  return reinterpret_cast<FlagFastTypeId>(
+      op(FlagOp::kFastTypeId, nullptr, nullptr, nullptr));
+}
+// Returns fast type id coresponding to the value type.
+inline const std::type_info* RuntimeTypeId(FlagOpFn op) {
+  return reinterpret_cast<const std::type_info*>(
+      op(FlagOp::kRuntimeTypeId, nullptr, nullptr, nullptr));
+}
+// Returns offset of the field value_ from the field impl_ inside of
+// absl::Flag<T> data. Given FlagImpl pointer p you can get the
+// location of the corresponding value as:
+//      reinterpret_cast<char*>(p) + ValueOffset().
+inline ptrdiff_t ValueOffset(FlagOpFn op) {
+  // This sequence of casts reverses the sequence from
+  // `flags_internal::FlagOps()`
+  return static_cast<ptrdiff_t>(reinterpret_cast<intptr_t>(
+      op(FlagOp::kValueOffset, nullptr, nullptr, nullptr)));
+}
+
+// Returns an address of RTTI's typeid(T).
+template <typename T>
+inline const std::type_info* GenRuntimeTypeId() {
+#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI)
+  return &typeid(T);
+#else
+  return nullptr;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag help auxiliary structs.
+
+// This is help argument for absl::Flag encapsulating the string literal pointer
+// or pointer to function generating it as well as enum descriminating two
+// cases.
+using HelpGenFunc = std::string (*)();
+
+template <size_t N>
+struct FixedCharArray {
+  char value[N];
+
+  template <size_t... I>
+  static constexpr FixedCharArray<N> FromLiteralString(
+      absl::string_view str, absl::index_sequence<I...>) {
+    return (void)str, FixedCharArray<N>({{str[I]..., '\0'}});
+  }
+};
+
+template <typename Gen, size_t N = Gen::Value().size()>
+constexpr FixedCharArray<N + 1> HelpStringAsArray(int) {
+  return FixedCharArray<N + 1>::FromLiteralString(
+      Gen::Value(), absl::make_index_sequence<N>{});
+}
+
+template <typename Gen>
+constexpr std::false_type HelpStringAsArray(char) {
+  return std::false_type{};
+}
+
+union FlagHelpMsg {
+  constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {}
+  constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {}
+
+  const char* literal;
+  HelpGenFunc gen_func;
+};
+
+enum class FlagHelpKind : uint8_t { kLiteral = 0, kGenFunc = 1 };
+
+struct FlagHelpArg {
+  FlagHelpMsg source;
+  FlagHelpKind kind;
+};
+
+extern const char kStrippedFlagHelp[];
+
+// These two HelpArg overloads allows us to select at compile time one of two
+// way to pass Help argument to absl::Flag. We'll be passing
+// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer
+// first overload if possible. If help message is evaluatable on constexpr
+// context We'll be able to make FixedCharArray out of it and we'll choose first
+// overload. In this case the help message expression is immediately evaluated
+// and is used to construct the absl::Flag. No additionl code is generated by
+// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the
+// consideration, in which case the second overload will be used. The second
+// overload does not attempt to evaluate the help message expression
+// immediately and instead delays the evaluation by returing the function
+// pointer (&T::NonConst) genering the help message when necessary. This is
+// evaluatable in constexpr context, but the cost is an extra function being
+// generated in the ABSL_FLAG code.
+template <typename Gen, size_t N>
+constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) {
+  return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral};
+}
+
+template <typename Gen>
+constexpr FlagHelpArg HelpArg(std::false_type) {
+  return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc};
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag default value auxiliary structs.
+
+// Signature for the function generating the initial flag value (usually
+// based on default value supplied in flag's definition)
+using FlagDfltGenFunc = void (*)(void*);
+
+union FlagDefaultSrc {
+  constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg)
+      : gen_func(gen_func_arg) {}
+
+#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \
+  T name##_value;                                  \
+  constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {}  // NOLINT
+  ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE)
+#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE
+
+  void* dynamic_value;
+  FlagDfltGenFunc gen_func;
+};
+
+enum class FlagDefaultKind : uint8_t {
+  kDynamicValue = 0,
+  kGenFunc = 1,
+  kOneWord = 2  // for default values UP to one word in size
+};
+
+struct FlagDefaultArg {
+  FlagDefaultSrc source;
+  FlagDefaultKind kind;
+};
+
+// This struct and corresponding overload to InitDefaultValue are used to
+// facilitate usage of {} as default value in ABSL_FLAG macro.
+// TODO(rogeeff): Fix handling types with explicit constructors.
+struct EmptyBraces {};
+
+template <typename T>
+constexpr T InitDefaultValue(T t) {
+  return t;
+}
+
+template <typename T>
+constexpr T InitDefaultValue(EmptyBraces) {
+  return T{};
+}
+
+template <typename ValueT, typename GenT,
+          typename std::enable_if<std::is_integral<ValueT>::value, int>::type =
+              (GenT{}, 0)>
+constexpr FlagDefaultArg DefaultArg(int) {
+  return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord};
+}
+
+template <typename ValueT, typename GenT>
+constexpr FlagDefaultArg DefaultArg(char) {
+  return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc};
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag current value auxiliary structs.
+
+constexpr int64_t UninitializedFlagValue() { return 0xababababababababll; }
+
+template <typename T>
+using FlagUseOneWordStorage = std::integral_constant<
+    bool, absl::type_traits_internal::is_trivially_copyable<T>::value &&
+              (sizeof(T) <= 8)>;
+
+#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD)
+// Clang does not always produce cmpxchg16b instruction when alignment of a 16
+// bytes type is not 16.
+struct alignas(16) AlignedTwoWords {
+  int64_t first;
+  int64_t second;
+
+  bool IsInitialized() const {
+    return first != flags_internal::UninitializedFlagValue();
+  }
+};
+
+template <typename T>
+using FlagUseTwoWordsStorage = std::integral_constant<
+    bool, absl::type_traits_internal::is_trivially_copyable<T>::value &&
+              (sizeof(T) > 8) && (sizeof(T) <= 16)>;
+#else
+// This is actually unused and only here to avoid ifdefs in other palces.
+struct AlignedTwoWords {
+  constexpr AlignedTwoWords() noexcept : dummy() {}
+  constexpr AlignedTwoWords(int64_t, int64_t) noexcept : dummy() {}
+  char dummy;
+
+  bool IsInitialized() const {
+    std::abort();
+    return true;
+  }
+};
+
+// This trait should be type dependent, otherwise SFINAE below will fail
+template <typename T>
+using FlagUseTwoWordsStorage =
+    std::integral_constant<bool, sizeof(T) != sizeof(T)>;
+#endif
+
+template <typename T>
+using FlagUseBufferStorage =
+    std::integral_constant<bool, !FlagUseOneWordStorage<T>::value &&
+                                     !FlagUseTwoWordsStorage<T>::value>;
+
+enum class FlagValueStorageKind : uint8_t {
+  kAlignedBuffer = 0,
+  kOneWordAtomic = 1,
+  kTwoWordsAtomic = 2
+};
+
+template <typename T>
+static constexpr FlagValueStorageKind StorageKind() {
+  return FlagUseBufferStorage<T>::value
+             ? FlagValueStorageKind::kAlignedBuffer
+             : FlagUseOneWordStorage<T>::value
+                   ? FlagValueStorageKind::kOneWordAtomic
+                   : FlagValueStorageKind::kTwoWordsAtomic;
+}
+
+struct FlagOneWordValue {
+  constexpr FlagOneWordValue() : value(UninitializedFlagValue()) {}
+
+  std::atomic<int64_t> value;
+};
+
+struct FlagTwoWordsValue {
+  constexpr FlagTwoWordsValue()
+      : value(AlignedTwoWords{UninitializedFlagValue(), 0}) {}
+
+  std::atomic<AlignedTwoWords> value;
+};
+
+template <typename T,
+          FlagValueStorageKind Kind = flags_internal::StorageKind<T>()>
+struct FlagValue;
+
+template <typename T>
+struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> {
+  bool Get(T&) const { return false; }
+
+  alignas(T) char value[sizeof(T)];
+};
+
+template <typename T>
+struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue {
+  bool Get(T& dst) const {
+    int64_t one_word_val = value.load(std::memory_order_acquire);
+    if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) {
+      return false;
+    }
+    std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T));
+    return true;
+  }
+};
+
+template <typename T>
+struct FlagValue<T, FlagValueStorageKind::kTwoWordsAtomic> : FlagTwoWordsValue {
+  bool Get(T& dst) const {
+    AlignedTwoWords two_words_val = value.load(std::memory_order_acquire);
+    if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) {
+      return false;
+    }
+    std::memcpy(&dst, static_cast<const void*>(&two_words_val), sizeof(T));
+    return true;
+  }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag callback auxiliary structs.
+
+// Signature for the mutation callback used by watched Flags
+// The callback is noexcept.
+// TODO(rogeeff): add noexcept after C++17 support is added.
+using FlagCallbackFunc = void (*)();
+
+struct FlagCallback {
+  FlagCallbackFunc func;
+  absl::Mutex guard;  // Guard for concurrent callback invocations.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Flag implementation, which does not depend on flag value type.
+// The class encapsulates the Flag's data and access to it.
+
+struct DynValueDeleter {
+  explicit DynValueDeleter(FlagOpFn op_arg = nullptr);
+  void operator()(void* ptr) const;
+
+  FlagOpFn op;
+};
+
+class FlagState;
+
+class FlagImpl final : public CommandLineFlag {
+ public:
+  constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op,
+                     FlagHelpArg help, FlagValueStorageKind value_kind,
+                     FlagDefaultArg default_arg)
+      : name_(name),
+        filename_(filename),
+        op_(op),
+        help_(help.source),
+        help_source_kind_(static_cast<uint8_t>(help.kind)),
+        value_storage_kind_(static_cast<uint8_t>(value_kind)),
+        def_kind_(static_cast<uint8_t>(default_arg.kind)),
+        modified_(false),
+        on_command_line_(false),
+        counter_(0),
+        callback_(nullptr),
+        default_value_(default_arg.source),
+        data_guard_{} {}
+
+  // Constant access methods
+  void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  // Mutating access methods
+  void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  // Interfaces to operate on callbacks.
+  void SetCallback(const FlagCallbackFunc mutation_callback)
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+  void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
+
+  // Used in read/write operations to validate source/target has correct type.
+  // For example if flag is declared as absl::Flag<int> FLAGS_foo, a call to
+  // absl::GetFlag(FLAGS_foo) validates that the type of FLAGS_foo is indeed
+  // int. To do that we pass the "assumed" type id (which is deduced from type
+  // int) as an argument `type_id`, which is in turn is validated against the
+  // type id stored in flag object by flag definition statement.
+  void AssertValidType(FlagFastTypeId type_id,
+                       const std::type_info* (*gen_rtti)()) const;
+
+ private:
+  template <typename T>
+  friend class Flag;
+  friend class FlagState;
+
+  // Ensures that `data_guard_` is initialized and returns it.
+  absl::Mutex* DataGuard() const ABSL_LOCK_RETURNED((absl::Mutex*)&data_guard_);
+  // Returns heap allocated value of type T initialized with default value.
+  std::unique_ptr<void, DynValueDeleter> MakeInitValue() const
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
+  // Flag initialization called via absl::call_once.
+  void Init();
+
+  // Offset value access methods. One per storage kind. These methods to not
+  // respect const correctness, so be very carefull using them.
+
+  // This is a shared helper routine which encapsulates most of the magic. Since
+  // it is only used inside the three routines below, which are defined in
+  // flag.cc, we can define it in that file as well.
+  template <typename StorageT>
+  StorageT* OffsetValue() const;
+  // This is an accessor for a value stored in an aligned buffer storage.
+  // Returns a mutable pointer to the start of a buffer.
+  void* AlignedBufferValue() const;
+  // This is an accessor for a value stored as one word atomic. Returns a
+  // mutable reference to an atomic value.
+  std::atomic<int64_t>& OneWordValue() const;
+  // This is an accessor for a value stored as two words atomic. Returns a
+  // mutable reference to an atomic value.
+  std::atomic<AlignedTwoWords>& TwoWordsValue() const;
+
+  // Attempts to parse supplied `value` string. If parsing is successful,
+  // returns new value. Otherwise returns nullptr.
+  std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value,
+                                                  std::string& err) const
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
+  // Stores the flag value based on the pointer to the source.
+  void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
+
+  FlagHelpKind HelpSourceKind() const {
+    return static_cast<FlagHelpKind>(help_source_kind_);
+  }
+  FlagValueStorageKind ValueStorageKind() const {
+    return static_cast<FlagValueStorageKind>(value_storage_kind_);
+  }
+  FlagDefaultKind DefaultKind() const
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) {
+    return static_cast<FlagDefaultKind>(def_kind_);
+  }
+
+  // CommandLineFlag interface implementation
+  absl::string_view Name() const override;
+  std::string Filename() const override;
+  std::string Help() const override;
+  FlagFastTypeId TypeId() const override;
+  bool IsSpecifiedOnCommandLine() const override
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+  std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard());
+  std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard());
+  bool ValidateInputValue(absl::string_view value) const override
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+  void CheckDefaultValueParsingRoundtrip() const override
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  // Interfaces to save and restore flags to/from persistent state.
+  // Returns current flag state or nullptr if flag does not support
+  // saving and restoring a state.
+  std::unique_ptr<FlagStateInterface> SaveState() override
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  // Restores the flag state to the supplied state object. If there is
+  // nothing to restore returns false. Otherwise returns true.
+  bool RestoreState(const FlagState& flag_state)
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  bool ParseFrom(absl::string_view value, FlagSettingMode set_mode,
+                 ValueSource source, std::string& error) override
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+
+  // Immutable flag's state.
+
+  // Flags name passed to ABSL_FLAG as second arg.
+  const char* const name_;
+  // The file name where ABSL_FLAG resides.
+  const char* const filename_;
+  // Type-specific operations "vtable".
+  const FlagOpFn op_;
+  // Help message literal or function to generate it.
+  const FlagHelpMsg help_;
+  // Indicates if help message was supplied as literal or generator func.
+  const uint8_t help_source_kind_ : 1;
+  // Kind of storage this flag is using for the flag's value.
+  const uint8_t value_storage_kind_ : 2;
+
+  uint8_t : 0;  // The bytes containing the const bitfields must not be
+                // shared with bytes containing the mutable bitfields.
+
+  // Mutable flag's state (guarded by `data_guard_`).
+
+  // def_kind_ is not guard by DataGuard() since it is accessed in Init without
+  // locks.
+  uint8_t def_kind_ : 2;
+  // Has this flag's value been modified?
+  bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard());
+  // Has this flag been specified on command line.
+  bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard());
+
+  // Unique tag for absl::call_once call to initialize this flag.
+  absl::once_flag init_control_;
+
+  // Mutation counter
+  int64_t counter_ ABSL_GUARDED_BY(*DataGuard());
+  // Optional flag's callback and absl::Mutex to guard the invocations.
+  FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard());
+  // Either a pointer to the function generating the default value based on the
+  // value specified in ABSL_FLAG or pointer to the dynamically set default
+  // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish
+  // these two cases.
+  FlagDefaultSrc default_value_;
+
+  // This is reserved space for an absl::Mutex to guard flag data. It will be
+  // initialized in FlagImpl::Init via placement new.
+  // We can't use "absl::Mutex data_guard_", since this class is not literal.
+  // We do not want to use "absl::Mutex* data_guard_", since this would require
+  // heap allocation during initialization, which is both slows program startup
+  // and can fail. Using reserved space + placement new allows us to avoid both
+  // problems.
+  alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)];
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// The Flag object parameterized by the flag's value type. This class implements
+// flag reflection handle interface.
+
+template <typename T>
+class Flag {
+ public:
+  constexpr Flag(const char* name, const char* filename, FlagHelpArg help,
+                 const FlagDefaultArg default_arg)
+      : impl_(name, filename, &FlagOps<T>, help,
+              flags_internal::StorageKind<T>(), default_arg),
+        value_() {}
+
+  // CommandLineFlag interface
+  absl::string_view Name() const { return impl_.Name(); }
+  std::string Filename() const { return impl_.Filename(); }
+  std::string Help() const { return impl_.Help(); }
+  // Do not use. To be removed.
+  bool IsSpecifiedOnCommandLine() const {
+    return impl_.IsSpecifiedOnCommandLine();
+  }
+  std::string DefaultValue() const { return impl_.DefaultValue(); }
+  std::string CurrentValue() const { return impl_.CurrentValue(); }
+
+ private:
+  template <typename U, bool do_register>
+  friend class FlagRegistrar;
+
+#if !defined(_MSC_VER) || defined(__clang__)
+  template <typename U>
+  friend U absl::GetFlag(const flags_internal::Flag<U>& flag);
+  template <typename U>
+  friend void absl::SetFlag(flags_internal::Flag<U>* flag, const U& v);
+  template <typename U, typename V>
+  friend void absl::SetFlag(flags_internal::Flag<U>* flag, const V& v);
+#else
+  template <typename U>
+  friend class absl::Flag;
+#endif
+
+  T Get() const {
+    // See implementation notes in CommandLineFlag::Get().
+    union U {
+      T value;
+      U() {}
+      ~U() { value.~T(); }
+    };
+    U u;
+
+#if !defined(NDEBUG)
+    impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>);
+#endif
+
+    if (!value_.Get(u.value)) impl_.Read(&u.value);
+    return std::move(u.value);
+  }
+  void Set(const T& v) {
+    impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>);
+    impl_.Write(&v);
+  }
+
+  template <typename U>
+  friend const CommandLineFlag& absl::GetFlagReflectionHandle(
+      const absl::Flag<U>& f);
+
+  // Access to the reflection.
+  const CommandLineFlag& Reflect() const { return impl_; }
+
+  // Flag's data
+  // The implementation depends on value_ field to be placed exactly after the
+  // impl_ field, so that impl_ can figure out the offset to the value and
+  // access it.
+  FlagImpl impl_;
+  FlagValue<T> value_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of Flag value specific operations routine.
+template <typename T>
+void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) {
+  switch (op) {
+    case FlagOp::kAlloc: {
+      std::allocator<T> alloc;
+      return std::allocator_traits<std::allocator<T>>::allocate(alloc, 1);
+    }
+    case FlagOp::kDelete: {
+      T* p = static_cast<T*>(v2);
+      p->~T();
+      std::allocator<T> alloc;
+      std::allocator_traits<std::allocator<T>>::deallocate(alloc, p, 1);
+      return nullptr;
+    }
+    case FlagOp::kCopy:
+      *static_cast<T*>(v2) = *static_cast<const T*>(v1);
+      return nullptr;
+    case FlagOp::kCopyConstruct:
+      new (v2) T(*static_cast<const T*>(v1));
+      return nullptr;
+    case FlagOp::kSizeof:
+      return reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(T)));
+    case FlagOp::kFastTypeId:
+      return const_cast<void*>(base_internal::FastTypeId<T>());
+    case FlagOp::kRuntimeTypeId:
+      return const_cast<std::type_info*>(GenRuntimeTypeId<T>());
+    case FlagOp::kParse: {
+      // Initialize the temporary instance of type T based on current value in
+      // destination (which is going to be flag's default value).
+      T temp(*static_cast<T*>(v2));
+      if (!absl::ParseFlag<T>(*static_cast<const absl::string_view*>(v1), &temp,
+                              static_cast<std::string*>(v3))) {
+        return nullptr;
+      }
+      *static_cast<T*>(v2) = std::move(temp);
+      return v2;
+    }
+    case FlagOp::kUnparse:
+      *static_cast<std::string*>(v2) =
+          absl::UnparseFlag<T>(*static_cast<const T*>(v1));
+      return nullptr;
+    case FlagOp::kValueOffset: {
+      // Round sizeof(FlagImp) to a multiple of alignof(FlagValue<T>) to get the
+      // offset of the data.
+      ptrdiff_t round_to = alignof(FlagValue<T>);
+      ptrdiff_t offset =
+          (sizeof(FlagImpl) + round_to - 1) / round_to * round_to;
+      return reinterpret_cast<void*>(offset);
+    }
+  }
+  return nullptr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This class facilitates Flag object registration and tail expression-based
+// flag definition, for example:
+// ABSL_FLAG(int, foo, 42, "Foo help").OnUpdate(NotifyFooWatcher);
+struct FlagRegistrarEmpty {};
+template <typename T, bool do_register>
+class FlagRegistrar {
+ public:
+  explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) {
+    if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_);
+  }
+
+  FlagRegistrar OnUpdate(FlagCallbackFunc cb) && {
+    flag_.impl_.SetCallback(cb);
+    return *this;
+  }
+
+  // Make the registrar "die" gracefully as an empty struct on a line where
+  // registration happens. Registrar objects are intended to live only as
+  // temporary.
+  operator FlagRegistrarEmpty() const { return {}; }  // NOLINT
+
+ private:
+  Flag<T>& flag_;  // Flag being registered (not owned).
+};
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_FLAG_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/parse.h b/third_party/abseil_cpp/absl/flags/internal/parse.h
new file mode 100644
index 000000000000..de706c898470
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/parse.h
@@ -0,0 +1,59 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_PARSE_H_
+#define ABSL_FLAGS_INTERNAL_PARSE_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/base/config.h"
+#include "absl/flags/declare.h"
+#include "absl/strings/string_view.h"
+
+ABSL_DECLARE_FLAG(std::vector<std::string>, flagfile);
+ABSL_DECLARE_FLAG(std::vector<std::string>, fromenv);
+ABSL_DECLARE_FLAG(std::vector<std::string>, tryfromenv);
+ABSL_DECLARE_FLAG(std::vector<std::string>, undefok);
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+enum class ArgvListAction { kRemoveParsedArgs, kKeepParsedArgs };
+enum class UsageFlagsAction { kHandleUsage, kIgnoreUsage };
+enum class OnUndefinedFlag {
+  kIgnoreUndefined,
+  kReportUndefined,
+  kAbortIfUndefined
+};
+
+std::vector<char*> ParseCommandLineImpl(int argc, char* argv[],
+                                        ArgvListAction arg_list_act,
+                                        UsageFlagsAction usage_flag_act,
+                                        OnUndefinedFlag on_undef_flag);
+
+// --------------------------------------------------------------------
+// Inspect original command line
+
+// Returns true if flag with specified name was either present on the original
+// command line or specified in flag file present on the original command line.
+bool WasPresentOnCommandLine(absl::string_view flag_name);
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_PARSE_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/path_util.h b/third_party/abseil_cpp/absl/flags/internal/path_util.h
new file mode 100644
index 000000000000..a6594d3347e1
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/path_util.h
@@ -0,0 +1,62 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_PATH_UTIL_H_
+#define ABSL_FLAGS_INTERNAL_PATH_UTIL_H_
+
+#include "absl/base/config.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// A portable interface that returns the basename of the filename passed as an
+// argument. It is similar to basename(3)
+// <https://linux.die.net/man/3/basename>.
+// For example:
+//     flags_internal::Basename("a/b/prog/file.cc")
+// returns "file.cc"
+//     flags_internal::Basename("file.cc")
+// returns "file.cc"
+inline absl::string_view Basename(absl::string_view filename) {
+  auto last_slash_pos = filename.find_last_of("/\\");
+
+  return last_slash_pos == absl::string_view::npos
+             ? filename
+             : filename.substr(last_slash_pos + 1);
+}
+
+// A portable interface that returns the directory name of the filename
+// passed as an argument, including the trailing slash.
+// Returns the empty string if a slash is not found in the input file name.
+// For example:
+//      flags_internal::Package("a/b/prog/file.cc")
+// returns "a/b/prog/"
+//      flags_internal::Package("file.cc")
+// returns ""
+inline absl::string_view Package(absl::string_view filename) {
+  auto last_slash_pos = filename.find_last_of("/\\");
+
+  return last_slash_pos == absl::string_view::npos
+             ? absl::string_view()
+             : filename.substr(0, last_slash_pos + 1);
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_PATH_UTIL_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc b/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc
new file mode 100644
index 000000000000..2091373c88ea
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc
@@ -0,0 +1,46 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/path_util.h"
+
+#include "gtest/gtest.h"
+
+namespace {
+
+namespace flags = absl::flags_internal;
+
+TEST(FlagsPathUtilTest, TestBasename) {
+  EXPECT_EQ(flags::Basename(""), "");
+  EXPECT_EQ(flags::Basename("a.cc"), "a.cc");
+  EXPECT_EQ(flags::Basename("dir/a.cc"), "a.cc");
+  EXPECT_EQ(flags::Basename("dir1/dir2/a.cc"), "a.cc");
+  EXPECT_EQ(flags::Basename("../dir1/dir2/a.cc"), "a.cc");
+  EXPECT_EQ(flags::Basename("/dir1/dir2/a.cc"), "a.cc");
+  EXPECT_EQ(flags::Basename("/dir1/dir2/../dir3/a.cc"), "a.cc");
+}
+
+// --------------------------------------------------------------------
+
+TEST(FlagsPathUtilTest, TestPackage) {
+  EXPECT_EQ(flags::Package(""), "");
+  EXPECT_EQ(flags::Package("a.cc"), "");
+  EXPECT_EQ(flags::Package("dir/a.cc"), "dir/");
+  EXPECT_EQ(flags::Package("dir1/dir2/a.cc"), "dir1/dir2/");
+  EXPECT_EQ(flags::Package("../dir1/dir2/a.cc"), "../dir1/dir2/");
+  EXPECT_EQ(flags::Package("/dir1/dir2/a.cc"), "/dir1/dir2/");
+  EXPECT_EQ(flags::Package("/dir1/dir2/../dir3/a.cc"), "/dir1/dir2/../dir3/");
+}
+
+}  // namespace
diff --git a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc
new file mode 100644
index 000000000000..a7eb58b6d45f
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc
@@ -0,0 +1,65 @@
+//
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/private_handle_accessor.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) {
+  return flag.TypeId();
+}
+
+std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState(
+    CommandLineFlag& flag) {
+  return flag.SaveState();
+}
+
+bool PrivateHandleAccessor::IsSpecifiedOnCommandLine(
+    const CommandLineFlag& flag) {
+  return flag.IsSpecifiedOnCommandLine();
+}
+
+bool PrivateHandleAccessor::ValidateInputValue(const CommandLineFlag& flag,
+                                               absl::string_view value) {
+  return flag.ValidateInputValue(value);
+}
+
+void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip(
+    const CommandLineFlag& flag) {
+  flag.CheckDefaultValueParsingRoundtrip();
+}
+
+bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag,
+                                      absl::string_view value,
+                                      flags_internal::FlagSettingMode set_mode,
+                                      flags_internal::ValueSource source,
+                                      std::string& error) {
+  return flag.ParseFrom(value, set_mode, source, error);
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
diff --git a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h
new file mode 100644
index 000000000000..c64435cd6199
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h
@@ -0,0 +1,61 @@
+//
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_
+#define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// This class serves as a trampoline to access private methods of
+// CommandLineFlag. This class is intended for use exclusively internally inside
+// of the Abseil Flags implementation.
+class PrivateHandleAccessor {
+ public:
+  // Access to CommandLineFlag::TypeId.
+  static FlagFastTypeId TypeId(const CommandLineFlag& flag);
+
+  // Access to CommandLineFlag::SaveState.
+  static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag);
+
+  // Access to CommandLineFlag::IsSpecifiedOnCommandLine.
+  static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag);
+
+  // Access to CommandLineFlag::ValidateInputValue.
+  static bool ValidateInputValue(const CommandLineFlag& flag,
+                                 absl::string_view value);
+
+  // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip.
+  static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag);
+
+  static bool ParseFrom(CommandLineFlag& flag, absl::string_view value,
+                        flags_internal::FlagSettingMode set_mode,
+                        flags_internal::ValueSource source, std::string& error);
+};
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name.cc b/third_party/abseil_cpp/absl/flags/internal/program_name.cc
new file mode 100644
index 000000000000..51d698da8b31
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/program_name.cc
@@ -0,0 +1,60 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/program_name.h"
+
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/const_init.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/flags/internal/path_util.h"
+#include "absl/strings/string_view.h"
+#include "absl/synchronization/mutex.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit);
+ABSL_CONST_INIT static std::string* program_name
+    ABSL_GUARDED_BY(program_name_guard) = nullptr;
+
+std::string ProgramInvocationName() {
+  absl::MutexLock l(&program_name_guard);
+
+  return program_name ? *program_name : "UNKNOWN";
+}
+
+std::string ShortProgramInvocationName() {
+  absl::MutexLock l(&program_name_guard);
+
+  return program_name ? std::string(flags_internal::Basename(*program_name))
+                      : "UNKNOWN";
+}
+
+void SetProgramInvocationName(absl::string_view prog_name_str) {
+  absl::MutexLock l(&program_name_guard);
+
+  if (!program_name)
+    program_name = new std::string(prog_name_str);
+  else
+    program_name->assign(prog_name_str.data(), prog_name_str.size());
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name.h b/third_party/abseil_cpp/absl/flags/internal/program_name.h
new file mode 100644
index 000000000000..b99b94fe18ab
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/program_name.h
@@ -0,0 +1,50 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_
+#define ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_
+
+#include <string>
+
+#include "absl/base/config.h"
+#include "absl/strings/string_view.h"
+
+// --------------------------------------------------------------------
+// Program name
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// Returns program invocation name or "UNKNOWN" if `SetProgramInvocationName()`
+// is never called. At the moment this is always set to argv[0] as part of
+// library initialization.
+std::string ProgramInvocationName();
+
+// Returns base name for program invocation name. For example, if
+//   ProgramInvocationName() == "a/b/mybinary"
+// then
+//   ShortProgramInvocationName() == "mybinary"
+std::string ShortProgramInvocationName();
+
+// Sets program invocation name to a new value. Should only be called once
+// during program initialization, before any threads are spawned.
+void SetProgramInvocationName(absl::string_view prog_name_str);
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc b/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc
new file mode 100644
index 000000000000..aff9f6315e4e
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc
@@ -0,0 +1,61 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/program_name.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+
+namespace {
+
+namespace flags = absl::flags_internal;
+
+TEST(FlagsPathUtilTest, TestProgamNameInterfaces) {
+  flags::SetProgramInvocationName("absl/flags/program_name_test");
+  std::string program_name = flags::ProgramInvocationName();
+  for (char& c : program_name)
+    if (c == '\\') c = '/';
+
+#if !defined(__wasm__) && !defined(__asmjs__)
+  const std::string expect_name = "absl/flags/program_name_test";
+  const std::string expect_basename = "program_name_test";
+#else
+  // For targets that generate javascript or webassembly the invocation name
+  // has the special value below.
+  const std::string expect_name = "this.program";
+  const std::string expect_basename = "this.program";
+#endif
+
+  EXPECT_TRUE(absl::EndsWith(program_name, expect_name)) << program_name;
+  EXPECT_EQ(flags::ShortProgramInvocationName(), expect_basename);
+
+  flags::SetProgramInvocationName("a/my_test");
+
+  EXPECT_EQ(flags::ProgramInvocationName(), "a/my_test");
+  EXPECT_EQ(flags::ShortProgramInvocationName(), "my_test");
+
+  absl::string_view not_null_terminated("absl/aaa/bbb");
+  not_null_terminated = not_null_terminated.substr(1, 10);
+
+  flags::SetProgramInvocationName(not_null_terminated);
+
+  EXPECT_EQ(flags::ProgramInvocationName(), "bsl/aaa/bb");
+  EXPECT_EQ(flags::ShortProgramInvocationName(), "bb");
+}
+
+}  // namespace
diff --git a/third_party/abseil_cpp/absl/flags/internal/registry.h b/third_party/abseil_cpp/absl/flags/internal/registry.h
new file mode 100644
index 000000000000..6f5006a016fd
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/registry.h
@@ -0,0 +1,89 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_REGISTRY_H_
+#define ABSL_FLAGS_INTERNAL_REGISTRY_H_
+
+#include <functional>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/strings/string_view.h"
+
+// --------------------------------------------------------------------
+// Global flags registry API.
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// Executes specified visitor for each non-retired flag in the registry.
+// Requires the caller hold the registry lock.
+void ForEachFlagUnlocked(std::function<void(CommandLineFlag&)> visitor);
+// Executes specified visitor for each non-retired flag in the registry. While
+// callback are executed, the registry is locked and can't be changed.
+void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
+
+//-----------------------------------------------------------------------------
+
+bool RegisterCommandLineFlag(CommandLineFlag&);
+
+//-----------------------------------------------------------------------------
+// Retired registrations:
+//
+// Retired flag registrations are treated specially. A 'retired' flag is
+// provided only for compatibility with automated invocations that still
+// name it.  A 'retired' flag:
+//   - is not bound to a C++ FLAGS_ reference.
+//   - has a type and a value, but that value is intentionally inaccessible.
+//   - does not appear in --help messages.
+//   - is fully supported by _all_ flag parsing routines.
+//   - consumes args normally, and complains about type mismatches in its
+//     argument.
+//   - emits a complaint but does not die (e.g. LOG(ERROR)) if it is
+//     accessed by name through the flags API for parsing or otherwise.
+//
+// The registrations for a flag happen in an unspecified order as the
+// initializers for the namespace-scope objects of a program are run.
+// Any number of weak registrations for a flag can weakly define the flag.
+// One non-weak registration will upgrade the flag from weak to non-weak.
+// Further weak registrations of a non-weak flag are ignored.
+//
+// This mechanism is designed to support moving dead flags into a
+// 'graveyard' library.  An example migration:
+//
+//   0: Remove references to this FLAGS_flagname in the C++ codebase.
+//   1: Register as 'retired' in old_lib.
+//   2: Make old_lib depend on graveyard.
+//   3: Add a redundant 'retired' registration to graveyard.
+//   4: Remove the old_lib 'retired' registration.
+//   5: Eventually delete the graveyard registration entirely.
+//
+
+// Retire flag with name "name" and type indicated by ops.
+bool Retire(const char* name, FlagFastTypeId type_id);
+
+// Registered a retired flag with name 'flag_name' and type 'T'.
+template <typename T>
+inline bool RetiredFlag(const char* flag_name) {
+  return flags_internal::Retire(flag_name, base_internal::FastTypeId<T>());
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_INTERNAL_REGISTRY_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/usage.cc b/third_party/abseil_cpp/absl/flags/internal/usage.cc
new file mode 100644
index 000000000000..35b6427b6c83
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/usage.cc
@@ -0,0 +1,391 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/usage.h"
+
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/internal/flag.h"
+#include "absl/flags/internal/path_util.h"
+#include "absl/flags/internal/private_handle_accessor.h"
+#include "absl/flags/internal/program_name.h"
+#include "absl/flags/internal/registry.h"
+#include "absl/flags/usage_config.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+
+ABSL_FLAG(bool, help, false,
+          "show help on important flags for this binary [tip: all flags can "
+          "have two dashes]");
+ABSL_FLAG(bool, helpfull, false, "show help on all flags");
+ABSL_FLAG(bool, helpshort, false,
+          "show help on only the main module for this program");
+ABSL_FLAG(bool, helppackage, false,
+          "show help on all modules in the main package");
+ABSL_FLAG(bool, version, false, "show version and build info and exit");
+ABSL_FLAG(bool, only_check_args, false, "exit after checking all flags");
+ABSL_FLAG(std::string, helpon, "",
+          "show help on the modules named by this flag value");
+ABSL_FLAG(std::string, helpmatch, "",
+          "show help on modules whose name contains the specified substr");
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+namespace {
+
+// This class is used to emit an XML element with `tag` and `text`.
+// It adds opening and closing tags and escapes special characters in the text.
+// For example:
+// std::cout << XMLElement("title", "Milk & Cookies");
+// prints "<title>Milk &amp; Cookies</title>"
+class XMLElement {
+ public:
+  XMLElement(absl::string_view tag, absl::string_view txt)
+      : tag_(tag), txt_(txt) {}
+
+  friend std::ostream& operator<<(std::ostream& out,
+                                  const XMLElement& xml_elem) {
+    out << "<" << xml_elem.tag_ << ">";
+
+    for (auto c : xml_elem.txt_) {
+      switch (c) {
+        case '"':
+          out << "&quot;";
+          break;
+        case '\'':
+          out << "&apos;";
+          break;
+        case '&':
+          out << "&amp;";
+          break;
+        case '<':
+          out << "&lt;";
+          break;
+        case '>':
+          out << "&gt;";
+          break;
+        default:
+          out << c;
+          break;
+      }
+    }
+
+    return out << "</" << xml_elem.tag_ << ">";
+  }
+
+ private:
+  absl::string_view tag_;
+  absl::string_view txt_;
+};
+
+// --------------------------------------------------------------------
+// Helper class to pretty-print info about a flag.
+
+class FlagHelpPrettyPrinter {
+ public:
+  // Pretty printer holds on to the std::ostream& reference to direct an output
+  // to that stream.
+  FlagHelpPrettyPrinter(int max_line_len, std::ostream& out)
+      : out_(out),
+        max_line_len_(max_line_len),
+        line_len_(0),
+        first_line_(true) {}
+
+  void Write(absl::string_view str, bool wrap_line = false) {
+    // Empty string - do nothing.
+    if (str.empty()) return;
+
+    std::vector<absl::string_view> tokens;
+    if (wrap_line) {
+      for (auto line : absl::StrSplit(str, absl::ByAnyChar("\n\r"))) {
+        if (!tokens.empty()) {
+          // Keep line separators in the input string.
+          tokens.push_back("\n");
+        }
+        for (auto token :
+             absl::StrSplit(line, absl::ByAnyChar(" \t"), absl::SkipEmpty())) {
+          tokens.push_back(token);
+        }
+      }
+    } else {
+      tokens.push_back(str);
+    }
+
+    for (auto token : tokens) {
+      bool new_line = (line_len_ == 0);
+
+      // Respect line separators in the input string.
+      if (token == "\n") {
+        EndLine();
+        continue;
+      }
+
+      // Write the token, ending the string first if necessary/possible.
+      if (!new_line && (line_len_ + token.size() >= max_line_len_)) {
+        EndLine();
+        new_line = true;
+      }
+
+      if (new_line) {
+        StartLine();
+      } else {
+        out_ << ' ';
+        ++line_len_;
+      }
+
+      out_ << token;
+      line_len_ += token.size();
+    }
+  }
+
+  void StartLine() {
+    if (first_line_) {
+      out_ << "    ";
+      line_len_ = 4;
+      first_line_ = false;
+    } else {
+      out_ << "      ";
+      line_len_ = 6;
+    }
+  }
+  void EndLine() {
+    out_ << '\n';
+    line_len_ = 0;
+  }
+
+ private:
+  std::ostream& out_;
+  const int max_line_len_;
+  int line_len_;
+  bool first_line_;
+};
+
+void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) {
+  FlagHelpPrettyPrinter printer(80, out);  // Max line length is 80.
+
+  // Flag name.
+  printer.Write(absl::StrCat("--", flag.Name()));
+
+  // Flag help.
+  printer.Write(absl::StrCat("(", flag.Help(), ");"), /*wrap_line=*/true);
+
+  // The listed default value will be the actual default from the flag
+  // definition in the originating source file, unless the value has
+  // subsequently been modified using SetCommandLineOption() with mode
+  // SET_FLAGS_DEFAULT.
+  std::string dflt_val = flag.DefaultValue();
+  std::string curr_val = flag.CurrentValue();
+  bool is_modified = curr_val != dflt_val;
+
+  if (flag.IsOfType<std::string>()) {
+    dflt_val = absl::StrCat("\"", dflt_val, "\"");
+  }
+  printer.Write(absl::StrCat("default: ", dflt_val, ";"));
+
+  if (is_modified) {
+    if (flag.IsOfType<std::string>()) {
+      curr_val = absl::StrCat("\"", curr_val, "\"");
+    }
+    printer.Write(absl::StrCat("currently: ", curr_val, ";"));
+  }
+
+  printer.EndLine();
+}
+
+// Shows help for every filename which matches any of the filters
+// If filters are empty, shows help for every file.
+// If a flag's help message has been stripped (e.g. by adding '#define
+// STRIP_FLAG_HELP 1' then this flag will not be displayed by '--help'
+// and its variants.
+void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb,
+                   HelpFormat format, absl::string_view program_usage_message) {
+  if (format == HelpFormat::kHumanReadable) {
+    out << flags_internal::ShortProgramInvocationName() << ": "
+        << program_usage_message << "\n\n";
+  } else {
+    // XML schema is not a part of our public API for now.
+    out << "<?xml version=\"1.0\"?>\n"
+        << "<!-- This output should be used with care. We do not report type "
+           "names for flags with user defined types -->\n"
+        << "<!-- Prefer flag only_check_args for validating flag inputs -->\n"
+        // The document.
+        << "<AllFlags>\n"
+        // The program name and usage.
+        << XMLElement("program", flags_internal::ShortProgramInvocationName())
+        << '\n'
+        << XMLElement("usage", program_usage_message) << '\n';
+  }
+
+  // Map of package name to
+  //   map of file name to
+  //     vector of flags in the file.
+  // This map is used to output matching flags grouped by package and file
+  // name.
+  std::map<std::string,
+           std::map<std::string, std::vector<const absl::CommandLineFlag*>>>
+      matching_flags;
+
+  flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) {
+    std::string flag_filename = flag.Filename();
+
+    // Ignore retired flags.
+    if (flag.IsRetired()) return;
+
+    // If the flag has been stripped, pretend that it doesn't exist.
+    if (flag.Help() == flags_internal::kStrippedFlagHelp) return;
+
+    // Make sure flag satisfies the filter
+    if (!filter_cb || !filter_cb(flag_filename)) return;
+
+    matching_flags[std::string(flags_internal::Package(flag_filename))]
+                  [flag_filename]
+                      .push_back(&flag);
+  });
+
+  absl::string_view package_separator;  // controls blank lines between packages
+  absl::string_view file_separator;     // controls blank lines between files
+  for (const auto& package : matching_flags) {
+    if (format == HelpFormat::kHumanReadable) {
+      out << package_separator;
+      package_separator = "\n\n";
+    }
+
+    file_separator = "";
+    for (const auto& flags_in_file : package.second) {
+      if (format == HelpFormat::kHumanReadable) {
+        out << file_separator << "  Flags from " << flags_in_file.first
+            << ":\n";
+        file_separator = "\n";
+      }
+
+      for (const auto* flag : flags_in_file.second) {
+        flags_internal::FlagHelp(out, *flag, format);
+      }
+    }
+  }
+
+  if (format == HelpFormat::kHumanReadable) {
+    if (filter_cb && matching_flags.empty()) {
+      out << "  No modules matched: use -helpfull\n";
+    }
+  } else {
+    // The end of the document.
+    out << "</AllFlags>\n";
+  }
+}
+
+}  // namespace
+
+// --------------------------------------------------------------------
+// Produces the help message describing specific flag.
+void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
+              HelpFormat format) {
+  if (format == HelpFormat::kHumanReadable)
+    flags_internal::FlagHelpHumanReadable(flag, out);
+}
+
+// --------------------------------------------------------------------
+// Produces the help messages for all flags matching the filter.
+// If filter is empty produces help messages for all flags.
+void FlagsHelp(std::ostream& out, absl::string_view filter, HelpFormat format,
+               absl::string_view program_usage_message) {
+  flags_internal::FlagKindFilter filter_cb = [&](absl::string_view filename) {
+    return filter.empty() || filename.find(filter) != absl::string_view::npos;
+  };
+  flags_internal::FlagsHelpImpl(out, filter_cb, format, program_usage_message);
+}
+
+// --------------------------------------------------------------------
+// Checks all the 'usage' command line flags to see if any have been set.
+// If so, handles them appropriately.
+int HandleUsageFlags(std::ostream& out,
+                     absl::string_view program_usage_message) {
+  if (absl::GetFlag(FLAGS_helpshort)) {
+    flags_internal::FlagsHelpImpl(
+        out, flags_internal::GetUsageConfig().contains_helpshort_flags,
+        HelpFormat::kHumanReadable, program_usage_message);
+    return 1;
+  }
+
+  if (absl::GetFlag(FLAGS_helpfull)) {
+    // show all options
+    flags_internal::FlagsHelp(out, "", HelpFormat::kHumanReadable,
+                              program_usage_message);
+    return 1;
+  }
+
+  if (!absl::GetFlag(FLAGS_helpon).empty()) {
+    flags_internal::FlagsHelp(
+        out, absl::StrCat("/", absl::GetFlag(FLAGS_helpon), "."),
+        HelpFormat::kHumanReadable, program_usage_message);
+    return 1;
+  }
+
+  if (!absl::GetFlag(FLAGS_helpmatch).empty()) {
+    flags_internal::FlagsHelp(out, absl::GetFlag(FLAGS_helpmatch),
+                              HelpFormat::kHumanReadable,
+                              program_usage_message);
+    return 1;
+  }
+
+  if (absl::GetFlag(FLAGS_help)) {
+    flags_internal::FlagsHelpImpl(
+        out, flags_internal::GetUsageConfig().contains_help_flags,
+        HelpFormat::kHumanReadable, program_usage_message);
+
+    out << "\nTry --helpfull to get a list of all flags.\n";
+
+    return 1;
+  }
+
+  if (absl::GetFlag(FLAGS_helppackage)) {
+    flags_internal::FlagsHelpImpl(
+        out, flags_internal::GetUsageConfig().contains_helppackage_flags,
+        HelpFormat::kHumanReadable, program_usage_message);
+
+    out << "\nTry --helpfull to get a list of all flags.\n";
+
+    return 1;
+  }
+
+  if (absl::GetFlag(FLAGS_version)) {
+    if (flags_internal::GetUsageConfig().version_string)
+      out << flags_internal::GetUsageConfig().version_string();
+    // Unlike help, we may be asking for version in a script, so return 0
+    return 0;
+  }
+
+  if (absl::GetFlag(FLAGS_only_check_args)) {
+    return 0;
+  }
+
+  return -1;
+}
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/third_party/abseil_cpp/absl/flags/internal/usage.h b/third_party/abseil_cpp/absl/flags/internal/usage.h
new file mode 100644
index 000000000000..0c62dc4b2ac6
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/usage.h
@@ -0,0 +1,81 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_FLAGS_INTERNAL_USAGE_H_
+#define ABSL_FLAGS_INTERNAL_USAGE_H_
+
+#include <iosfwd>
+#include <string>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/declare.h"
+#include "absl/strings/string_view.h"
+
+// --------------------------------------------------------------------
+// Usage reporting interfaces
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+
+// The format to report the help messages in.
+enum class HelpFormat {
+  kHumanReadable,
+};
+
+// Outputs the help message describing specific flag.
+void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
+              HelpFormat format = HelpFormat::kHumanReadable);
+
+// Produces the help messages for all flags matching the filter. A flag matches
+// the filter if it is defined in a file with a filename which includes
+// filter string as a substring. You can use '/' and '.' to restrict the
+// matching to a specific file names. For example:
+//   FlagsHelp(out, "/path/to/file.");
+// restricts help to only flags which resides in files named like:
+//  .../path/to/file.<ext>
+// for any extension 'ext'. If the filter is empty this function produces help
+// messages for all flags.
+void FlagsHelp(std::ostream& out, absl::string_view filter,
+               HelpFormat format, absl::string_view program_usage_message);
+
+// --------------------------------------------------------------------
+
+// If any of the 'usage' related command line flags (listed on the bottom of
+// this file) has been set this routine produces corresponding help message in
+// the specified output stream and returns:
+//  0 - if "version" or "only_check_flags" flags were set and handled.
+//  1 - if some other 'usage' related flag was set and handled.
+// -1 - if no usage flags were set on a commmand line.
+// Non negative return values are expected to be used as an exit code for a
+// binary.
+int HandleUsageFlags(std::ostream& out,
+                     absl::string_view program_usage_message);
+
+}  // namespace flags_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+ABSL_DECLARE_FLAG(bool, help);
+ABSL_DECLARE_FLAG(bool, helpfull);
+ABSL_DECLARE_FLAG(bool, helpshort);
+ABSL_DECLARE_FLAG(bool, helppackage);
+ABSL_DECLARE_FLAG(bool, version);
+ABSL_DECLARE_FLAG(bool, only_check_args);
+ABSL_DECLARE_FLAG(std::string, helpon);
+ABSL_DECLARE_FLAG(std::string, helpmatch);
+
+#endif  // ABSL_FLAGS_INTERNAL_USAGE_H_
diff --git a/third_party/abseil_cpp/absl/flags/internal/usage_test.cc b/third_party/abseil_cpp/absl/flags/internal/usage_test.cc
new file mode 100644
index 000000000000..6e583fbe4b0e
--- /dev/null
+++ b/third_party/abseil_cpp/absl/flags/internal/usage_test.cc
@@ -0,0 +1,409 @@
+//
+//  Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/internal/usage.h"
+
+#include <stdint.h>
+
+#include <sstream>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/internal/parse.h"
+#include "absl/flags/internal/path_util.h"
+#include "absl/flags/internal/program_name.h"
+#include "absl/flags/reflection.h"
+#include "absl/flags/usage.h"
+#include "absl/flags/usage_config.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+
+ABSL_FLAG(int, usage_reporting_test_flag_01, 101,
+          "usage_reporting_test_flag_01 help message");
+ABSL_FLAG(bool, usage_reporting_test_flag_02, false,
+          "usage_reporting_test_flag_02 help message");
+ABSL_FLAG(double, usage_reporting_test_flag_03, 1.03,
+          "usage_reporting_test_flag_03 help message");
+ABSL_FLAG(int64_t, usage_reporting_test_flag_04, 1000000000000004L,
+          "usage_reporting_test_flag_04 help message");
+
+static const char kTestUsageMessage[] = "Custom usage message";
+
+struct UDT {
+  UDT() = default;
+  UDT(const UDT&) = default;
+};
+bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
+std::string AbslUnparseFlag(const UDT&) { return "UDT{}"; }
+
+ABSL_FLAG(UDT, usage_reporting_test_flag_05, {},
+          "usage_reporting_test_flag_05 help message");
+
+ABSL_FLAG(
+    std::string, usage_reporting_test_flag_06, {},
+    "usage_reporting_test_flag_06 help message.\n"
+    "\n"
+    "Some more help.\n"
+    "Even more long long long long long long long long long long long long "
+    "help message.");
+
+namespace {
+
+namespace flags = absl::flags_internal;
+
+static std::string NormalizeFileName(absl::string_view fname) {
+#ifdef _WIN32
+  std::string normalized(fname);
+  std::replace(normalized.begin(), normalized.end(), '\\', '/');
+  fname = normalized;
+#endif
+
+  auto absl_pos = fname.rfind("absl/");
+  if (absl_pos != absl::string_view::npos) {
+    fname = fname.substr(absl_pos);
+  }
+  return std::string(fname);
+}
+
+class UsageReportingTest : public testing::Test {
+ protected:
+  UsageReportingTest() {
+    // Install default config for the use on this unit test.
+    // Binary may install a custom config before tests are run.
+    absl::FlagsUsageConfig default_config;
+    default_config.normalize_filename = &NormalizeFileName;
+    absl::SetFlagsUsageConfig(default_config);
+  }
+
+ private:
+  absl::FlagSaver flag_saver_;
+};
+
+// --------------------------------------------------------------------
+
+using UsageReportingDeathTest = UsageReportingTest;
+
+TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) {
+  EXPECT_EQ(absl::ProgramUsageMessage(), kTestUsageMessage);
+
+#ifndef _WIN32
+  // TODO(rogeeff): figure out why this does not work on Windows.
+  EXPECT_DEATH_IF_SUPPORTED(
+      absl::SetProgramUsageMessage("custom usage message"),
+      ".*SetProgramUsageMessage\\(\\) called twice.*");
+#endif
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01");
+  std::stringstream test_buf;
+
+  flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
+  EXPECT_EQ(
+      test_buf.str(),
+      R"(    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+)");
+}
+
+TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02");
+  std::stringstream test_buf;
+
+  flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
+  EXPECT_EQ(
+      test_buf.str(),
+      R"(    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+)");
+}
+
+TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03");
+  std::stringstream test_buf;
+
+  flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
+  EXPECT_EQ(
+      test_buf.str(),
+      R"(    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+)");
+}
+
+TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04");
+  std::stringstream test_buf;
+
+  flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
+  EXPECT_EQ(
+      test_buf.str(),
+      R"(    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+)");
+}
+
+TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) {
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05");
+  std::stringstream test_buf;
+
+  flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
+  EXPECT_EQ(
+      test_buf.str(),
+      R"(    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+)");
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestFlagsHelpHRF) {
+  std::string usage_test_flags_out =
+      R"(usage_test: Custom usage message
+
+  Flags from absl/flags/internal/usage_test.cc:
+    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+    --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
+
+      Some more help.
+      Even more long long long long long long long long long long long long help
+      message.); default: "";
+)";
+
+  std::stringstream test_buf_01;
+  flags::FlagsHelp(test_buf_01, "usage_test.cc",
+                   flags::HelpFormat::kHumanReadable, kTestUsageMessage);
+  EXPECT_EQ(test_buf_01.str(), usage_test_flags_out);
+
+  std::stringstream test_buf_02;
+  flags::FlagsHelp(test_buf_02, "flags/internal/usage_test.cc",
+                   flags::HelpFormat::kHumanReadable, kTestUsageMessage);
+  EXPECT_EQ(test_buf_02.str(), usage_test_flags_out);
+
+  std::stringstream test_buf_03;
+  flags::FlagsHelp(test_buf_03, "usage_test", flags::HelpFormat::kHumanReadable,
+                   kTestUsageMessage);
+  EXPECT_EQ(test_buf_03.str(), usage_test_flags_out);
+
+  std::stringstream test_buf_04;
+  flags::FlagsHelp(test_buf_04, "flags/invalid_file_name.cc",
+                   flags::HelpFormat::kHumanReadable, kTestUsageMessage);
+  EXPECT_EQ(test_buf_04.str(),
+            R"(usage_test: Custom usage message
+
+  No modules matched: use -helpfull
+)");
+
+  std::stringstream test_buf_05;
+  flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable,
+                   kTestUsageMessage);
+  std::string test_out = test_buf_05.str();
+  absl::string_view test_out_str(test_out);
+  EXPECT_TRUE(
+      absl::StartsWith(test_out_str, "usage_test: Custom usage message"));
+  EXPECT_TRUE(absl::StrContains(
+      test_out_str, "Flags from absl/flags/internal/usage_test.cc:"));
+  EXPECT_TRUE(absl::StrContains(test_out_str,
+                                "Flags from absl/flags/internal/usage.cc:"));
+  EXPECT_TRUE(
+      absl::StrContains(test_out_str, "-usage_reporting_test_flag_01 "));
+  EXPECT_TRUE(absl::StrContains(test_out_str, "-help (show help"))
+      << test_out_str;
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestNoUsageFlags) {
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), -1);
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_helpshort) {
+  absl::SetFlag(&FLAGS_helpshort, true);
+
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
+  EXPECT_EQ(test_buf.str(),
+            R"(usage_test: Custom usage message
+
+  Flags from absl/flags/internal/usage_test.cc:
+    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+    --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
+
+      Some more help.
+      Even more long long long long long long long long long long long long help
+      message.); default: "";
+)");
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_help) {
+  absl::SetFlag(&FLAGS_help, true);
+
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
+  EXPECT_EQ(test_buf.str(),
+            R"(usage_test: Custom usage message
+
+  Flags from absl/flags/internal/usage_test.cc:
+    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+    --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
+
+      Some more help.
+      Even more long long long long long long long long long long long long help
+      message.); default: "";
+
+Try --helpfull to get a list of all flags.
+)");
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_helppackage) {
+  absl::SetFlag(&FLAGS_helppackage, true);
+
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
+  EXPECT_EQ(test_buf.str(),
+            R"(usage_test: Custom usage message
+
+  Flags from absl/flags/internal/usage_test.cc:
+    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+    --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
+
+      Some more help.
+      Even more long long long long long long long long long long long long help
+      message.); default: "";
+
+Try --helpfull to get a list of all flags.
+)");
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_version) {
+  absl::SetFlag(&FLAGS_version, true);
+
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0);
+#ifndef NDEBUG
+  EXPECT_EQ(test_buf.str(), "usage_test\nDebug build (NDEBUG not #defined)\n");
+#else
+  EXPECT_EQ(test_buf.str(), "usage_test\n");
+#endif
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_only_check_args) {
+  absl::SetFlag(&FLAGS_only_check_args, true);
+
+  std::stringstream test_buf;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0);
+  EXPECT_EQ(test_buf.str(), "");
+}
+
+// --------------------------------------------------------------------
+
+TEST_F(UsageReportingTest, TestUsageFlag_helpon) {
+  absl::SetFlag(&FLAGS_helpon, "bla-bla");
+
+  std::stringstream test_buf_01;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf_01, kTestUsageMessage), 1);
+  EXPECT_EQ(test_buf_01.str(),
+            R"(usage_test: Custom usage message
+
+  No modules matched: use -helpfull
+)");
+
+  absl::SetFlag(&FLAGS_helpon, "usage_test");
+
+  std::stringstream test_buf_02;
+  EXPECT_EQ(flags::HandleUsageFlags(test_buf_02, kTestUsageMessage), 1);
+  EXPECT_EQ(test_buf_02.str(),
+            R"(usage_test: Custom usage message
+
+  Flags from absl/flags/internal/usage_test.cc:
+    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
+      default: 101;
+    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
+      default: false;
+    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
+      default: 1.03;
+    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
+      default: 1000000000000004;
+    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
+      default: UDT{};
+    --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
+
+      Some more help.
+      Even more long long long long long long long long long long long long help
+      message.); default: "";
+)");
+}
+
+// --------------------------------------------------------------------
+
+}  // namespace
+
+int main(int argc, char* argv[]) {
+  (void)absl::GetFlag(FLAGS_undefok);  // Force linking of parse.cc
+  flags::SetProgramInvocationName("usage_test");
+  absl::SetProgramUsageMessage(kTestUsageMessage);
+  ::testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}