about summary refs log tree commit diff
path: root/absl/flags/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags/internal')
-rw-r--r--absl/flags/internal/commandlineflag.cc34
-rw-r--r--absl/flags/internal/commandlineflag.h119
-rw-r--r--absl/flags/internal/commandlineflag_test.cc233
-rw-r--r--absl/flags/internal/flag.cc48
-rw-r--r--absl/flags/internal/flag.h105
-rw-r--r--absl/flags/internal/parse.h1
-rw-r--r--absl/flags/internal/path_util.h1
-rw-r--r--absl/flags/internal/private_handle_accessor.cc18
-rw-r--r--absl/flags/internal/private_handle_accessor.h12
-rw-r--r--absl/flags/internal/program_name_test.cc4
-rw-r--r--absl/flags/internal/registry.cc350
-rw-r--r--absl/flags/internal/registry.h43
-rw-r--r--absl/flags/internal/type_erased.cc86
-rw-r--r--absl/flags/internal/type_erased.h79
-rw-r--r--absl/flags/internal/type_erased_test.cc157
-rw-r--r--absl/flags/internal/usage.cc33
-rw-r--r--absl/flags/internal/usage.h4
-rw-r--r--absl/flags/internal/usage_test.cc16
18 files changed, 145 insertions, 1198 deletions
diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc
deleted file mode 100644
index 84112437d9cf..000000000000
--- a/absl/flags/internal/commandlineflag.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// 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/commandlineflag.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-FlagStateInterface::~FlagStateInterface() {}
-
-bool CommandLineFlag::IsRetired() const { return false; }
-
-bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) {
-  return ParseFrom(value, flags_internal::SET_FLAGS_VALUE,
-                   flags_internal::kProgrammaticChange, error);
-}
-
-}  // namespace flags_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h
index fa050209b0d7..cb46fe2e979d 100644
--- a/absl/flags/internal/commandlineflag.h
+++ b/absl/flags/internal/commandlineflag.h
@@ -16,14 +16,8 @@
 #ifndef ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_
 #define ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_
 
