PiperOrigin-RevId: 162771369
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 07c139e..e0c6a93 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -970,6 +970,7 @@
         ":packages-internal",
         ":proto-rules",
         "//src/main/java/com/google/devtools/build/lib/actions",
+        "//third_party:guava",
     ],
 )
 
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
index 8698ce8..0430654 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
@@ -26,7 +26,7 @@
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
 import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
-import com.google.devtools.build.lib.rules.java.JavaLibraryHelper;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.proto.JavaProtoAspect;
 import com.google.devtools.build.lib.rules.java.proto.RpcSupport;
 import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
@@ -69,8 +69,8 @@
     }
 
     @Override
-    public void mutateJavaCompileAction(RuleContext ruleContext, JavaLibraryHelper helper) {
-      // Intentionally left empty.
+    public ImmutableList<JavaCompilationArgsProvider> getRuntimes(RuleContext ruleContext) {
+      return ImmutableList.of();
     }
 
     @Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
index d93f4db..7d51ede 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.rules.java;
 
+import static com.google.common.collect.Iterables.size;
+
 import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
@@ -21,7 +23,6 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import java.util.List;
 
 /**
  * An interface for objects that provide information on how to include them in
@@ -87,9 +88,9 @@
    */
   public abstract NestedSet<Artifact> getRunTimeJavaDependencyArtifacts();
 
-  public static JavaCompilationArgsProvider merge(List<JavaCompilationArgsProvider> providers) {
-    if (providers.size() == 1) {
-      return providers.get(0);
+  public static JavaCompilationArgsProvider merge(Iterable<JavaCompilationArgsProvider> providers) {
+    if (size(providers) == 1) {
+      return providers.iterator().next();
     }
 
     JavaCompilationArgs.Builder javaCompilationArgs = JavaCompilationArgs.builder();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ProtoJavaApiInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProtoJavaApiInfoProvider.java
index a6d05f9..07d9146 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/ProtoJavaApiInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProtoJavaApiInfoProvider.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import java.util.Map;
 import javax.annotation.Nullable;
@@ -42,9 +43,12 @@
       Artifact sourceJar1,
       Artifact sourceJarMutable,
       Artifact sourceJarImmutable,
-      ImmutableList<JavaCompilationArgsProvider> protoRuntime1,
-      ImmutableList<JavaCompilationArgsProvider> protoRuntimeMutable,
-      ImmutableList<JavaCompilationArgsProvider> protoRuntimeImmutable,
+      @Nullable ImmutableList<JavaCompilationArgsProvider> protoRuntime1,
+      @Nullable ImmutableList<JavaCompilationArgsProvider> protoRuntimeMutable,
+      @Nullable ImmutableList<JavaCompilationArgsProvider> protoRuntimeImmutable,
+      NestedSet<JavaCompilationArgsProvider> transitiveProtoRuntime1,
+      NestedSet<JavaCompilationArgsProvider> transitiveProtoRuntimeMutable,
+      NestedSet<JavaCompilationArgsProvider> transitiveProtoRuntimeImmutable,
       Map<Artifact, Artifact> compileTimeJarToRuntimeJar,
       boolean mixedApiVersions,
       int apiVersion,
@@ -67,6 +71,9 @@
         protoRuntime1,
         protoRuntimeMutable,
         protoRuntimeImmutable,
+        transitiveProtoRuntime1,
+        transitiveProtoRuntimeMutable,
+        transitiveProtoRuntimeImmutable,
         mixedApiVersions,
         apiVersion,
         supportsProto1,
@@ -152,6 +159,14 @@
   @Nullable
   public abstract ImmutableList<JavaCompilationArgsProvider> getProtoRuntimeImmutable();
 
+  // The following 3 fields are the jars that proto_library got from the proto runtime, and their
+  // transitive dependencies..
+  public abstract NestedSet<JavaCompilationArgsProvider> getTransitiveProtoRuntime1();
+
+  public abstract NestedSet<JavaCompilationArgsProvider> getTransitiveProtoRuntimeMutable();
+
+  public abstract NestedSet<JavaCompilationArgsProvider> getTransitiveProtoRuntimeImmutable();
+
   /**
    * Returns true if the transitive closure contains libraries with API versions other than the one
    * specified in this target. Building in mixed mode will add implicit deps for all the api_version
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
index 5d8e296..255ca08 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/ActionReuser.java
@@ -36,6 +36,7 @@
 import com.google.devtools.build.lib.rules.java.JavaSkylarkApiProvider;
 import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
 import com.google.devtools.build.lib.rules.java.ProtoJavaApiInfoProvider;
+import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
 
 public class ActionReuser {
 
@@ -57,25 +58,39 @@
       return false;
     }
 
-    JavaCompilationArgs transitiveJars =
-        JavaCompilationArgs.builder()
-            .addTransitiveArgs(javaApi.getTransitiveJavaCompilationArgsImmutable(), BOTH)
-            .addTransitiveDependencies(javaApi.getProtoRuntimeImmutable(), true /* recursive */)
-            .merge(directJars)
-            .build();
-
     Artifact outputJar = getOnlyElement(directJars.getRuntimeJars());
     Artifact compileTimeJar = getOnlyElement(directJars.getCompileTimeJars());
     Artifact sourceJar = checkNotNull(javaApi.sourceJarImmutable());
 
+    boolean jplNonStrictDepsLikePl =
+        ruleContext
+            .getConfiguration()
+            .getFragment(ProtoConfiguration.class)
+            .jplNonStrictDepsLikePl();
+
     JavaCompilationArgsProvider compilationArgsProvider =
         JavaCompilationArgsProvider.create(
             JavaCompilationArgs.builder().merge(directJars).build(),
-            transitiveJars,
+            collectTransitiveJarsFromUnderlyingProtoLibrary(
+                javaApi, true /* includeDepsOfProtoRuntimes */, jplNonStrictDepsLikePl),
             NestedSetBuilder.create(
                 Order.STABLE_ORDER, directJars.getCompileTimeDependencyArtifact()),
             NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER));
 
+    // Used when java_proto_library specifies strict_deps=0. It's almost the same as pouring the
+    // transitiveJars into the direct jars (i.e., the second parameter into the first) except that
+    // the transitive dependencies of the proto runtime themselves are _not_ included.
+    //
+    // Unlike JavaProtoAspect.Impl.createNonStrictCompilationArgsProvider(), this JCAP is used when
+    // reusing actions created by the underlying proto_library.
+    JavaCompilationArgsProvider nonStrictCompArgsProvider =
+        JavaCompilationArgsProvider.create(
+            collectTransitiveJarsFromUnderlyingProtoLibrary(
+                javaApi, false /* includeDepsOfProtoRuntimes */, jplNonStrictDepsLikePl),
+            compilationArgsProvider.getRecursiveJavaCompilationArgs(),
+            compilationArgsProvider.getCompileTimeJavaDependencyArtifacts(),
+            compilationArgsProvider.getRunTimeJavaDependencyArtifacts());
+
     TransitiveInfoProviderMapBuilder javaProvidersBuilder =
         new TransitiveInfoProviderMapBuilder()
             .add(createOutputJarProvider(outputJar, compileTimeJar, sourceJar))
@@ -95,10 +110,37 @@
             JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
             JavaSkylarkApiProvider.fromProviderMap(javaProviders))
         .addProviders(
-            new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+            new JavaProtoLibraryAspectProvider(
+                javaProviders, transitiveOutputJars.build(), nonStrictCompArgsProvider));
     return true;
   }
 
