check-flagged-apis: handle nested flags

Consider

  @FlaggedApi(FLAG_OUTER) Clazz {
      @FlaggedApi(FLAG_INNER) method();
  }

If FLAG_OUTER is disabled, any class members are ignored. Teach
check-flagged-apis to recognize this and stop reporting false positives.

Bug: 339183637
Test: atest --host check-flagged-apis-test
Change-Id: Ie6799e952dc33874c1239231f841d7dfd947c7ce
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index b514048..a277ce8 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -385,10 +385,48 @@
 
     return false
   }
+
+  /**
+   * Returns whether the given flag is enabled for the given symbol.
+   *
+   * A flagged member inside a flagged class is ignored (and the flag value considered disabled) if
+   * the class' flag is disabled.
+   *
+   * @param symbol the symbol to check
+   * @param flag the flag to check
+   * @return whether the flag is enabled for the given symbol
+   */
+  fun isFlagEnabledForSymbol(symbol: Symbol, flag: Flag): Boolean {
+    when (symbol) {
+      is ClassSymbol -> return flags.getValue(flag)
+      is MemberSymbol -> {
+        val memberFlagValue = flags.getValue(flag)
+        if (!memberFlagValue) {
+          return false
+        }
+        // Special case: if the MemberSymbol's flag is enabled, but the outer
+        // ClassSymbol's flag (if the class is flagged) is disabled, consider
+        // the MemberSymbol's flag as disabled:
+        //
+        //   @FlaggedApi(this-flag-is-disabled) Clazz {
+        //       @FlaggedApi(this-flag-is-enabled) method(); // The Clazz' flag "wins"
+        //   }
+        //
+        // Note: the current implementation does not handle nested classes.
+        val classFlagValue =
+            flaggedSymbolsInSource
+                .find { it.first.toPrettyString() == symbol.clazz }
+                ?.let { flags.getValue(it.second) }
+                ?: true
+        return classFlagValue
+      }
+    }
+  }
+
   val errors = mutableSetOf<ApiError>()
   for ((symbol, flag) in flaggedSymbolsInSource) {
     try {
-      if (flags.getValue(flag)) {
+      if (isFlagEnabledForSymbol(symbol, flag)) {
         if (!symbolsInOutput.containsSymbol(symbol)) {
           errors.add(EnabledFlaggedApiNotPresentError(symbol, flag))
         }