-#include <memory>
-#include <string>
-
 #include "absl/base/config.h"
 #include "absl/base/internal/fast_type_id.h"
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -34,7 +28,7 @@ namespace flags_internal {
 // 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 = base_internal::FastTypeIdType;
+using FlagFastTypeId = absl::base_internal::FastTypeIdType;
 
 // Options that control SetCommandLineOptionWithMode.
 enum FlagSettingMode {
@@ -67,117 +61,6 @@ class FlagStateInterface {
   virtual void Restore() const = 0;
 };
 
-// Holds all information for a flag.
-class CommandLineFlag {
- public:
-  constexpr CommandLineFlag() = default;
-
-  // Not copyable/assignable.
-  CommandLineFlag(const CommandLineFlag&) = delete;
-  CommandLineFlag& operator=(const CommandLineFlag&) = delete;
-
-  // Non-polymorphic access methods.
-
-  // Return true iff flag has type T.
-  template <typename T>
-  inline bool IsOfType() const {
-    return TypeId() == base_internal::FastTypeId<T>();
-  }
-
-  // Attempts to retrieve the flag value. Returns value on success,
-  // absl::nullopt otherwise.
-  template <typename T>
-  absl::optional<T> TryGet() const {
-    if (IsRetired() || !IsOfType<T>()) {
-      return absl::nullopt;
-    }
-
-    // Implementation notes:
-    //
-    // We are wrapping a union around the value of `T` to serve three purposes:
-    //
-    //  1. `U.value` has correct size and alignment for a value of type `T`
-    //  2. The `U.value` constructor is not invoked since U's constructor does
-    //     not do it explicitly.
-    //  3. The `U.value` destructor is invoked since U's destructor does it
-    //     explicitly. This makes `U` a kind of RAII wrapper around non default
-    //     constructible value of T, which is destructed when we leave the
-    //     scope. We do need to destroy U.value, which is constructed by
-    //     CommandLineFlag::Read even though we left it in a moved-from state
-    //     after std::move.
-    //
-    // All of this serves to avoid requiring `T` being default constructible.
-    union U {
-      T value;
-      U() {}
-      ~U() { value.~T(); }
-    };
-    U u;
-
-    Read(&u.value);
-    return std::move(u.value);
-  }
-
-  // Polymorphic access methods
-
-  // Returns name of this flag.
-  virtual absl::string_view Name() const = 0;
-  // Returns name of the file where this flag is defined.
-  virtual std::string Filename() const = 0;
-  // Returns help message associated with this flag.
-  virtual std::string Help() const = 0;
-  // Returns true iff this object corresponds to retired flag.
-  virtual bool IsRetired() const;
-  virtual std::string DefaultValue() const = 0;
-  virtual std::string CurrentValue() const = 0;
-
-  // 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 `error`
-  // to indicate the error, leaves the flag unchanged, and returns false.
-  bool ParseFrom(absl::string_view value, std::string* error);
-
- protected:
-  ~CommandLineFlag() = default;
-
- private:
-  friend class PrivateHandleAccessor;
-
-  // 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 `error`
-  // 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.
-  virtual bool ParseFrom(absl::string_view value,
-                         flags_internal::FlagSettingMode set_mode,
-                         flags_internal::ValueSource source,
-                         std::string* error) = 0;
-
-  // Returns id of the flag's value type.
-  virtual FlagFastTypeId TypeId() const = 0;
-
-  // Interface to save flag to some persistent state. Returns current flag state
-  // or nullptr if flag does not support saving and restoring a state.
-  virtual std::unique_ptr<FlagStateInterface> SaveState() = 0;
-
-  // Copy-construct a new value of the flag's type in a memory referenced by
-  // the dst based on the current flag's value.
-  virtual void Read(void* dst) const = 0;
-
-  // To be deleted. Used to return true if flag's current value originated from
-  // command line.
-  virtual bool IsSpecifiedOnCommandLine() const = 0;
-
-  // Validates supplied value usign validator or parseflag routine
-  virtual bool ValidateInputValue(absl::string_view value) const = 0;
-
-  // Checks that flags default value can be converted to string and back to the
-  // flag's value type.
-  virtual void CheckDefaultValueParsingRoundtrip() const = 0;
-};
-
 }  // namespace flags_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/internal/commandlineflag_test.cc
deleted file mode 100644
index 0b5aea379219..000000000000
--- a/absl/flags/internal/commandlineflag_test.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-//
-//  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/commandlineflag.h"
-
-#include <memory>
-#include <string>
-
-#include "gtest/gtest.h"
-#include "absl/flags/flag.h"
-#include "absl/flags/internal/private_handle_accessor.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/flags/usage_config.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-ABSL_FLAG(int, int_flag, 201, "int_flag help");
-ABSL_FLAG(std::string, string_flag, "dflt",
-          absl::StrCat("string_flag", " help"));
-ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help");
-
-namespace {
-
-namespace flags = absl::flags_internal;
-
-class CommandLineFlagTest : public testing::Test {
- protected:
-  static void SetUpTestSuite() {
-    // Install a function to normalize filenames before this test is run.
-    absl::FlagsUsageConfig default_config;
-    default_config.normalize_filename = &CommandLineFlagTest::NormalizeFileName;
-    absl::SetFlagsUsageConfig(default_config);
-  }
-
-  void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); }
-  void TearDown() override { flag_saver_.reset(); }
-
- private:
-  static std::string NormalizeFileName(absl::string_view fname) {
-#ifdef _WIN32
-    std::string normalized(fname);
-    std::replace(normalized.begin(), normalized.end(), '\\', '/');
-    fname = normalized;
-#endif
-    return std::string(fname);
-  }
-
-  std::unique_ptr<flags::FlagSaver> flag_saver_;
-};
-
-TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) {
-  auto* flag_01 = flags::FindCommandLineFlag("int_flag");
-
-  ASSERT_TRUE(flag_01);
-  EXPECT_EQ(flag_01->Name(), "int_flag");
-  EXPECT_EQ(flag_01->Help(), "int_flag help");
-  EXPECT_TRUE(!flag_01->IsRetired());
-  EXPECT_TRUE(flag_01->IsOfType<int>());
-  EXPECT_TRUE(
-      absl::EndsWith(flag_01->Filename(),
-                     "absl/flags/internal/commandlineflag_test.cc"))
-      << flag_01->Filename();
-
-  auto* flag_02 = flags::FindCommandLineFlag("string_flag");
-
-  ASSERT_TRUE(flag_02);
-  EXPECT_EQ(flag_02->Name(), "string_flag");
-  EXPECT_EQ(flag_02->Help(), "string_flag help");
-  EXPECT_TRUE(!flag_02->IsRetired());
-  EXPECT_TRUE(flag_02->IsOfType<std::string>());
-  EXPECT_TRUE(
-      absl::EndsWith(flag_02->Filename(),
-                     "absl/flags/internal/commandlineflag_test.cc"))
-      << flag_02->Filename();
-
-  auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag");
-
-  ASSERT_TRUE(flag_03);
-  EXPECT_EQ(flag_03->Name(), "bool_retired_flag");
-  EXPECT_EQ(flag_03->Help(), "");
-  EXPECT_TRUE(flag_03->IsRetired());
-  EXPECT_TRUE(flag_03->IsOfType<bool>());
-  EXPECT_EQ(flag_03->Filename(), "RETIRED");
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(CommandLineFlagTest, TestValueAccessMethods) {
-  absl::SetFlag(&FLAGS_int_flag, 301);
-  auto* flag_01 = flags::FindCommandLineFlag("int_flag");
-
-  ASSERT_TRUE(flag_01);
-  EXPECT_EQ(flag_01->CurrentValue(), "301");
-  EXPECT_EQ(flag_01->DefaultValue(), "201");
-
-  absl::SetFlag(&FLAGS_string_flag, "new_str_value");
-  auto* flag_02 = flags::FindCommandLineFlag("string_flag");
-
-  ASSERT_TRUE(flag_02);
-  EXPECT_EQ(flag_02->CurrentValue(), "new_str_value");
-  EXPECT_EQ(flag_02->DefaultValue(), "dflt");
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) {
-  std::string err;
-
-  auto* flag_01 = flags::FindCommandLineFlag("int_flag");
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
-  EXPECT_EQ(err, "Illegal value 'xyz' specified for flag 'int_flag'");
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
-  EXPECT_EQ(err, "Illegal value 'A1' specified for flag 'int_flag'");
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16);
-  EXPECT_FALSE(
-      flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
-  EXPECT_TRUE(flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
-
-  EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
-  EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'");
-
-  auto* flag_02 = flags::FindCommandLineFlag("string_flag");
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "xyz");
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "");
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) {
-  std::string err;
-
-  auto* flag_01 = flags::FindCommandLineFlag("int_flag");
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(flag_01->DefaultValue(), "111");
-
-  auto* flag_02 = flags::FindCommandLineFlag("string_flag");
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(flag_02->DefaultValue(), "abc");
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(CommandLineFlagTest, TestParseFromIfDefault) {
-  std::string err;
-
-  auto* flag_01 = flags::FindCommandLineFlag("int_flag");
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err))
-      << err;
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
-  // EXPECT_EQ(err, "ERROR: int_flag is already set to 22");
-
-  // Reset back to default value
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
-
-  EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 201);
-  // EXPECT_EQ(err, "ERROR: int_flag is already set to 201");
-}
-
-}  // namespace
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index 96c026dcb5d2..1502e7f11d36 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -15,22 +15,26 @@
 
 #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 <vector>
+#include <typeinfo>
 
-#include "absl/base/attributes.h"
+#include "absl/base/call_once.h"
 #include "absl/base/casts.h"
 #include "absl/base/config.h"
