Rollback of commit b043fafb957ae8038088e427ff27a5c9f951c979.

*** Reason for rollback ***

Use proto_lang_toolchain() in java_proto_library, after fixing breakage.
Verified on Jenkins, http://ci.bazel.io/job/Gerrit-bazel-tests/169/

*** Original change description ***

Automated [] rollback of commit a396b070ae36032a973672e11145533621c39edc.

*** Reason for rollback ***

Breaks tests on latest, as proto_lang_toolchain didn't make it into the 0.4.0 release

see http://ci.bazel.io/job/bazel-tests/306/BAZEL_VERSION=latest,PLATFORM_NAME=linux-x86_64/console

*** Original change description ***

Use proto_lang_toolchain() in java_proto_library.

--
MOS_MIGRATED_REVID=138432193
diff --git a/WORKSPACE b/WORKSPACE
index b06d57f..cace908 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -52,6 +52,7 @@
 
 bind(name = "protobuf/java_runtime", actual = "//third_party/protobuf:protobuf")
 bind(name = "protobuf/javalite_runtime", actual = "//third_party/protobuf:protobuf-lite")
+bind(name = "proto/toolchains/java", actual = "//third_party/protobuf:java_toolchain")
 
 # For Skylark tests at //src/test/shell/bazel:maven_skylark_test
 # Uncomment the following lines, and the test in src/test/shell/bazel/BUILD to run it.
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 62b0cdb..a7a0fe5 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -813,6 +813,7 @@
     srcs = ["rules/java/proto/RpcSupport.java"],
     deps = [
         ":build-base",
+        ":collect",
         ":java-compilation",
         ":packages-internal",
         ":proto-rules",
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 ab062dd..8dd2ae2 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
@@ -14,15 +14,21 @@
 
 package com.google.devtools.build.lib.bazel.rules.java.proto;
 
+import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER;
+
+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.bazel.rules.java.BazelJavaSemantics;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 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.proto.JavaProtoAspect;
 import com.google.devtools.build.lib.rules.java.proto.RpcSupport;
 import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
+import java.util.List;
 
 /** An Aspect which BazelJavaProtoLibrary injects to build Java SPEED protos. */
 public class BazelJavaProtoAspect extends JavaProtoAspect {
@@ -37,8 +43,24 @@
   private static class NoopRpcSupport
       implements RpcSupport {
     @Override
-    public void mutateProtoCompileAction(
-        RuleContext ruleContext, Artifact sourceJar, ProtoCompileActionBuilder actionBuilder) {
+    public List<ProtoCompileActionBuilder.ToolchainInvocation> getToolchainInvocation(
+        RuleContext ruleContext, Artifact sourceJar) {
+      return ImmutableList.of();
+    }
+
+    @Override
+    public boolean allowServices(RuleContext ruleContext) {
+      return true;
+    }
+
+    @Override
+    public NestedSet<Artifact> getBlacklist(RuleContext ruleContext) {
+      return NestedSetBuilder.emptySet(STABLE_ORDER);
+    }
+
+    @Override
+    public void mutateProtoCompileAction(RuleContext ruleContext, Artifact sourceJar,
+        ProtoCompileActionBuilder actionBuilder) {
       // Intentionally left empty.
     }
 
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 ba6184e..02308f7 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
@@ -33,6 +33,7 @@
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -54,7 +55,9 @@
 import com.google.devtools.build.lib.rules.java.JavaSemantics;
 import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
+import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder.ToolchainInvocation;
 import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
+import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoSourceFileBlacklist;
 import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoSupportDataProvider;
@@ -65,6 +68,8 @@
 /** An Aspect which JavaProtoLibrary injects to build Java SPEED protos. */
 public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspectFactory {
 
+  private static final String SPEED_PROTO_TOOLCHAIN_ATTR = ":aspect_java_proto_toolchain";
+
   private static final String SPEED_PROTO_RUNTIME_ATTR = "$aspect_java_lib";
   private static final String SPEED_PROTO_RUNTIME_LABEL = "//external:protobuf/java_runtime";
 
@@ -91,6 +96,15 @@
         }
       };
 
+  private static final Attribute.LateBoundLabel<BuildConfiguration> SPEED_PROTO_TOOLCHAIN_LABEL =
+      new Attribute.LateBoundLabel<BuildConfiguration>(
+          "//tools/proto/toolchains:java", ProtoConfiguration.class) {
+        @Override
+        public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
+          return configuration.getFragment(ProtoConfiguration.class).protoToolchainForJava();
+        }
+      };
+
   private final JavaSemantics javaSemantics;
 
   @Nullable private final String jacocoLabel;
@@ -128,7 +142,8 @@
                     .getFragment(ProtoConfiguration.class, ConfigurationTransition.HOST)
                     .protoCompilerJavaFlags(),
                 javaSemantics,
-                rpcSupport)
+                rpcSupport,
+                ruleContext.getFragment(ProtoConfiguration.class).useToolchainForJavaProto())
             .createProviders());
 
     return aspect.build();