+  /**
+   * Collects all jars produced+provided by the underlying proto_library, and its dependencies.
+   *
+   * <p>This contains almost all jars required to compile and run against the underlying
+   * proto_library.
+   *
+   * @param includeDepsOfProtoRuntimes if true, includes the jars of the dependencies of the proto
+   *     runtime, which are needed for runtime. If false, doesn't return these dependencies, which
+   *     is useful to mimic non-strict behavior in java_xxx_proto_library.
+   */
+  private static JavaCompilationArgs collectTransitiveJarsFromUnderlyingProtoLibrary(
+      ProtoJavaApiInfoProvider javaApi,
+      boolean includeDepsOfProtoRuntimes,
+      boolean jplNonStrictDepsLikePl) {
+    JavaCompilationArtifacts directJars = javaApi.getJavaCompilationArtifactsImmutable();
+    return JavaCompilationArgs.builder()
+        .addTransitiveArgs(javaApi.getTransitiveJavaCompilationArgsImmutable(), BOTH)
+        .addTransitiveDependencies(
+            jplNonStrictDepsLikePl
+                ? javaApi.getTransitiveProtoRuntimeImmutable()
+                : javaApi.getProtoRuntimeImmutable(),
+            includeDepsOfProtoRuntimes)
+        .merge(directJars)
+        .build();
+  }
+
   private static JavaRuleOutputJarsProvider createOutputJarProvider(
       Artifact outputJar, Artifact compileTimeJar, Artifact sourceJar) {
     return JavaRuleOutputJarsProvider.builder()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
index 07ddb04..0083597 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
 import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET;
 import static com.google.devtools.build.lib.cmdline.Label.parseAbsoluteUnchecked;
 import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
@@ -63,6 +64,7 @@
 import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoSupportDataProvider;
 import com.google.devtools.build.lib.rules.proto.SupportData;
+import java.util.ArrayList;
 import javax.annotation.Nullable;
 
 /** An Aspect which JavaLiteProtoLibrary injects to build Java Lite protos. */
@@ -227,7 +229,26 @@
               JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
               JavaSkylarkApiProvider.fromProviderMap(javaProviders))
           .addProvider(
-              new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+              new JavaProtoLibraryAspectProvider(
+                  javaProviders,
+                  transitiveOutputJars.build(),
+                  createNonStrictCompilationArgsProvider(generatedCompilationArgsProvider)));
+    }
+
+    /**
+     * Creates a JavaCompilationArgsProvider that's used when java_lite_proto_library sets
+     * strict_deps=0. It contains the jars we produced, as well as all transitive proto jars, and
+     * the proto runtime jars, all described as direct dependencies.
+     */
+    private JavaCompilationArgsProvider createNonStrictCompilationArgsProvider(
+        JavaCompilationArgsProvider generatedCompilationArgsProvider) {
+      ArrayList<JavaCompilationArgsProvider> providers = new ArrayList<>(3);
+      providers.add(
+          JavaCompilationArgsProvider.merge(
+              transform(javaProtoLibraryAspectProviders, p -> p.getNonStrictCompArgsProvider())));
+      providers.add(generatedCompilationArgsProvider);
+      providers.addAll(getProtoRuntimeDeps());
+      return JavaCompilationArgsProvider.merge(providers);
     }
 
     private void createProtoCompileAction(Artifact sourceJar) {
@@ -252,12 +273,10 @@
               .setOutput(outputJar)
               .addSourceJars(sourceJar)
               .setJavacOpts(ProtoJavacOpts.constructJavacOpts(ruleContext));
-      helper.addDep(dependencyCompilationArgs);
-      TransitiveInfoCollection runtime = getProtoToolchainProvider().runtime();
-      if (runtime != null) {
-        helper.addDep(runtime.getProvider(JavaCompilationArgsProvider.class));
-      }
-      helper.setCompilationStrictDepsMode(StrictDepsMode.OFF);
+      helper
+          .addDep(dependencyCompilationArgs)
+          .addAllDeps(getProtoRuntimeDeps())
+          .setCompilationStrictDepsMode(StrictDepsMode.OFF);
       JavaCompilationArtifacts artifacts =
           helper.build(
               javaSemantics,
@@ -267,6 +286,13 @@
       return helper.buildCompilationArgsProvider(artifacts, true /* isReportedAsStrict */);
     }
 
+    private ImmutableList<JavaCompilationArgsProvider> getProtoRuntimeDeps() {
+      TransitiveInfoCollection runtime = getProtoToolchainProvider().runtime();
+      return runtime != null
+          ? ImmutableList.of(runtime.getProvider(JavaCompilationArgsProvider.class))
+          : ImmutableList.of();
+    }
+
     private ProtoLangToolchainProvider getProtoToolchainProvider() {
       return checkNotNull(
           ruleContext.getPrerequisite(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
index 705f324..8399089 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoLibrary.java
@@ -55,13 +55,7 @@
         ruleContext.getPrerequisites("deps", Mode.TARGET, JavaProtoLibraryAspectProvider.class);
 
     JavaCompilationArgsProvider dependencyArgsProviders =
-        JavaCompilationArgsProvider.merge(
-            WrappingProvider.Helper.unwrapProviders(
-                javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
-
-    if (!StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
-      dependencyArgsProviders = StrictDepsUtils.makeNonStrict(dependencyArgsProviders);
-    }
+        StrictDepsUtils.constructJcapFromAspectDeps(ruleContext, javaProtoLibraryAspectProviders);
 
     Runfiles runfiles =
         new Runfiles.Builder(ruleContext.getWorkspaceName())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
index 398494c..11dbcfa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
 import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET;
 import static com.google.devtools.build.lib.cmdline.Label.parseAbsoluteUnchecked;
 import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
@@ -63,6 +64,7 @@
 import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoSupportDataProvider;
 import com.google.devtools.build.lib.rules.proto.SupportData;
+import java.util.ArrayList;
 import javax.annotation.Nullable;
 
 /** An Aspect which JavaProtoLibrary injects to build Java SPEED protos. */
@@ -243,7 +245,29 @@
               JavaSkylarkApiProvider.PROTO_NAME.getLegacyId(),
               JavaSkylarkApiProvider.fromProviderMap(javaProviders))
           .addProvider(
-              new JavaProtoLibraryAspectProvider(javaProviders, transitiveOutputJars.build()));
+              new JavaProtoLibraryAspectProvider(
+                  javaProviders,
+                  transitiveOutputJars.build(),
+                  createNonStrictCompilationArgsProvider(generatedCompilationArgsProvider)));
+    }
+
+    /**
+     * Creates a JavaCompilationArgsProvider that's used when java_proto_library sets strict_deps=0.
+     * It contains the jars we produced, as well as all transitive proto jars, and the proto runtime
+     * jars, all described as direct dependencies.
+     *
+     * <p>This method is used when JavaProtoAspect is creating actions itself, as opposed to reusing
+     * ones created by the underlying proto_library.
+     */
+    private JavaCompilationArgsProvider createNonStrictCompilationArgsProvider(
+        JavaCompilationArgsProvider generatedCompilationArgsProvider) {
+      ArrayList<JavaCompilationArgsProvider> providers = new ArrayList<>(5);
+      providers.add(
+          JavaCompilationArgsProvider.merge(
+              transform(javaProtoLibraryAspectProviders, p -> p.getNonStrictCompArgsProvider())));
+      providers.add(generatedCompilationArgsProvider);
+      providers.addAll(getProtoRuntimeDeps());
+      return JavaCompilationArgsProvider.merge(providers);
     }
 
     /**
@@ -290,13 +314,11 @@
               .setOutput(outputJar)
               .addSourceJars(sourceJar)
               .setJavacOpts(ProtoJavacOpts.constructJavacOpts(ruleContext));
-      helper.addDep(dependencyCompilationArgs).setCompilationStrictDepsMode(StrictDepsMode.OFF);
-      TransitiveInfoCollection runtime = getProtoToolchainProvider().runtime();
-      if (runtime != null) {
-        helper.addDep(runtime.getProvider(JavaCompilationArgsProvider.class));
-      }
+      helper
+          .addDep(dependencyCompilationArgs)
+          .addAllDeps(getProtoRuntimeDeps())
+          .setCompilationStrictDepsMode(StrictDepsMode.OFF);
 
-      rpcSupport.mutateJavaCompileAction(ruleContext, helper);
       return helper.buildCompilationArgsProvider(
           helper.build(
               javaSemantics,
@@ -306,6 +328,16 @@
           true /* isReportedAsStrict */);
     }
 
+    private ImmutableList<JavaCompilationArgsProvider> getProtoRuntimeDeps() {
+      ImmutableList.Builder<JavaCompilationArgsProvider> result = ImmutableList.builder();
+      TransitiveInfoCollection runtime = getProtoToolchainProvider().runtime();
+      if (runtime != null) {
+        result.add(runtime.getProvider(JavaCompilationArgsProvider.class));
+      }
+      result.addAll(rpcSupport.getRuntimes(ruleContext));
+      return result.build();
+    }
+
     private ProtoLangToolchainProvider getProtoToolchainProvider() {
       return ruleContext.getPrerequisite(
           SPEED_PROTO_TOOLCHAIN_ATTR, TARGET, ProtoLangToolchainProvider.class);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
index 96cd2a7..de68362 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
@@ -46,13 +46,7 @@
         ruleContext.getPrerequisites("deps", TARGET, JavaProtoLibraryAspectProvider.class);
 
     JavaCompilationArgsProvider dependencyArgsProviders =
-        JavaCompilationArgsProvider.merge(
-            WrappingProvider.Helper.unwrapProviders(
-                javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
-
-    if (!StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
-      dependencyArgsProviders = StrictDepsUtils.makeNonStrict(dependencyArgsProviders);
-    }
+        StrictDepsUtils.constructJcapFromAspectDeps(ruleContext, javaProtoLibraryAspectProviders);
 
     Runfiles runfiles =
         new Runfiles.Builder(ruleContext.getWorkspaceName())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
index 3124e54..4f4afce 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java
@@ -18,16 +18,21 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
 import com.google.devtools.build.lib.analysis.WrappingProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 
 /** A provider used to communicate information between java_proto_library and its aspect. */
 public class JavaProtoLibraryAspectProvider implements WrappingProvider {
   private final TransitiveInfoProviderMap transitiveInfoProviderMap;
   private final NestedSet<Artifact> jars;
+  private final JavaCompilationArgsProvider nonStrictCompArgsProvider;
 
   public JavaProtoLibraryAspectProvider(
-      TransitiveInfoProviderMap transitiveInfoProviderMap, NestedSet<Artifact> jars) {
+      TransitiveInfoProviderMap transitiveInfoProviderMap,
+      NestedSet<Artifact> jars,
+      JavaCompilationArgsProvider nonStrictCompArgsProvider) {
     this.transitiveInfoProviderMap = transitiveInfoProviderMap;
     this.jars = jars;
+    this.nonStrictCompArgsProvider = nonStrictCompArgsProvider;
   }
 
   @Override
@@ -38,4 +43,8 @@
   public NestedSet<Artifact> getJars() {
     return jars;
   }
+
+  public JavaCompilationArgsProvider getNonStrictCompArgsProvider() {
+    return nonStrictCompArgsProvider;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
index 44a1c06..73ec196 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
@@ -14,12 +14,13 @@
 
 package com.google.devtools.build.lib.rules.java.proto;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.rules.java.JavaLibraryHelper;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
 import java.util.List;
 
@@ -37,7 +38,7 @@
   void mutateProtoCompileAction(
       RuleContext ruleContext, Artifact sourceJar, ProtoCompileActionBuilder actionBuilder);
 
-  void mutateJavaCompileAction(RuleContext ruleContext, JavaLibraryHelper helper);
+  ImmutableList<JavaCompilationArgsProvider> getRuntimes(RuleContext ruleContext);
 
   void mutateAspectDefinition(AspectDefinition.Builder def, AspectParameters aspectParameters);
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
index 8b9d5c2..fb12ed0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java
@@ -14,16 +14,46 @@
 
 package com.google.devtools.build.lib.rules.java.proto;
 
+import static com.google.common.collect.Iterables.transform;
 import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.BOTH;
 
 import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.WrappingProvider;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgs;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
+import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
 
 public class StrictDepsUtils {
 
   /**
+   * Used in JavaXXXProtoLibrary.java files to construct a JCAP from 'deps', where those were
+   * populated by the Aspect it injected.
+   *
+   * <p>Takes care of strict deps.
+   */
+  public static JavaCompilationArgsProvider constructJcapFromAspectDeps(
+      RuleContext ruleContext,
+      Iterable<JavaProtoLibraryAspectProvider> javaProtoLibraryAspectProviders) {
+    if (StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) {
+      return JavaCompilationArgsProvider.merge(
+          WrappingProvider.Helper.unwrapProviders(
+              javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class));
+    } else if (ruleContext
+        .getConfiguration()
+        .getFragment(ProtoConfiguration.class)
+        .jplNonStrictDepsLikePl()) {
+      return JavaCompilationArgsProvider.merge(
+          transform(javaProtoLibraryAspectProviders, p -> p.getNonStrictCompArgsProvider()));
+    } else {
+      return StrictDepsUtils.makeNonStrict(
+          JavaCompilationArgsProvider.merge(
+              WrappingProvider.Helper.unwrapProviders(
+                  javaProtoLibraryAspectProviders, JavaCompilationArgsProvider.class)));
+    }
+  }
+
+  /**
    * Returns true iff 'ruleContext' should enforce strict-deps.
    *
    * <p>Using this method requires requesting the JavaConfiguration fragment.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
index 23e76dd..91e0395 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
@@ -154,6 +154,19 @@
     )
     public List<String> ccProtoLibrarySourceSuffixes;
 
+    @Option(
+      name = "jplNonStrictDepsLikePl",
+      defaultValue = "false",
+      category = "rollout",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS},
+      metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE},
+      help =
+          "Roll-out flag for changing behavior of non-strict java_xxx_proto_library. "
+              + "See commit description for details. DO NOT USE."
+    )
+    public boolean jplNonStrictDepsLikePl;
+
     @Override
     public FragmentOptions getHost(boolean fallback) {
       Options host = (Options) super.getHost(fallback);
@@ -167,6 +180,7 @@
       host.strictProtoDeps = strictProtoDeps;
       host.ccProtoLibraryHeaderSuffixes = ccProtoLibraryHeaderSuffixes;
       host.ccProtoLibrarySourceSuffixes = ccProtoLibrarySourceSuffixes;
+      host.jplNonStrictDepsLikePl = jplNonStrictDepsLikePl;
       return host;
     }
   }
@@ -244,4 +258,8 @@
   public List<String> ccProtoLibrarySourceSuffixes() {
     return ccProtoLibrarySourceSuffixes;
   }
+
+  public boolean jplNonStrictDepsLikePl() {
+    return options.jplNonStrictDepsLikePl;
+  }
 }