-#include "absl/base/const_init.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"
@@ -63,14 +67,14 @@ bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) {
 // need to acquire these locks themselves.
 class MutexRelock {
  public:
-  explicit MutexRelock(absl::Mutex* mu) : mu_(mu) { mu_->Unlock(); }
-  ~MutexRelock() { mu_->Lock(); }
+  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_;
+  absl::Mutex& mu_;
 };
 
 }  // namespace
@@ -83,7 +87,7 @@ class FlagImpl;
 class FlagState : public flags_internal::FlagStateInterface {
  public:
   template <typename V>
-  FlagState(FlagImpl* flag_impl, const V& v, bool modified,
+  FlagState(FlagImpl& flag_impl, const V& v, bool modified,
             bool on_command_line, int64_t counter)
       : flag_impl_(flag_impl),
         value_(v),
@@ -92,9 +96,9 @@ class FlagState : public flags_internal::FlagStateInterface {
         counter_(counter) {}
 
   ~FlagState() override {
-    if (flag_impl_->ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer)
+    if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer)
       return;
-    flags_internal::Delete(flag_impl_->op_, value_.heap_allocated);
+    flags_internal::Delete(flag_impl_.op_, value_.heap_allocated);
   }
 
  private:
@@ -102,15 +106,15 @@ class FlagState : public flags_internal::FlagStateInterface {
 
   // Restores the flag to the saved state.
   void Restore() const override {
-    if (!flag_impl_->RestoreState(*this)) return;
+    if (!flag_impl_.RestoreState(*this)) return;
 
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrCat("Restore saved value of ", flag_impl_->Name(),
-                           " to: ", flag_impl_->CurrentValue()));
+    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_;
+  FlagImpl& flag_impl_;
   union SavedValue {
     explicit SavedValue(void* v) : heap_allocated(v) {}
     explicit SavedValue(int64_t v) : one_word(v) {}
@@ -327,7 +331,7 @@ void FlagImpl::InvokeCallback() const {
   // 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());
+  MutexRelock relock(*DataGuard());
   absl::MutexLock lock(&callback_->guard);
   cb();
 }
@@ -340,17 +344,17 @@ std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() {
   switch (ValueStorageKind()) {
     case FlagValueStorageKind::kAlignedBuffer: {
       return absl::make_unique<FlagState>(
-          this, flags_internal::Clone(op_, AlignedBufferValue()), modified,
+          *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,
+          *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,
+          *this, TwoWordsValue().load(std::memory_order_acquire), modified,
           on_command_line, counter_);
     }
   }
@@ -411,14 +415,14 @@ std::atomic<AlignedTwoWords>& FlagImpl::TwoWordsValue() const {
 // 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 {
+    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);
+    err = absl::StrCat("Illegal value '", value, "' specified for flag '",
+                       Name(), "'", err_sep, parse_err);
     return nullptr;
   }
 
@@ -474,7 +478,7 @@ void FlagImpl::Write(const void* src) {
 //  * 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) {
+                         ValueSource source, std::string& err) {
   absl::MutexLock l(DataGuard());
 
   switch (set_mode) {
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index e374ecde3d95..2cc44e00f762 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -16,31 +16,36 @@
 #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/memory/memory.h"
 #include "absl/meta/type_traits.h"
-#include "absl/strings/str_cat.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>
@@ -64,12 +69,15 @@ void SetFlag(absl::Flag<T>* flag, const T& v);
 template <typename T, typename V>
 void SetFlag(absl::Flag<T>* flag, const V& v);
 
-namespace flags_internal {
+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,
@@ -168,6 +176,28 @@ inline const std::type_info* GenRuntimeTypeId() {
 // 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) {}
@@ -185,40 +215,28 @@ struct FlagHelpArg {
 
 extern const char kStrippedFlagHelp[];
 
-// HelpConstexprWrap is used by struct AbslFlagHelpGenFor##name generated by
-// ABSL_FLAG macro. It is only used to silence the compiler in the case where
-// help message expression is not constexpr and does not have type const char*.
-// If help message expression is indeed constexpr const char* HelpConstexprWrap
-// is just a trivial identity function.
-template <typename T>
-const char* HelpConstexprWrap(const T&) {
-  return nullptr;
-}
-constexpr const char* HelpConstexprWrap(const char* p) { return p; }
-constexpr const char* HelpConstexprWrap(char* p) { return p; }
-
 // 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 T and integer 0 as a single argument to prefer
-// first overload if possible. If T::Const is evaluatable on constexpr
-// context (see non template int parameter below) 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
+// 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 T, int = (T::Const(), 1)>
-constexpr FlagHelpArg HelpArg(int) {
-  return {FlagHelpMsg(T::Const()), FlagHelpKind::kLiteral};
+template <typename Gen, size_t N>
+constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) {
+  return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral};
 }
 
-template <typename T>
-constexpr FlagHelpArg HelpArg(char) {
-  return {FlagHelpMsg(&T::NonConst), FlagHelpKind::kGenFunc};
+template <typename Gen>
+constexpr FlagHelpArg HelpArg(std::false_type) {
+  return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc};
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -364,31 +382,31 @@ struct FlagValue;
 
 template <typename T>
 struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> {
-  bool Get(T*) const { return false; }
+  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 {
+  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));
+    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 {
+  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));
+    std::memcpy(&dst, static_cast<const void*>(&two_words_val), sizeof(T));
     return true;
   }
 };
@@ -419,7 +437,7 @@ struct DynValueDeleter {
 
 class FlagState;
 
-class FlagImpl final : public flags_internal::CommandLineFlag {
+class FlagImpl final : public CommandLineFlag {
  public:
   constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op,
                      FlagHelpArg help, FlagValueStorageKind value_kind,
@@ -492,7 +510,7 @@ class FlagImpl final : public flags_internal::CommandLineFlag {
   // 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
+                                                  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());
@@ -534,7 +552,7 @@ class FlagImpl final : public flags_internal::CommandLineFlag {
       ABSL_LOCKS_EXCLUDED(*DataGuard());
 
   bool ParseFrom(absl::string_view value, FlagSettingMode set_mode,
-                 ValueSource source, std::string* error) override
+                 ValueSource source, std::string& error) override
       ABSL_LOCKS_EXCLUDED(*DataGuard());
 
   // Immutable flag's state.
@@ -641,7 +659,7 @@ class Flag {
     impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>);
 #endif
 
-    if (!value_.Get(&u.value)) impl_.Read(&u.value);
+    if (!value_.Get(u.value)) impl_.Read(&u.value);
     return std::move(u.value);
   }
   void Set(const T& v) {
@@ -649,6 +667,13 @@ class Flag {
     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
@@ -720,12 +745,12 @@ 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_);
+  explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) {
+    if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_);
   }
 
   FlagRegistrar OnUpdate(FlagCallbackFunc cb) && {
-    flag_->impl_.SetCallback(cb);
+    flag_.impl_.SetCallback(cb);
     return *this;
   }
 
@@ -735,7 +760,7 @@ class FlagRegistrar {
   operator FlagRegistrarEmpty() const { return {}; }  // NOLINT
 
  private:
-  Flag<T>* flag_;  // Flag being registered (not owned).
+  Flag<T>& flag_;  // Flag being registered (not owned).
 };
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/parse.h b/absl/flags/internal/parse.h
index d259be733ce2..de706c898470 100644
--- a/absl/flags/internal/parse.h
+++ b/absl/flags/internal/parse.h
@@ -21,6 +21,7 @@
 
 #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);
diff --git a/absl/flags/internal/path_util.h b/absl/flags/internal/path_util.h
index 365c83052266..a6594d3347e1 100644
--- a/absl/flags/internal/path_util.h
+++ b/absl/flags/internal/path_util.h
@@ -17,7 +17,6 @@
 #define ABSL_FLAGS_INTERNAL_PATH_UTIL_H_
 
 #include "absl/base/config.h"
-#include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
 
 namespace absl {
diff --git a/absl/flags/internal/private_handle_accessor.cc b/absl/flags/internal/private_handle_accessor.cc
index 64fe31663a0a..a7eb58b6d45f 100644
--- a/absl/flags/internal/private_handle_accessor.cc
+++ b/absl/flags/internal/private_handle_accessor.cc
@@ -15,6 +15,14 @@
 
 #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 {
@@ -24,8 +32,8 @@ FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) {
 }
 
 std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState(
-    CommandLineFlag* flag) {
-  return flag->SaveState();
+    CommandLineFlag& flag) {
+  return flag.SaveState();
 }
 
 bool PrivateHandleAccessor::IsSpecifiedOnCommandLine(
@@ -43,12 +51,12 @@ void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip(
   flag.CheckDefaultValueParsingRoundtrip();
 }
 
-bool PrivateHandleAccessor::ParseFrom(CommandLineFlag* flag,
+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);
+                                      std::string& error) {
+  return flag.ParseFrom(value, set_mode, source, error);
 }
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/private_handle_accessor.h b/absl/flags/internal/private_handle_accessor.h
index 40591de447dd..c64435cd6199 100644
--- a/absl/flags/internal/private_handle_accessor.h
+++ b/absl/flags/internal/private_handle_accessor.h
@@ -16,7 +16,13 @@
 #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
@@ -31,7 +37,7 @@ class PrivateHandleAccessor {
   static FlagFastTypeId TypeId(const CommandLineFlag& flag);
 
   // Access to CommandLineFlag::SaveState.
-  static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag* flag);
+  static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag);
 
   // Access to CommandLineFlag::IsSpecifiedOnCommandLine.
   static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag);
@@ -43,9 +49,9 @@ class PrivateHandleAccessor {
   // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip.
   static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag);
 
-  static bool ParseFrom(CommandLineFlag* flag, absl::string_view value,
+  static bool ParseFrom(CommandLineFlag& flag, absl::string_view value,
                         flags_internal::FlagSettingMode set_mode,
-                        flags_internal::ValueSource source, std::string* error);
+                        flags_internal::ValueSource source, std::string& error);
 };
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/program_name_test.cc b/absl/flags/internal/program_name_test.cc
index 269142f2255f..aff9f6315e4e 100644
--- a/absl/flags/internal/program_name_test.cc
+++ b/absl/flags/internal/program_name_test.cc
@@ -25,7 +25,7 @@ namespace {
 
 namespace flags = absl::flags_internal;
 
-TEST(FlagsPathUtilTest, TestInitialProgamName) {
+TEST(FlagsPathUtilTest, TestProgamNameInterfaces) {
   flags::SetProgramInvocationName("absl/flags/program_name_test");
   std::string program_name = flags::ProgramInvocationName();
   for (char& c : program_name)
@@ -43,9 +43,7 @@ TEST(FlagsPathUtilTest, TestInitialProgamName) {
 
   EXPECT_TRUE(absl::EndsWith(program_name, expect_name)) << program_name;
   EXPECT_EQ(flags::ShortProgramInvocationName(), expect_basename);
-}
 
-TEST(FlagsPathUtilTest, TestProgamNameInterfaces) {
   flags::SetProgramInvocationName("a/my_test");
 
   EXPECT_EQ(flags::ProgramInvocationName(), "a/my_test");
diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc
deleted file mode 100644
index 3b941f04c21d..000000000000
--- a/absl/flags/internal/registry.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-//
-// 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/registry.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include <functional>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/thread_annotations.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/private_handle_accessor.h"
-#include "absl/flags/usage_config.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/synchronization/mutex.h"
-
-// --------------------------------------------------------------------
-// FlagRegistry implementation
-//    A FlagRegistry holds all flag objects indexed
-//    by their names so that if you know a flag's name you can access or
-//    set it.
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-// --------------------------------------------------------------------
-// FlagRegistry
-//    A FlagRegistry singleton object holds all flag objects indexed
-//    by their names so that if you know a flag's name (as a C
-//    string), you can access or set it.  If the function is named
-//    FooLocked(), you must own the registry lock before calling
-//    the function; otherwise, you should *not* hold the lock, and
-//    the function will acquire it itself if needed.
-// --------------------------------------------------------------------
-
-class FlagRegistry {
- public:
-  FlagRegistry() = default;
-  ~FlagRegistry() = default;
-
-  // Store a flag in this registry.  Takes ownership of *flag.
-  void RegisterFlag(CommandLineFlag* flag);
-
-  void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
-  void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
-
-  // Returns the flag object for the specified name, or nullptr if not found.
-  // Will emit a warning if a 'retired' flag is specified.
-  CommandLineFlag* FindFlagLocked(absl::string_view name);
-
-  // Returns the retired flag object for the specified name, or nullptr if not
-  // found or not retired.  Does not emit a warning.
-  CommandLineFlag* FindRetiredFlagLocked(absl::string_view name);
-
-  static FlagRegistry* GlobalRegistry();  // returns a singleton registry
-
- private:
-  friend class FlagSaverImpl;  // reads all the flags in order to copy them
-  friend void ForEachFlagUnlocked(
-      std::function<void(CommandLineFlag*)> visitor);
-
-  // The map from name to flag, for FindFlagLocked().
-  using FlagMap = std::map<absl::string_view, CommandLineFlag*>;
-  using FlagIterator = FlagMap::iterator;
-  using FlagConstIterator = FlagMap::const_iterator;
-  FlagMap flags_;
-
-  absl::Mutex lock_;
-
-  // Disallow
-  FlagRegistry(const FlagRegistry&);
-  FlagRegistry& operator=(const FlagRegistry&);
-};
-
-FlagRegistry* FlagRegistry::GlobalRegistry() {
-  static FlagRegistry* global_registry = new FlagRegistry;
-  return global_registry;
-}
-
-namespace {
-
-class FlagRegistryLock {
- public:
-  explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
-  ~FlagRegistryLock() { fr_->Unlock(); }
-
- private:
-  FlagRegistry* const fr_;
-};
-
-void DestroyRetiredFlag(CommandLineFlag* flag);
-}  // namespace
-
-void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
-  FlagRegistryLock registry_lock(this);
-  std::pair<FlagIterator, bool> ins =
-      flags_.insert(FlagMap::value_type(flag->Name(), flag));
-  if (ins.second == false) {  // means the name was already in the map
-    CommandLineFlag* old_flag = ins.first->second;
-    if (flag->IsRetired() != old_flag->IsRetired()) {
-      // All registrations must agree on the 'retired' flag.
-      flags_internal::ReportUsageError(
-          absl::StrCat(
-              "Retired flag '", flag->Name(),
-              "' was defined normally in file '",
-              (flag->IsRetired() ? old_flag->Filename() : flag->Filename()),
-              "'."),
-          true);
-    } else if (flags_internal::PrivateHandleAccessor::TypeId(*flag) !=
-               flags_internal::PrivateHandleAccessor::TypeId(*old_flag)) {
-      flags_internal::ReportUsageError(
-          absl::StrCat("Flag '", flag->Name(),
-                       "' was defined more than once but with "
-                       "differing types. Defined in files '",
-                       old_flag->Filename(), "' and '", flag->Filename(), "'."),
-          true);
-    } else if (old_flag->IsRetired()) {
-      // Retired flag can just be deleted.
-      DestroyRetiredFlag(flag);
-      return;
-    } else if (old_flag->Filename() != flag->Filename()) {
-      flags_internal::ReportUsageError(
-          absl::StrCat("Flag '", flag->Name(),
-                       "' was defined more than once (in files '",
-                       old_flag->Filename(), "' and '", flag->Filename(),
-                       "')."),
-          true);
-    } else {
-      flags_internal::ReportUsageError(
-          absl::StrCat(
-              "Something wrong with flag '", flag->Name(), "' in file '",
-              flag->Filename(), "'. One possibility: file '", flag->Filename(),
-              "' is being linked both statically and dynamically into this "
-              "executable. e.g. some files listed as srcs to a test and also "
-              "listed as srcs of some shared lib deps of the same test."),
-          true);
-    }
-    // All cases above are fatal, except for the retired flags.
-    std::exit(1);
-  }
-}
-
-CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) {
-  FlagConstIterator i = flags_.find(name);
-  if (i == flags_.end()) {
-    return nullptr;
-  }
-
-  if (i->second->IsRetired()) {
-    flags_internal::ReportUsageError(
-        absl::StrCat("Accessing retired flag '", name, "'"), false);
-  }
-
-  return i->second;
-}
-
-CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) {
-  FlagConstIterator i = flags_.find(name);
-  if (i == flags_.end() || !i->second->IsRetired()) {
-    return nullptr;
-  }
-
-  return i->second;
-}
-
-// --------------------------------------------------------------------
-// FlagSaver
-// FlagSaverImpl
-//    This class stores the states of all flags at construct time,
-//    and restores all flags to that state at destruct time.
-//    Its major implementation challenge is that it never modifies
-//    pointers in the 'main' registry, so global FLAG_* vars always
-//    point to the right place.
-// --------------------------------------------------------------------
-
-class FlagSaverImpl {
- public:
-  FlagSaverImpl() = default;
-  FlagSaverImpl(const FlagSaverImpl&) = delete;
-  void operator=(const FlagSaverImpl&) = delete;
-
-  // Saves the flag states from the flag registry into this object.
-  // It's an error to call this more than once.
-  void SaveFromRegistry() {
-    assert(backup_registry_.empty());  // call only once!
-    flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) {
-      if (auto flag_state =
-              flags_internal::PrivateHandleAccessor::SaveState(flag)) {
-        backup_registry_.emplace_back(std::move(flag_state));
-      }
-    });
-  }
-
-  // Restores the saved flag states into the flag registry.
-  void RestoreToRegistry() {
-    for (const auto& flag_state : backup_registry_) {
-      flag_state->Restore();
-    }
-  }
-
- private:
-  std::vector<std::unique_ptr<flags_internal::FlagStateInterface>>
-      backup_registry_;
-};
-
-FlagSaver::FlagSaver() : impl_(new FlagSaverImpl) { impl_->SaveFromRegistry(); }
-
-void FlagSaver::Ignore() {
-  delete impl_;
-  impl_ = nullptr;
-}
-
-FlagSaver::~FlagSaver() {
-  if (!impl_) return;
-
-  impl_->RestoreToRegistry();
-  delete impl_;
-}
-
-// --------------------------------------------------------------------
-
-CommandLineFlag* FindCommandLineFlag(absl::string_view name) {
-  if (name.empty()) return nullptr;
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-
-  return registry->FindFlagLocked(name);
-}
-
-CommandLineFlag* FindRetiredFlag(absl::string_view name) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-
-  return registry->FindRetiredFlagLocked(name);
-}
-
-// --------------------------------------------------------------------
-
-void ForEachFlagUnlocked(std::function<void(CommandLineFlag*)> visitor) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
-       i != registry->flags_.end(); ++i) {
-    visitor(i->second);
-  }
-}
-
-void ForEachFlag(std::function<void(CommandLineFlag*)> visitor) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  FlagRegistryLock frl(registry);
-  ForEachFlagUnlocked(visitor);
-}
-
-// --------------------------------------------------------------------
-
-bool RegisterCommandLineFlag(CommandLineFlag* flag) {
-  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);
-  return true;
-}
-
-// --------------------------------------------------------------------
-
-namespace {
-
-class RetiredFlagObj final : public flags_internal::CommandLineFlag {
- public:
-  constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id)
-      : name_(name), type_id_(type_id) {}
-
- private:
-  absl::string_view Name() const override { return name_; }
-  std::string Filename() const override { return "RETIRED"; }
-  FlagFastTypeId TypeId() const override { return type_id_; }
-  std::string Help() const override { return ""; }
-  bool IsRetired() const override { return true; }
-  bool IsSpecifiedOnCommandLine() const override { return false; }
-  std::string DefaultValue() const override { return ""; }
-  std::string CurrentValue() const override { return ""; }
-
-  // Any input is valid
-  bool ValidateInputValue(absl::string_view) const override { return true; }
-
-  std::unique_ptr<flags_internal::FlagStateInterface> SaveState() override {
-    return nullptr;
-  }
-
-  bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode,
-                 flags_internal::ValueSource, std::string*) override {
-    return false;
-  }
-
-  void CheckDefaultValueParsingRoundtrip() const override {}
-
-  void Read(void*) const override {}
-
-  // Data members
-  const char* const name_;
-  const FlagFastTypeId type_id_;
-};
-
-void DestroyRetiredFlag(flags_internal::CommandLineFlag* flag) {
-  assert(flag->IsRetired());
-  delete static_cast<RetiredFlagObj*>(flag);
-}
-
-}  // namespace
-
-bool Retire(const char* name, FlagFastTypeId type_id) {
-  auto* flag = new flags_internal::RetiredFlagObj(name, type_id);
-  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);
-  return true;
-}
-
-// --------------------------------------------------------------------
-
-bool IsRetiredFlag(absl::string_view name, bool* type_is_bool) {
-  assert(!name.empty());
-  CommandLineFlag* flag = flags_internal::FindRetiredFlag(name);
-  if (flag == nullptr) {
-    return false;
-  }
-  assert(type_is_bool);
-  *type_is_bool = flag->IsOfType<bool>();
-  return true;
-}
-
-}  // namespace flags_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h
index af8ed6b99b78..6f5006a016fd 100644
--- a/absl/flags/internal/registry.h
+++ b/absl/flags/internal/registry.h
@@ -17,11 +17,9 @@
 #define ABSL_FLAGS_INTERNAL_REGISTRY_H_
 
 #include <functional>