@@ -149,6 +164,12 @@
                 attr(PROTO_SOURCE_FILE_BLACKLIST_ATTR, LABEL_LIST)
                     .cfg(HOST)
                     .value(BLACKLISTED_PROTOS))
+            .add(
+                attr(SPEED_PROTO_TOOLCHAIN_ATTR, LABEL)
+                    // TODO(carmi): reinstate mandatoryNativeProviders(ProtoLangToolchainProvider)
+                    // once it's in a Bazel release.
+                    .legacyAllowAnyFileType()
+                    .value(SPEED_PROTO_TOOLCHAIN_LABEL))
             .add(attr(":host_jdk", LABEL).cfg(HOST).value(JavaSemantics.HOST_JDK))
             .add(
                 attr(":java_toolchain", LABEL)
@@ -179,18 +200,21 @@
      */
     private final JavaCompilationArgsProvider dependencyCompilationArgs;
     private final String protoCompilerPluginOptions;
+    private final boolean useToolchainForJavaProto;
 
     Impl(
         final RuleContext ruleContext,
         final SupportData supportData,
         String protoCompilerPluginOptions,
         JavaSemantics javaSemantics,
-        RpcSupport rpcSupport) {
+        RpcSupport rpcSupport,
+        boolean useToolchainForJavaProto) {
       this.ruleContext = ruleContext;
       this.supportData = supportData;
       this.protoCompilerPluginOptions = protoCompilerPluginOptions;
       this.javaSemantics = javaSemantics;
       this.rpcSupport = rpcSupport;
+      this.useToolchainForJavaProto = useToolchainForJavaProto;
 
       dependencyCompilationArgs =
           JavaCompilationArgsProvider.merge(
@@ -250,24 +274,49 @@
         return false;
       }
 
-      ProtoSourceFileBlacklist protoBlackList =
-          new ProtoSourceFileBlacklist(
-              ruleContext,
-              ruleContext
-                  .getPrerequisiteArtifacts(PROTO_SOURCE_FILE_BLACKLIST_ATTR, Mode.HOST)
-                  .list());
+      final ProtoSourceFileBlacklist protoBlackList;
+      if (useToolchainForJavaProto) {
+        NestedSetBuilder<Artifact> blacklistedProtos = NestedSetBuilder.stableOrder();
+        blacklistedProtos.addTransitive(getProtoToolchainProvider().blacklistedProtos());
+        blacklistedProtos.addTransitive(rpcSupport.getBlacklist(ruleContext));
+
+        protoBlackList = new ProtoSourceFileBlacklist(ruleContext, blacklistedProtos.build());
+      } else {
+        protoBlackList =
+            new ProtoSourceFileBlacklist(
+                ruleContext,
+                ruleContext
+                    .getPrerequisiteArtifacts(PROTO_SOURCE_FILE_BLACKLIST_ATTR, Mode.HOST)
+                    .list());
+      }
+
       return protoBlackList.checkSrcs(supportData.getDirectProtoSources(), "java_proto_library");
     }
 
     private void createProtoCompileAction(Artifact sourceJar) {
-      ProtoCompileActionBuilder actionBuilder =
-          new ProtoCompileActionBuilder(
-                  ruleContext, supportData, "Java", "java", ImmutableList.of(sourceJar))
-              .allowServices(true)
-              .setLangParameter(
-                  String.format(protoCompilerPluginOptions, sourceJar.getExecPathString()));
-      rpcSupport.mutateProtoCompileAction(ruleContext, sourceJar, actionBuilder);
-      ruleContext.registerAction(actionBuilder.build());
+      if (useToolchainForJavaProto) {
+        ImmutableList.Builder<ToolchainInvocation> invocations = ImmutableList.builder();
+        invocations.add(
+            new ToolchainInvocation(
+                "java", checkNotNull(getProtoToolchainProvider()), sourceJar.getExecPathString()));
+        invocations.addAll(rpcSupport.getToolchainInvocation(ruleContext, sourceJar));
+        ProtoCompileActionBuilder.registerActions(
+            ruleContext,
+            invocations.build(),
+            supportData,
+            ImmutableList.of(sourceJar),
+            "Java (Immutable)",
+            rpcSupport.allowServices(ruleContext));
+      } else {
+        ProtoCompileActionBuilder actionBuilder =
+            new ProtoCompileActionBuilder(
+                    ruleContext, supportData, "Java", "java", ImmutableList.of(sourceJar))
+                .allowServices(true)
+                .setLangParameter(
+                    String.format(protoCompilerPluginOptions, sourceJar.getExecPathString()));
+        rpcSupport.mutateProtoCompileAction(ruleContext, sourceJar, actionBuilder);
+        ruleContext.registerAction(actionBuilder.build());
+      }
     }
 
     private JavaCompilationArgsProvider createJavaCompileAction(
@@ -279,15 +328,28 @@
               .setJavacOpts(ProtoJavacOpts.constructJavacOpts(ruleContext));
       helper
           .addDep(dependencyCompilationArgs)
-          .addDep(
-              ruleContext.getPrerequisite(
-                  SPEED_PROTO_RUNTIME_ATTR, Mode.TARGET, JavaCompilationArgsProvider.class))
           .setCompilationStrictDepsMode(StrictDepsMode.OFF);
+      if (useToolchainForJavaProto) {
+        TransitiveInfoCollection runtime = getProtoToolchainProvider().runtime();
+        if (runtime != null) {
+          helper.addDep(runtime.getProvider(JavaCompilationArgsProvider.class));
+        }
+      } else {
+        helper.addDep(
+            ruleContext.getPrerequisite(
+                SPEED_PROTO_RUNTIME_ATTR, Mode.TARGET, JavaCompilationArgsProvider.class));
+      }
+
       rpcSupport.mutateJavaCompileAction(ruleContext, helper);
       return helper.buildCompilationArgsProvider(
           helper.build(javaSemantics), true /* isReportedAsStrict */);
     }
 
+    private ProtoLangToolchainProvider getProtoToolchainProvider() {
+      return ruleContext.getPrerequisite(
+          SPEED_PROTO_TOOLCHAIN_ATTR, TARGET, ProtoLangToolchainProvider.class);
+    }
+
     private Artifact getSourceJarArtifact() {
       return ruleContext.getGenfilesArtifact(ruleContext.getLabel().getName() + "-speed-src.jar");
     }
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 0840311..44a1c06 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
@@ -16,15 +16,24 @@
 
 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.proto.ProtoCompileActionBuilder;
+import java.util.List;
 
 /**
  * Used by java_proto_library to support Google-specific features.
  */
 public interface RpcSupport {
+  List<ProtoCompileActionBuilder.ToolchainInvocation> getToolchainInvocation(
+      RuleContext ruleContext, Artifact sourceJar);
+
+  boolean allowServices(RuleContext ruleContext);
+
+  NestedSet<Artifact> getBlacklist(RuleContext ruleContext);
+
   void mutateProtoCompileAction(
       RuleContext ruleContext, Artifact sourceJar, ProtoCompileActionBuilder actionBuilder);
 
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 8f0cab9..39be830 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
@@ -122,6 +122,26 @@
     )
     public Label protoToolchainForJavaLite;
 
+    @Option(
+      name = "proto_toolchain_for_java",
+      defaultValue = "//tools/proto/toolchains:java",
+      category = "flags",
+      converter = BuildConfiguration.EmptyToNullLabelConverter.class,
+      help = "Label of proto_lang_toolchain() which describes how to compile Java protos"
+    )
+    public Label protoToolchainForJava;
+
+    @Option(
+      name = "use_toolchain_for_java_proto",
+      defaultValue = "false",
+      category = "experimental",
+      help =
+          "If true, --proto_toolchain_for_java will be used for java_proto_library. "
+              + "This flag is an escape-hatch and should be removed once toolchain-based builds "
+              + "are tested."
+    )
+    public boolean useToolchainForJavaProto;
+
     @Override
     public FragmentOptions getHost(boolean fallback) {
       Options host = (Options) super.getHost(fallback);
@@ -133,7 +153,9 @@
       host.protoCompilerJavaBlacklistedProtos = protoCompilerJavaBlacklistedProtos;
       host.protoCompilerJavaLiteFlags = protoCompilerJavaLiteFlags;
       host.protoCompilerJavaLitePlugin = protoCompilerJavaLitePlugin;
+      host.protoToolchainForJava = protoToolchainForJava;
       host.protoToolchainForJavaLite = protoToolchainForJavaLite;
+      host.useToolchainForJavaProto = useToolchainForJavaProto;
       return host;
     }
   }
