• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
6 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/command_line.h"
12 #include "base/export_template.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/no_destructor.h"
15 #include "net/third_party/quiche/src/quiche/common/platform/api/quiche_export.h"
16 #include "net/third_party/quiche/src/quiche/common/platform/api/quiche_flags.h"
17 #include "third_party/abseil-cpp/absl/types/optional.h"
18 
19 namespace quiche {
20 
21 // Abstract class for setting flags and fetching help strings.
22 class QuicheFlagHelper {
23  public:
QuicheFlagHelper(const char * help)24   explicit QuicheFlagHelper(const char* help) : help_(help) {}
25   virtual ~QuicheFlagHelper() = default;
26 
27   virtual bool SetFlag(const std::string& value) const = 0;
28   virtual void ResetFlag() const = 0;
GetHelp()29   std::string GetHelp() const { return help_; }
30 
31  private:
32   std::string help_;
33 };
34 
35 // Templated class for setting flags of various types.
36 template <typename T>
37 class TypedQuicheFlagHelper : public QuicheFlagHelper {
38  public:
TypedQuicheFlagHelper(T * flag,const T & default_value,const char * help)39   TypedQuicheFlagHelper(T* flag, const T& default_value, const char* help)
40       : QuicheFlagHelper(help), flag_(flag), default_value_(default_value) {}
41   bool SetFlag(const std::string& value) const override;
ResetFlag()42   void ResetFlag() const override { *flag_ = default_value_; }
43 
44  private:
45   mutable raw_ptr<T> flag_;
46   T default_value_;
47 };
48 
49 // SetFlag specializations. Implementations in .cc file.
50 template <>
51 bool TypedQuicheFlagHelper<bool>::SetFlag(const std::string&) const;
52 template <>
53 bool TypedQuicheFlagHelper<uint16_t>::SetFlag(const std::string&) const;
54 template <>
55 bool TypedQuicheFlagHelper<int32_t>::SetFlag(const std::string&) const;
56 template <>
57 bool TypedQuicheFlagHelper<std::string>::SetFlag(const std::string&) const;
58 
59 // TypedQuicheFlagHelper instantiations are in .cc file.
60 extern template class TypedQuicheFlagHelper<bool>;
61 extern template class TypedQuicheFlagHelper<uint16_t>;
62 extern template class TypedQuicheFlagHelper<int32_t>;
63 extern template class TypedQuicheFlagHelper<std::string>;
64 
65 // Registry of QuicheFlagHelpers.
66 class QuicheFlagRegistry {
67  public:
68   ~QuicheFlagRegistry();
69 
70   static QuicheFlagRegistry& GetInstance();
71 
72   // Adds a flag to the registry.
73   void RegisterFlag(const char* name, std::unique_ptr<QuicheFlagHelper> helper);
74 
75   // Sets any flags in the registry that are specified in |command_line|,
76   // returning true iff successful. If there is a failure, e.g. due to an
77   // invalid flag value, returns false and sets |error_msg|.
78   bool SetFlags(const base::CommandLine& command_line,
79                 std::string* error_msg) const;
80 
81   // Resets flags to their default values.
82   void ResetFlags() const;
83 
84   // Returns a help string consisting of the names and help strings of all
85   // registered flags.
86   std::string GetHelp() const;
87 
88  private:
89   friend class base::NoDestructor<QuicheFlagRegistry>;
90 
91   // Should only be accessed as a singleton.
92   QuicheFlagRegistry();
93 
94   std::map<std::string, std::unique_ptr<QuicheFlagHelper>> flags_;
95 };
96 
97 // Class instantiated in DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL macro expansion,
98 // that registers flag as a side effect of its constructor. Similar in spirit to
99 // absl::flags_internal::FlagRegistrar.
100 template <typename T>
101 class QuicheFlagSetup {
102  public:
QuicheFlagSetup(T * flag,const char * name,const T & default_value,const char * help)103   QuicheFlagSetup(T* flag,
104                   const char* name,
105                   const T& default_value,
106                   const char* help) {
107     QuicheFlagRegistry::GetInstance().RegisterFlag(
108         name,
109         std::make_unique<TypedQuicheFlagHelper<T>>(flag, default_value, help));
110   }
111   // Allow QuicheFlagSetup instance to convert to a bool in
112   // DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL macro expansion, so it can go away.
113   operator bool() const { return true; }
114 };
115 
116 // ------------------------------------------------------------------------
117 // DEFINE_QUICHE_COMMAND_LINE_FLAG implementation.
118 // ------------------------------------------------------------------------
119 
120 #define DEFINE_QUICHE_COMMAND_LINE_FLAG_IMPL(type, name, default_value, help) \
121   type FLAGS_##name = default_value;                                          \
122   bool FLAGS_no##name =                                                       \
123       quiche::QuicheFlagSetup<type>(&FLAGS_##name, #name, default_value, help)
124 
125 std::vector<std::string> QuicheParseCommandLineFlagsImpl(
126     const char* usage,
127     int argc,
128     const char* const* argv);
129 
130 // Used internally by QuicheParseCommandLineFlagsImpl(), but exposed here for
131 // testing.
132 struct QuicheParseCommandLineFlagsResult {
133   QuicheParseCommandLineFlagsResult();
134   QuicheParseCommandLineFlagsResult(const QuicheParseCommandLineFlagsResult&);
135   ~QuicheParseCommandLineFlagsResult();
136 
137   std::vector<std::string> non_flag_args;
138   absl::optional<int> exit_status;
139 };
140 
141 QuicheParseCommandLineFlagsResult QuicheParseCommandLineFlagsHelper(
142     const char* usage,
143     const base::CommandLine& command_line);
144 
145 void QuichePrintCommandLineFlagHelpImpl(const char* usage);
146 
147 template <typename T>
GetQuicheCommandLineFlag(const T & flag)148 T GetQuicheCommandLineFlag(const T& flag) {
149   return flag;
150 }
151 
152 }  // namespace quiche
153 
154 #endif  // NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
155