-#include <map>
-#include <string>
 
 #include "absl/base/config.h"
-#include "absl/base/macros.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/internal/commandlineflag.h"
 #include "absl/strings/string_view.h"
 
@@ -32,19 +30,16 @@ namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace flags_internal {
 
-CommandLineFlag* FindCommandLineFlag(absl::string_view name);
-CommandLineFlag* FindRetiredFlag(absl::string_view name);
-
 // 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);
+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);
+void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
 
 //-----------------------------------------------------------------------------
 
-bool RegisterCommandLineFlag(CommandLineFlag*);
+bool RegisterCommandLineFlag(CommandLineFlag&);
 
 //-----------------------------------------------------------------------------
 // Retired registrations:
@@ -87,36 +82,6 @@ inline bool RetiredFlag(const char* flag_name) {
   return flags_internal::Retire(flag_name, base_internal::FastTypeId<T>());
 }
 
-// If the flag is retired, returns true and indicates in |*type_is_bool|
-// whether the type of the retired flag is a bool.
-// Only to be called by code that needs to explicitly ignore retired flags.
-bool IsRetiredFlag(absl::string_view name, bool* type_is_bool);
-
-//-----------------------------------------------------------------------------
-// Saves the states (value, default value, whether the user has set
-// the flag, registered validators, etc) of all flags, and restores
-// them when the FlagSaver is destroyed.
-//
-// This class is thread-safe.  However, its destructor writes to
-// exactly the set of flags that have changed value during its
-// lifetime, so concurrent _direct_ access to those flags
-// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
-
-class FlagSaver {
- public:
-  FlagSaver();
-  ~FlagSaver();
-
-  FlagSaver(const FlagSaver&) = delete;
-  void operator=(const FlagSaver&) = delete;
-
-  // Prevents saver from restoring the saved state of flags.
-  void Ignore();
-
- private:
-  class FlagSaverImpl* impl_;  // we use pimpl here to keep API steady
-};
-
 }  // namespace flags_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc
