Automated rollback of commit 76c8c3a35776ecd6c568cf4ef1b6f2d2f52c0280.

*** Reason for rollback ***

Partially rolling back, because CapturingMapFn seems to be still applicable, see
https://github.com/bazelbuild/bazel/pull/14892

*** Original change description ***

Remove native proto_library implementation.

PiperOrigin-RevId: 440820625
diff --git a/src/main/java/com/google/devtools/build/lib/actions/CommandLineItem.java b/src/main/java/com/google/devtools/build/lib/actions/CommandLineItem.java
index 7b98379..5580b1c 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/CommandLineItem.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/CommandLineItem.java
@@ -57,6 +57,15 @@
     public abstract int maxInstancesAllowed();
   }
 
+  /**
+   * Use this map function when your map function needs to capture per-rule information.
+   *
+   * <p>Use of this class prevents sharing sub-computations over shared NestedSets, since the map
+   * function is per-target. This will make your action key computations become O(N^2). Please avoid
+   * if possible.
+   */
+  interface CapturingMapFn<T> extends MapFn<T> {}
+
   /** Expands the object into the command line as a string. */
   String expandToCommandLine();
 
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
index 1611817..29c0284 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
@@ -19,6 +19,7 @@
 import com.google.common.collect.Multiset;
 import com.google.devtools.build.lib.actions.CommandLineExpansionException;
 import com.google.devtools.build.lib.actions.CommandLineItem;
+import com.google.devtools.build.lib.actions.CommandLineItem.MapFn;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.vfs.DigestHashFunction;
 import java.util.HashSet;
@@ -44,6 +45,10 @@
   public <T> void addNestedSetToFingerprint(
       CommandLineItem.MapFn<? super T> mapFn, Fingerprint fingerprint, NestedSet<T> nestedSet)
       throws CommandLineExpansionException, InterruptedException {
+    if (mapFn instanceof CommandLineItem.CapturingMapFn) {
+      addNestedSetToFingerprintSlow(mapFn, fingerprint, nestedSet);
+      return;
+    }
     // Only top-level nested sets can be empty, so we can bail here
     if (nestedSet.isEmpty()) {
       fingerprint.addInt(EMPTY_SET_DIGEST);
@@ -55,6 +60,14 @@
     addToFingerprint(mapFn, fingerprint, digestMap, children);
   }
 
+  private <T> void addNestedSetToFingerprintSlow(
+      MapFn<? super T> mapFn, Fingerprint fingerprint, NestedSet<T> nestedSet)
+      throws CommandLineExpansionException, InterruptedException {
+    for (T object : nestedSet.toList()) {
+      addToFingerprint(mapFn, fingerprint, object);
+    }
+  }
+
   public void clear() {
     mapFnToDigestMap = createMap();
     seenMapFns.clear();
diff --git a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCacheTest.java b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCacheTest.java
index 216b3c3..87f5275 100644
--- a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCacheTest.java
+++ b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCacheTest.java
@@ -21,6 +21,7 @@
 import com.google.common.collect.Multiset;
 import com.google.devtools.build.lib.actions.CommandLineExpansionException;
 import com.google.devtools.build.lib.actions.CommandLineItem;
+import com.google.devtools.build.lib.actions.CommandLineItem.CapturingMapFn;
 import com.google.devtools.build.lib.actions.CommandLineItem.MapFn;
 import com.google.devtools.build.lib.util.Fingerprint;
 import java.util.function.Consumer;
@@ -141,6 +142,12 @@
           (s, args) -> args.accept(s + "_mapped"), new Fingerprint(), nestedSet);
     }
 
+    // Make sure a CapturingMapFn doesn't get denied
+    for (int i = 0; i < 2; ++i) {
+      cache.addNestedSetToFingerprint(
+          (CapturingMapFn<String>) (s, args) -> args.accept(s + 1), new Fingerprint(), nestedSet);
+    }
+
     // Make sure a ParametrizedMapFn doesn't get denied until it exceeds its instance count
     cache.addNestedSetToFingerprint(new IntParametrizedMapFn(1), new Fingerprint(), nestedSet);
     cache.addNestedSetToFingerprint(new IntParametrizedMapFn(2), new Fingerprint(), nestedSet);