| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_ |
| #define NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_ |
| |
| #include <cstdint> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/export_template.h" |
| #include "base/no_destructor.h" |
| #include "base/optional.h" |
| #include "net/third_party/quic/platform/api/quic_export.h" |
| #include "net/third_party/quic/platform/api/quic_string.h" |
| #include "net/third_party/quic/platform/api/quic_string_piece.h" |
| |
| #define QUIC_FLAG(type, flag, value) QUIC_EXPORT_PRIVATE extern type flag; |
| #include "net/quic/quic_flags_list.h" |
| #undef QUIC_FLAG |
| |
| // API compatibility with new-style flags. |
| |
| inline bool GetQuicFlagImpl(bool flag) { |
| return flag; |
| } |
| inline int32_t GetQuicFlagImpl(int32_t flag) { |
| return flag; |
| } |
| inline uint32_t GetQuicFlagImpl(uint32_t flag) { |
| return flag; |
| } |
| inline int64_t GetQuicFlagImpl(int64_t flag) { |
| return flag; |
| } |
| inline uint64_t GetQuicFlagImpl(uint64_t flag) { |
| return flag; |
| } |
| inline double GetQuicFlagImpl(double flag) { |
| return flag; |
| } |
| inline std::string GetQuicFlagImpl(const std::string& flag) { |
| return flag; |
| } |
| |
| inline void SetQuicFlagImpl(bool* f, bool v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(int32_t* f, int32_t v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(uint32_t* f, uint32_t v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(int64_t* f, int64_t v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(uint64_t* f, uint64_t v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(double* f, double v) { |
| *f = v; |
| } |
| inline void SetQuicFlagImpl(std::string* f, const std::string& v) { |
| *f = v; |
| } |
| |
| namespace quic { |
| |
| // ------------------------------------------------------------------------ |
| // DEFINE_QUIC_COMMAND_LINE_FLAG implementation. |
| // ------------------------------------------------------------------------ |
| |
| // Abstract class for setting flags and fetching help strings. |
| class QuicFlagHelper { |
| public: |
| explicit QuicFlagHelper(const char* help) : help_(help) {} |
| virtual ~QuicFlagHelper() = default; |
| |
| virtual bool SetFlag(const std::string& value) const = 0; |
| virtual void ResetFlag() const = 0; |
| std::string GetHelp() const { return help_; } |
| |
| private: |
| std::string help_; |
| }; |
| |
| // Templated class for setting flags of various types. |
| template <typename T> |
| class TypedQuicFlagHelper : public QuicFlagHelper { |
| public: |
| TypedQuicFlagHelper(T* flag, const T& default_value, const char* help) |
| : QuicFlagHelper(help), flag_(flag), default_value_(default_value) {} |
| bool SetFlag(const std::string& value) const override; |
| void ResetFlag() const override { *flag_ = default_value_; } |
| |
| private: |
| mutable T* flag_; |
| T default_value_; |
| }; |
| |
| // SetFlag specializations. Implementations in .cc file. |
| template <> |
| QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<bool>::SetFlag( |
| const std::string&) const; |
| template <> |
| QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<int32_t>::SetFlag( |
| const std::string&) const; |
| template <> |
| QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<QuicString>::SetFlag( |
| const std::string&) const; |
| |
| // TypedQuicFlagHelper instantiations are in .cc file. |
| extern template class EXPORT_TEMPLATE_DECLARE(QUIC_EXPORT_PRIVATE) |
| TypedQuicFlagHelper<bool>; |
| extern template class EXPORT_TEMPLATE_DECLARE(QUIC_EXPORT_PRIVATE) |
| TypedQuicFlagHelper<int32_t>; |
| extern template class EXPORT_TEMPLATE_DECLARE(QUIC_EXPORT_PRIVATE) |
| TypedQuicFlagHelper<QuicString>; |
| |
| // Registry of QuicFlagHelpers. |
| class QUIC_EXPORT_PRIVATE QuicFlagRegistry { |
| public: |
| static QuicFlagRegistry& GetInstance(); |
| |
| // Adds a flag to the registry. |
| void RegisterFlag(const char* name, std::unique_ptr<QuicFlagHelper> helper); |
| |
| // Sets any flags in the registry that are specified in |command_line|, |
| // returning true iff successful. If there is a failure, e.g. due to an |
| // invalid flag value, returns false and sets |error_msg|. |
| bool SetFlags(const base::CommandLine& command_line, |
| std::string* error_msg) const; |
| |
| // Resets flags to their default values. |
| void ResetFlags() const; |
| |
| // Returns a help string consisting of the names and help strings of all |
| // registered flags. |
| std::string GetHelp() const; |
| |
| private: |
| friend class base::NoDestructor<QuicFlagRegistry>; |
| |
| // Should only be accessed as a singleton. |
| QuicFlagRegistry() = default; |
| |
| std::map<std::string, std::unique_ptr<QuicFlagHelper>> flags_; |
| }; |
| |
| // Class instantiated in DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL macro expansion, |
| // that registers flag as a side effect of its constructor. Similar in spirit to |
| // absl::flags_internal::FlagRegistrar. |
| template <typename T> |
| class QuicFlagSetup { |
| public: |
| QuicFlagSetup(T* flag, |
| const char* name, |
| const T& default_value, |
| const char* help) { |
| QuicFlagRegistry::GetInstance().RegisterFlag( |
| name, |
| std::make_unique<TypedQuicFlagHelper<T>>(flag, default_value, help)); |
| } |
| // Allow QuicFlagSetup instance to convert to a bool in |
| // DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL macro expansion, so it can go away. |
| operator bool() const { return true; } |
| }; |
| |
| #define DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL(type, name, default_value, help) \ |
| type FLAGS_##name = default_value; \ |
| bool FLAGS_no##name = \ |
| quic::QuicFlagSetup<type>(&FLAGS_##name, #name, default_value, help) |
| |
| QUIC_EXPORT_PRIVATE std::vector<QuicString> QuicParseCommandLineFlagsImpl( |
| const char* usage, |
| int argc, |
| const char* const* argv); |
| |
| // Used internally by QuicParseCommandLineFlagsImpl(), but exposed here for |
| // testing. |
| struct QUIC_EXPORT_PRIVATE QuicParseCommandLineFlagsResult { |
| std::vector<QuicString> non_flag_args; |
| base::Optional<int> exit_status; |
| }; |
| QUIC_EXPORT_PRIVATE QuicParseCommandLineFlagsResult |
| QuicParseCommandLineFlagsHelper(const char* usage, |
| const base::CommandLine& command_line); |
| |
| QUIC_EXPORT_PRIVATE void QuicPrintCommandLineFlagHelpImpl(const char* usage); |
| |
| // ------------------------------------------------------------------------ |
| // QUIC feature flags implementation. |
| // ------------------------------------------------------------------------ |
| #define RELOADABLE_FLAG(flag) FLAGS_quic_reloadable_flag_##flag |
| #define RESTART_FLAG(flag) FLAGS_quic_restart_flag_##flag |
| |
| #define GetQuicReloadableFlagImpl(flag) GetQuicFlag(RELOADABLE_FLAG(flag)) |
| #define SetQuicReloadableFlagImpl(flag, value) \ |
| SetQuicFlag(&RELOADABLE_FLAG(flag), value) |
| #define GetQuicRestartFlagImpl(flag) GetQuicFlag(RESTART_FLAG(flag)) |
| #define SetQuicRestartFlagImpl(flag, value) \ |
| SetQuicFlag(&RESTART_FLAG(flag), value) |
| |
| } // namespace quic |
| #endif // NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_ |