deleted file mode 100644
index c13fb9b0d453..000000000000
--- a/absl/flags/internal/type_erased.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// 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/type_erased.h"
-
-#include <assert.h>
-
-#include <string>
-
-#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/private_handle_accessor.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/flags/usage_config.h"
-#include "absl/strings/string_view.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-bool GetCommandLineOption(absl::string_view name, std::string* value) {
-  if (name.empty()) return false;
-  assert(value);
-
-  CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-  if (flag == nullptr || flag->IsRetired()) {
-    return false;
-  }
-
-  *value = flag->CurrentValue();
-  return true;
-}
-
-bool SetCommandLineOption(absl::string_view name, absl::string_view value) {
-  return SetCommandLineOptionWithMode(name, value,
-                                      flags_internal::SET_FLAGS_VALUE);
-}
-
-bool SetCommandLineOptionWithMode(absl::string_view name,
-                                  absl::string_view value,
-                                  FlagSettingMode set_mode) {
-  CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-
-  if (!flag || flag->IsRetired()) return false;
-
-  std::string error;
-  if (!flags_internal::PrivateHandleAccessor::ParseFrom(
-          flag, value, set_mode, kProgrammaticChange, &error)) {
-    // Errors here are all of the form: the provided name was a recognized
-    // flag, but the value was invalid (bad type, or validation failed).
-    flags_internal::ReportUsageError(error, false);
-    return false;
-  }
-
-  return true;
-}
-
-// --------------------------------------------------------------------
-
-bool IsValidFlagValue(absl::string_view name, absl::string_view value) {
-  CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-
-  return flag != nullptr &&
-         (flag->IsRetired() ||
-          flags_internal::PrivateHandleAccessor::ValidateInputValue(*flag,
-                                                                    value));
-}
-
-// --------------------------------------------------------------------
-
-}  // namespace flags_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
diff --git a/absl/flags/internal/type_erased.h b/absl/flags/internal/type_erased.h
deleted file mode 100644
index b43a0ff7be66..000000000000
--- a/absl/flags/internal/type_erased.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// 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_TYPE_ERASED_H_
-#define ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
-
-#include <string>
-
-#include "absl/base/config.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/strings/string_view.h"
-
-// --------------------------------------------------------------------
-// Registry interfaces operating on type erased handles.
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-// If a flag named "name" exists, store its current value in *OUTPUT
-// and return true.  Else return false without changing *OUTPUT.
-// Thread-safe.
-bool GetCommandLineOption(absl::string_view name, std::string* value);
-
-// Set the value of the flag named "name" to value.  If successful,
-// returns true.  If not successful (e.g., the flag was not found or
-// the value is not a valid value), returns false.
-// Thread-safe.
-bool SetCommandLineOption(absl::string_view name, absl::string_view value);
-
-bool SetCommandLineOptionWithMode(absl::string_view name,
-                                  absl::string_view value,
-                                  FlagSettingMode set_mode);
-
-//-----------------------------------------------------------------------------
-
-// Returns true iff all of the following conditions are true:
-// (a) "name" names a registered flag
-// (b) "value" can be parsed succesfully according to the type of the flag
-// (c) parsed value passes any validator associated with the flag
-bool IsValidFlagValue(absl::string_view name, absl::string_view value);
-
-//-----------------------------------------------------------------------------
-
-// If a flag with specified "name" exists and has type T, store
-// its current value in *dst and return true.  Else return false
-// without touching *dst.  T must obey all of the requirements for
-// types passed to DEFINE_FLAG.
-template <typename T>
-inline bool GetByName(absl::string_view name, T* dst) {
-  CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-  if (!flag) return false;
-
-  if (auto val = flag->TryGet<T>()) {
-    *dst = *val;
-    return true;
-  }
-
-  return false;
-}
-
-}  // namespace flags_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#endif  // ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
diff --git a/absl/flags/internal/type_erased_test.cc b/absl/flags/internal/type_erased_test.cc
deleted file mode 100644
index 4ce5981047b6..000000000000
--- a/absl/flags/internal/type_erased_test.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-//
-//  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/type_erased.h"
-
-#include <memory>
-#include <string>
-
-#include "gtest/gtest.h"
-#include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/flags/marshalling.h"
-#include "absl/memory/memory.h"
-
-ABSL_FLAG(int, int_flag, 1, "int_flag help");
-ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help");
-ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help");
-
-namespace {
-
-namespace flags = absl::flags_internal;
-
-class TypeErasedTest : public testing::Test {
- protected:
-  void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); }
-  void TearDown() override { flag_saver_.reset(); }
-
- private:
-  std::unique_ptr<flags::FlagSaver> flag_saver_;
-};
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestGetCommandLineOption) {
-  std::string value;
-  EXPECT_TRUE(flags::GetCommandLineOption("int_flag", &value));
-  EXPECT_EQ(value, "1");
-
-  EXPECT_TRUE(flags::GetCommandLineOption("string_flag", &value));
-  EXPECT_EQ(value, "dflt");
-
-  EXPECT_FALSE(flags::GetCommandLineOption("bool_retired_flag", &value));
-
-  EXPECT_FALSE(flags::GetCommandLineOption("unknown_flag", &value));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOption) {
-  EXPECT_TRUE(flags::SetCommandLineOption("int_flag", "101"));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
-  EXPECT_TRUE(flags::SetCommandLineOption("string_flag", "asdfgh"));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
-  EXPECT_FALSE(flags::SetCommandLineOption("bool_retired_flag", "true"));
-
-  EXPECT_FALSE(flags::SetCommandLineOption("unknown_flag", "true"));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_VALUE) {
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
-                                                  flags::SET_FLAGS_VALUE));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
-                                                  flags::SET_FLAGS_VALUE));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
-                                                   flags::SET_FLAGS_VALUE));
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
-                                                   flags::SET_FLAGS_VALUE));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAG_IF_DEFAULT) {
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
-                                                  flags::SET_FLAG_IF_DEFAULT));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
-  // This semantic is broken. We return true instead of false. Value is not
-  // updated.
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202",
-                                                  flags::SET_FLAG_IF_DEFAULT));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
-                                                  flags::SET_FLAG_IF_DEFAULT));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
-                                                   flags::SET_FLAG_IF_DEFAULT));
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
-                                                   flags::SET_FLAG_IF_DEFAULT));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_DEFAULT) {
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
-                                                  flags::SET_FLAGS_DEFAULT));
-
-  // Set it again to ensure that resetting logic is covered.
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "102",
-                                                  flags::SET_FLAGS_DEFAULT));
-
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "103",
-                                                  flags::SET_FLAGS_DEFAULT));
-
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
-                                                  flags::SET_FLAGS_DEFAULT));
-  EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
-                                                   flags::SET_FLAGS_DEFAULT));
-
-  EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
-                                                   flags::SET_FLAGS_DEFAULT));
-
-  // This should be successfull, since flag is still is not set
-  EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202",
-                                                  flags::SET_FLAG_IF_DEFAULT));
-  EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 202);
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestIsValidFlagValue) {
-  EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "57"));
-  EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "-101"));
-  EXPECT_FALSE(flags::IsValidFlagValue("int_flag", "1.1"));
-
-  EXPECT_TRUE(flags::IsValidFlagValue("string_flag", "#%^#%^$%DGHDG$W%adsf"));
-
-  EXPECT_TRUE(flags::IsValidFlagValue("bool_retired_flag", "true"));
-}
-
-}  // namespace
diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc
index 10accc46f32a..35b6427b6c83 100644
--- a/absl/flags/internal/usage.cc
+++ b/absl/flags/internal/usage.cc
@@ -15,6 +15,8 @@
 
 #include "absl/flags/internal/usage.h"
 
