flags: flag expiration support, take 2

This change implements flag expiration, with the same goal but a very
different method than the previous implementation
(https://chromium-review.googlesource.com/c/chromium/src/+/1729449).

This change preserves the flag-metadata.json file as the sole
authoritative source for flag expiration data. During the build process,
a new script (//tools/flags/generate_expired_list.py) generates a data
structure from flag-metadata.json listing flags that are expired at or
before the current milestone, with their expiration milestones. Logic in
//chrome/browser/about_flags.cc and //chrome/browser/unexpire_flags.cc
then conditionally hides these flags, depending on the state of the
unexpire flags - see //doc/flag_expiry.md for details about those.

Specifically, this change:
1) Renames //tools/flags/list-flags.py to list_flags.py to make it
   importable as a module;
2) Introduces //chrome/browser/expired_flags_list.h, which describes a
   data structure for representing expired flags;
3) Introduces //tools/flags/generate_expired_list.py, which takes as
   inputs //chrome/browser/flag-metadata.json and //chrome/VERSION and
   generates a C++ source file containing a data structure matching that
   in expired_flags_list.h;
4) Has the //chrome/browser build target depend on the generated file
   from step 3;
5) Re-introduces an unexpire flag as described in //doc/flag_expiry.md;
6) Adds logic to //chrome/browser/about_flags.cc to conditionally hide
   expired flags.

This means that flag-metadata.json is the sole determinant of whether a
flag is currently expired or not.

Note that this change expires all flags whose expiration milestones were
*M76* or earlier, not M78 (the current mstone); this is because the
backlog of flags to expire is currently quite large. In M79, we will
expire flags <= M78, then in M80, we will expire flags <= M80; after
that, each milestone Mx will expire flags <= Mx.

Also note that this change discards the notion of flag expiry depending
on usage metrics - i.e., we will now expire *all* flags that expire
before the target milestone, not just the N with the lowest usage. The
lowest-usage design proved to be extremely manual to implement and very
difficult for developers to predict the results of.

Bug: 953690
Change-Id: I7389b667d1e032c795c137cafadf0e5e80fb82c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1754762
Commit-Queue: Elly Fong-Jones <[email protected]>
Reviewed-by: Nico Weber <[email protected]>
Cr-Commit-Position: refs/heads/master@{#690742}
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 8304670..4f5182f8 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1195,8 +1195,8 @@
 extern const char kTurnOffStreamingMediaCachingName[];
 extern const char kTurnOffStreamingMediaCachingDescription[];
 
-extern const char kUnexpireFlagsM78Name[];
-extern const char kUnexpireFlagsM78Description[];
+extern const char kUnexpireFlagsM76Name[];
+extern const char kUnexpireFlagsM76Description[];
 
 extern const char kUnifiedConsentName[];
 extern const char kUnifiedConsentDescription[];