@@ -166,7 +188,9 @@
   private final List<Label> protoCompilerJavaBlacklistedProtos;
   private final String protoCompilerJavaLiteFlags;
   private final Label protoCompilerJavaLitePlugin;
+  private final Label protoToolchainForJava;
   private final Label protoToolchainForJavaLite;
+  private final boolean useToolchainForJavaProto;
 
   public ProtoConfiguration(Options options) {
     this.experimentalProtoExtraActions = options.experimentalProtoExtraActions;
@@ -176,7 +200,9 @@
     this.protoCompilerJavaLiteFlags = options.protoCompilerJavaLiteFlags;
     this.protoCompilerJavaLitePlugin = options.protoCompilerJavaLitePlugin;
     this.protoCompilerJavaBlacklistedProtos = options.protoCompilerJavaBlacklistedProtos;
+    this.protoToolchainForJava = options.protoToolchainForJava;
     this.protoToolchainForJavaLite = options.protoToolchainForJavaLite;
+    this.useToolchainForJavaProto = options.useToolchainForJavaProto;
   }
 
   public ImmutableList<String> protocOpts() {
@@ -212,7 +238,15 @@
     return protoCompilerJavaBlacklistedProtos;
   }
 
+  public Label protoToolchainForJava() {
+    return protoToolchainForJava;
+  }
+
   public Label protoToolchainForJavaLite() {
     return protoToolchainForJavaLite;
   }