+#include <stdint.h>
+
 #include <functional>
 #include <map>
 #include <ostream>
@@ -23,8 +25,8 @@
 #include <vector>
 
 #include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/internal/flag.h"
 #include "absl/flags/internal/path_util.h"
 #include "absl/flags/internal/private_handle_accessor.h"
@@ -107,8 +109,8 @@ 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),
+  FlagHelpPrettyPrinter(int max_line_len, std::ostream& out)
+      : out_(out),
         max_line_len_(max_line_len),
         line_len_(0),
         first_line_(true) {}
@@ -182,8 +184,7 @@ class FlagHelpPrettyPrinter {
   bool first_line_;
 };
 
-void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag,
-                           std::ostream* out) {
+void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) {
   FlagHelpPrettyPrinter printer(80, out);  // Max line length is 80.
 
   // Flag name.
@@ -245,30 +246,28 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb,
   // 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 flags_internal::CommandLineFlag*>>>
+           std::map<std::string, std::vector<const absl::CommandLineFlag*>>>
       matching_flags;
 
-  flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) {
-    std::string flag_filename = flag->Filename();
+  flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) {
+    std::string flag_filename = flag.Filename();
 
     // Ignore retired flags.
-    if (flag->IsRetired()) return;
+    if (flag.IsRetired()) return;
 
     // If the flag has been stripped, pretend that it doesn't exist.
-    if (flag->Help() == flags_internal::kStrippedFlagHelp) return;
+    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);
+                      .push_back(&flag);
   });
 
