Add BASE_FEATURE() / BASE_DECLARE_FEATURE() macros for defining features

There are subtle requirements around declaring and defining
base::Features. In addition, these requirements also evolve over time:
updating the various uses requires updating an estimated 6000+ uses.

Introduce helper macros modelled after absl's ABSL_FLAG() and
ABSL_DECLARE_FLAG() macros instead; in the future, base::Feature may
even become an internal implementation detail.

This also simplifies the helper script for autogenerating Java features
from C++ features, as it no longer needs to try to accommodate all
potential reorderings of `CONSTINIT`, `const`, and export macros.

Bug: 1364289
Change-Id: Id88f7c4a60efa28cdab36accb4d8386ec84ea3e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3902697
Reviewed-by: Egor Pasko <[email protected]>
Reviewed-by: Alexei Svitkine <[email protected]>
Commit-Queue: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1048852}
diff --git a/build/android/gyp/java_cpp_features.py b/build/android/gyp/java_cpp_features.py
index 01d650d..5aeb219 100755
--- a/build/android/gyp/java_cpp_features.py
+++ b/build/android/gyp/java_cpp_features.py
@@ -15,16 +15,24 @@
 
 
 class FeatureParserDelegate(java_cpp_utils.CppConstantParser.Delegate):
+  # Ex. 'BASE_FEATURE(kConstantName, "StringNameOfTheFeature", ...);'
+  # would parse as:
+  #   ExtractConstantName() -> 'ConstantName'
+  #   ExtractValue() -> '"StringNameOfTheFeature"'
+  FEATURE_RE = re.compile(r'BASE_FEATURE\(k([^,]+),')
   # Ex. 'const base::Feature kConstantName{"StringNameOfTheFeature", ...};'
   # would parse as:
   #   ExtractConstantName() -> 'ConstantName'
   #   ExtractValue() -> '"StringNameOfTheFeature"'
-  FEATURE_RE = re.compile(
+  LEGACY_FEATURE_RE = re.compile(
       r'\s*const(?:\s+\w+_EXPORT)? (?:base::)?Feature\s+k(\w+)\s*(?:=\s*)?')
   VALUE_RE = re.compile(r'\s*("(?:\"|[^"])*")\s*,')
 
   def ExtractConstantName(self, line):
     match = FeatureParserDelegate.FEATURE_RE.match(line)
+    if match:
+      return match.group(1)
+    match = FeatureParserDelegate.LEGACY_FEATURE_RE.match(line)
     return match.group(1) if match else None
 
   def ExtractValue(self, line):