Ensure the CommandSwitches::Get() singleton is properly initialized.

Otherwise, flags like `--as=buildfile` are ignored. This caused a
GN autoroll failure in Chromium. This fixes the issue by ensuring
that CommandSwitches::Init() is called from main(), and by adding
runtime checks to verify CommandSwitches::Get() and
CommandSwitches::Set() are always called after
CommandSwitches::Init().

Bug: chromium/1300012
Change-Id: Iaf2b3a9332f25b24c13f3075fe9bceed6c3f1a4b
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/13000
Reviewed-by: Nico Weber <thakis@chromium.org>
Reviewed-by: Petr Hosek <phosek@google.com>
Commit-Queue: Petr Hosek <phosek@google.com>
diff --git a/src/gn/commands.cc b/src/gn/commands.cc
index a5f2ca9..cb44795 100644
--- a/src/gn/commands.cc
+++ b/src/gn/commands.cc
@@ -366,16 +366,22 @@
 
 // static
 bool CommandSwitches::Init(const base::CommandLine& cmdline) {
+  CHECK(!s_global_switches_.is_initialized())
+      << "Only call this once from main()";
   return s_global_switches_.InitFrom(cmdline);
 }
 
 // static
 const CommandSwitches& CommandSwitches::Get() {
+  CHECK(s_global_switches_.is_initialized())
+      << "Missing previous succesful call to CommandSwitches::Init()";
   return s_global_switches_;
 }
 
 // static
 CommandSwitches CommandSwitches::Set(CommandSwitches new_switches) {
+  CHECK(s_global_switches_.is_initialized())
+      << "Missing previous succesful call to CommandSwitches::Init()";
   CommandSwitches result = std::move(s_global_switches_);
   s_global_switches_ = std::move(new_switches);
   return result;
@@ -383,6 +389,7 @@
 
 bool CommandSwitches::InitFrom(const base::CommandLine& cmdline) {
   CommandSwitches result;
+  result.initialized_ = true;
   result.has_quiet_ = cmdline.HasSwitch("a");
   result.has_force_ = cmdline.HasSwitch("force");
   result.has_all_ = cmdline.HasSwitch("all");
diff --git a/src/gn/commands.h b/src/gn/commands.h
index 049ff85..acff044 100644
--- a/src/gn/commands.h
+++ b/src/gn/commands.h
@@ -209,10 +209,13 @@
   static CommandSwitches Set(CommandSwitches new_switches);
 
  private:
+  bool is_initialized() const { return initialized_; }
+
   bool InitFrom(const base::CommandLine&);
 
   static CommandSwitches s_global_switches_;
 
+  bool initialized_ = false;
   bool has_quiet_ = false;
   bool has_force_ = false;
   bool has_all_ = false;
diff --git a/src/gn/gn_main.cc b/src/gn/gn_main.cc
index e839b32..e1a0517 100644
--- a/src/gn/gn_main.cc
+++ b/src/gn/gn_main.cc
@@ -63,6 +63,9 @@
     args.erase(args.begin());
   }
 
+  if (!commands::CommandSwitches::Init(cmdline))
+    return 1;
+
   const commands::CommandInfoMap& command_map = commands::GetCommands();
   commands::CommandInfoMap::const_iterator found_command =
       command_map.find(command);