Add flag to disallow keeping runtime invisible annotations

Bug: b/387958004
Change-Id: I2ed80a174d505f5814e2d2a6c2c3ad79a86080ca
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 11577a1..6bc6803 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -752,9 +752,10 @@
       DesugaredLibrarySpecification desugaredLibrarySpecification =
           getDesugaredLibraryConfiguration(factory, false);
 
+      ProguardConfigurationParserOptions parserOptions = parserOptionsBuilder.build();
       ProguardConfigurationParser parser =
           new ProguardConfigurationParser(
-              factory, reporter, parserOptionsBuilder.build(), inputDependencyGraphConsumer);
+              factory, reporter, parserOptions, inputDependencyGraphConsumer);
       ProguardConfiguration.Builder configurationBuilder =
           parser
               .getConfigurationBuilder()
@@ -787,6 +788,14 @@
       // TODO(b/248408342): Remove this and parse annotations as part of R8 root-set & enqueuer.
       extractKeepAnnotationRules(parser);
       ProguardConfiguration configuration = configurationBuilder.build();
+      if (!parserOptions.isKeepRuntimeInvisibleAnnotationsEnabled()) {
+        if (configuration.getKeepAttributes().runtimeInvisibleAnnotations
+            || configuration.getKeepAttributes().runtimeInvisibleParameterAnnotations
+            || configuration.getKeepAttributes().runtimeInvisibleTypeAnnotations) {
+          throw fatalError(
+              new StringDiagnostic("Illegal attempt to keep runtime invisible annotations"));
+        }
+      }
       getAppBuilder().addFilteredLibraryArchives(configuration.getLibraryjars());
 
       assert getProgramConsumer() != null;
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 95e0fde..ee01c44 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -759,7 +759,7 @@
     }
 
     private void parseKeepAttributes() throws ProguardRuleParserException {
-      List<String> attributesPatterns = acceptPatternList();
+      List<String> attributesPatterns = acceptKeepAttributesPatternList();
       if (attributesPatterns.isEmpty()) {
         throw parseError("Expected attribute pattern list");
       }
@@ -2015,11 +2015,11 @@
       return contents.substring(start, end);
     }
 
-    private List<String> acceptPatternList() throws ProguardRuleParserException {
+    private List<String> acceptKeepAttributesPatternList() throws ProguardRuleParserException {
       List<String> patterns = new ArrayList<>();
       skipWhitespace();
       char quote = acceptQuoteIfPresent();
-      String pattern = acceptPattern();
+      String pattern = acceptKeepAttributesPattern();
       if (isQuote(quote)) {
         expectClosingQuote(quote);
       }
@@ -2030,7 +2030,7 @@
           skipWhitespace();
           TextPosition start = getPosition();
           quote = acceptQuoteIfPresent();
-          pattern = acceptPattern();
+          pattern = acceptKeepAttributesPattern();
           if (isQuote(quote)) {
             expectClosingQuote(quote);
           }
@@ -2048,7 +2048,7 @@
       return patterns;
     }
 
-    private String acceptPattern() {
+    private String acceptKeepAttributesPattern() {
       return acceptString(
           codePoint ->
               IdentifierUtils.isDexIdentifierPart(codePoint)
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParserOptions.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParserOptions.java
index ab5db09..fcc499b 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParserOptions.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParserOptions.java
@@ -13,6 +13,7 @@
   private final boolean enableExperimentalCheckEnumUnboxed;
   private final boolean enableExperimentalConvertCheckNotNull;
   private final boolean enableExperimentalWhyAreYouNotInlining;
+  private final boolean enableKeepRuntimeInvisibleAnnotations;
   private final boolean enableTestingOptions;
 
   ProguardConfigurationParserOptions(
@@ -21,10 +22,12 @@
       boolean enableExperimentalCheckEnumUnboxed,
       boolean enableExperimentalConvertCheckNotNull,
       boolean enableExperimentalWhyAreYouNotInlining,
+      boolean enableKeepRuntimeInvisibleAnnotations,
       boolean enableTestingOptions) {
     this.enableExperimentalCheckEnumUnboxed = enableExperimentalCheckEnumUnboxed;
     this.enableExperimentalConvertCheckNotNull = enableExperimentalConvertCheckNotNull;
     this.enableExperimentalWhyAreYouNotInlining = enableExperimentalWhyAreYouNotInlining;
+    this.enableKeepRuntimeInvisibleAnnotations = enableKeepRuntimeInvisibleAnnotations;
     this.enableTestingOptions = enableTestingOptions;
     this.enableLegacyFullModeForKeepRules = enableLegacyFullModeForKeepRules;
     this.enableLegacyFullModeForKeepRulesWarnings = enableLegacyFullModeForKeepRulesWarnings;
@@ -59,6 +62,10 @@
     return enableExperimentalWhyAreYouNotInlining;
   }
 
+  public boolean isKeepRuntimeInvisibleAnnotationsEnabled() {
+    return enableKeepRuntimeInvisibleAnnotations;
+  }
+
   public boolean isTestingOptionsEnabled() {
     return enableTestingOptions;
   }
@@ -70,6 +77,7 @@
     private boolean enableExperimentalCheckEnumUnboxed;
     private boolean enableExperimentalConvertCheckNotNull;
     private boolean enableExperimentalWhyAreYouNotInlining;
+    private boolean enableKeepRuntimeInvisibleAnnotations = true;
     private boolean enableTestingOptions;
 
     public Builder readEnvironment() {
@@ -88,6 +96,9 @@
       enableExperimentalWhyAreYouNotInlining =
           parseSystemPropertyOrDefault(
               "com.android.tools.r8.experimental.enablewhyareyounotinlining", false);
+      enableKeepRuntimeInvisibleAnnotations =
+          parseSystemPropertyOrDefault(
+              "com.android.tools.r8.enableKeepRuntimeInvisibleAnnotations", true);
       enableTestingOptions =
           parseSystemPropertyOrDefault("com.android.tools.r8.allowTestProguardOptions", false);
       return this;
@@ -134,6 +145,7 @@
           enableExperimentalCheckEnumUnboxed,
           enableExperimentalConvertCheckNotNull,
           enableExperimentalWhyAreYouNotInlining,
+          enableKeepRuntimeInvisibleAnnotations,
           enableTestingOptions);
     }
   }