-  absl::string_view
-      package_separator;             // controls blank lines between packages.
-  absl::string_view file_separator;  // controls blank lines between files.
+  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;
@@ -303,10 +302,10 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb,
 
 // --------------------------------------------------------------------
 // Produces the help message describing specific flag.
-void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& flag,
+void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
               HelpFormat format) {
   if (format == HelpFormat::kHumanReadable)
-    flags_internal::FlagHelpHumanReadable(flag, &out);
+    flags_internal::FlagHelpHumanReadable(flag, out);
 }
 
 // --------------------------------------------------------------------
diff --git a/absl/flags/internal/usage.h b/absl/flags/internal/usage.h
index 6b080fd1eeec..0c62dc4b2ac6 100644
--- a/absl/flags/internal/usage.h
+++ b/absl/flags/internal/usage.h
@@ -20,8 +20,8 @@
 #include <string>
 
 #include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/declare.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/strings/string_view.h"
 
 // --------------------------------------------------------------------
@@ -37,7 +37,7 @@ enum class HelpFormat {
 };
 
 // Outputs the help message describing specific flag.
-void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& 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
diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc
index 8dd3532e6d40..6e583fbe4b0e 100644
--- a/absl/flags/internal/usage_test.cc
+++ b/absl/flags/internal/usage_test.cc
@@ -21,15 +21,13 @@
 #include <string>
 
 #include "gtest/gtest.h"
-#include "absl/flags/declare.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/internal/registry.h"
+#include "absl/flags/reflection.h"
 #include "absl/flags/usage.h"
 #include "absl/flags/usage_config.h"
-#include "absl/memory/memory.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
 
@@ -91,7 +89,7 @@ class UsageReportingTest : public testing::Test {
   }
 
  private:
-  flags::FlagSaver flag_saver_;
+  absl::FlagSaver flag_saver_;
 };
 
 // --------------------------------------------------------------------
@@ -112,7 +110,7 @@ TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) {
 // --------------------------------------------------------------------
 
 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
-  const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_01");
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01");
   std::stringstream test_buf;
 
   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -124,7 +122,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
 }
 
 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
-  const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_02");
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02");
   std::stringstream test_buf;
 
   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -136,7 +134,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
 }
 
 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
-  const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_03");
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03");
   std::stringstream test_buf;
 
   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -148,7 +146,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
 }
 
 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
-  const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_04");
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04");
   std::stringstream test_buf;
 
   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -160,7 +158,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
 }
 
 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) {
-  const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_05");
+  const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05");
   std::stringstream test_buf;
 
   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);