+
+  public boolean useToolchainForJavaProto() {
+    return useToolchainForJavaProto;
+  }
 }
diff --git a/third_party/protobuf/3.0.0/BUILD b/third_party/protobuf/3.0.0/BUILD
index 767ebd7..0146f66 100644
--- a/third_party/protobuf/3.0.0/BUILD
+++ b/third_party/protobuf/3.0.0/BUILD
@@ -3,6 +3,7 @@
 licenses(["notice"])
 
 load("//third_party/protobuf:protobuf.bzl", "py_proto_library")
+load(":proto_lang_toolchain_if_exists.bzl", "proto_lang_toolchain")
 
 filegroup(
     name = "srcs",
@@ -311,3 +312,9 @@
     visibility = ["//visibility:public"],
     deps = [":protobuf_clib"],
 )
+
+proto_lang_toolchain(
+    name = "java_toolchain",
+    command_line = "--java_out=shared,immutable:$(OUT)",
+    runtime = ":protobuf",
+)
diff --git a/third_party/protobuf/3.0.0/proto_lang_toolchain_if_exists.bzl b/third_party/protobuf/3.0.0/proto_lang_toolchain_if_exists.bzl
new file mode 100644
index 0000000..d0416f6
--- /dev/null
+++ b/third_party/protobuf/3.0.0/proto_lang_toolchain_if_exists.bzl
@@ -0,0 +1,24 @@
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Calls proto_lang_toolchain(), but only if it's already been released."""
+
+# TODO(carmi): Delete this after proto_lang_toolchain() is released in Bazel.
+def proto_lang_toolchain(**kwargs):
+  """Calls proto_lang_toolchain(), but only if it's already been released."""
+  if hasattr(native, 'proto_lang_toolchain'):
+    native.proto_lang_toolchain(**kwargs)
+  else:
+    native.filegroup(name = kwargs['name'])
+
diff --git a/third_party/protobuf/BUILD b/third_party/protobuf/BUILD
index 0f39107..f6e1ea9 100644
--- a/third_party/protobuf/BUILD
+++ b/third_party/protobuf/BUILD
@@ -29,3 +29,5 @@
 proto_alias("protobuf_clib", PROTOBUF_VERSION)
 
 proto_alias("protoc_lib", PROTOBUF_VERSION)
+
+proto_alias("java_toolchain", PROTOBUF_VERSION)
diff --git a/tools/proto/toolchains/BUILD b/tools/proto/toolchains/BUILD
index f5f4a5e..671a84e 100644
--- a/tools/proto/toolchains/BUILD
+++ b/tools/proto/toolchains/BUILD
@@ -5,6 +5,11 @@
     actual = "//external:proto/toolchains/javalite",
 )
 
+alias(
+    name = "java",
+    actual = "//external:proto/toolchains/java",
+)
+
 filegroup(
     name = "srcs",
     srcs = [