aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Carmi Grushko <carmi@google.com>2016-07-11 22:42:19 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-07-12 11:17:57 +0000
commit532c2f0c159b8b41cb5caddb550fae358c79a757 (patch)
treed656f7df24dc946d8ad8dc9c886fc0f6fa50b843
parent5e9ac25270998b863f6540fefe4d229c0bb1a244 (diff)
Open-source java_proto_library.
RELNOTES: New rule, java_proto_library, to generate Java bindings for protocol-buffers. -- MOS_MIGRATED_REVID=127136894
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD3
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibrary.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibraryRule.java101
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaCompilationArgsAspectProvider.java48
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java275
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java100
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryTransitiveFilesToBuildProvider.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaRuntimeJarAspectProvider.java46
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaSourceJarsAspectProvider.java44
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java34
16 files changed, 797 insertions, 18 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index f56f688d72..8cd60b38fa 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -717,7 +717,7 @@ java_library(
java_library(
name = "java-rules",
srcs = glob(
- ["rules/java/*.java"],
+ ["rules/java/**/*.java"],
exclude = [
"rules/java/JavaImplicitAttributes.java",
"rules/java/JavaToolchainDataParser.java",
@@ -730,6 +730,7 @@ java_library(
":events",
":java-implicit-attributes",
":packages-internal",
+ ":proto-rules",
":shell",
":skylarkinterface",
":util",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 66f46ce8e2..8fe4241985 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -48,6 +48,8 @@ import com.google.devtools.build.lib.bazel.rules.java.BazelJavaLibraryRule;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaPluginRule;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaRuleClasses;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaTestRule;
+import com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaProtoAspect;
+import com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaProtoLibraryRule;
import com.google.devtools.build.lib.bazel.rules.objc.BazelJ2ObjcLibraryRule;
import com.google.devtools.build.lib.bazel.rules.python.BazelPyBinaryRule;
import com.google.devtools.build.lib.bazel.rules.python.BazelPyLibraryRule;
@@ -135,6 +137,7 @@ import com.google.devtools.build.lib.rules.objc.ObjcProvider;
import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses;
import com.google.devtools.build.lib.rules.objc.ObjcXcodeprojRule;
import com.google.devtools.build.lib.rules.proto.BazelProtoLibraryRule;
+import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
import com.google.devtools.build.lib.rules.python.PythonConfigurationLoader;
import com.google.devtools.build.lib.rules.python.PythonOptions;
import com.google.devtools.build.lib.rules.repository.BindRule;
@@ -243,7 +246,9 @@ public class BazelRuleClassProvider {
builder.setUniversalConfigurationFragment(BazelConfiguration.class);
builder.addConfigurationOptions(BuildConfiguration.Options.class);
+ builder.addConfigurationOptions(ProtoConfiguration.Options.class);
builder.addConfigurationFragment(new BazelConfiguration.Loader());
+ builder.addConfigurationFragment(new ProtoConfiguration.Loader());
builder.addRuleDefinition(new BaseRuleClasses.BaseRule());
builder.addRuleDefinition(new BaseRuleClasses.RuleBase());
@@ -390,11 +395,13 @@ public class BazelRuleClassProvider {
AndroidStudioInfoAspect androidStudioInfoAspect =
new AndroidStudioInfoAspect(toolsRepository, new BazelAndroidStudioInfoSemantics());
ObjcProtoAspect objcProtoAspect = new ObjcProtoAspect();
+ BazelJavaProtoAspect bazelJavaProtoAspect = new BazelJavaProtoAspect();
builder.addNativeAspectClass(bazelJ2ObjcProtoAspect);
builder.addNativeAspectClass(j2ObjcAspect);
builder.addNativeAspectClass(androidStudioInfoAspect);
builder.addNativeAspectClass(objcProtoAspect);
+ builder.addNativeAspectClass(bazelJavaProtoAspect);
builder.addRuleDefinition(new BazelShRuleClasses.ShRule());
builder.addRuleDefinition(new BazelShLibraryRule());
@@ -470,6 +477,7 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new NewLocalRepositoryRule());
builder.addRuleDefinition(new AndroidSdkRepositoryRule());
builder.addRuleDefinition(new AndroidNdkRepositoryRule());
+ builder.addRuleDefinition(new BazelJavaProtoLibraryRule(bazelJavaProtoAspect));
builder.addConfigurationFragment(new PythonConfigurationLoader(Functions.<String>identity()));
builder.addConfigurationFragment(new BazelPythonConfiguration.Loader());
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
index fc40911439..f126a9ad99 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
@@ -116,17 +116,18 @@ public class BazelJavaRuleClasses {
}
}
- static final Set<String> ALLOWED_RULES_IN_DEPS = ImmutableSet.of(
- "cc_binary", // NB: linkshared=1
- "cc_library",
- "genrule",
- "genproto", // TODO(bazel-team): we should filter using providers instead (skylark rule).
- "java_import",
- "java_library",
- // There is no Java protoc for Bazel--yet. This is here for the benefit of J2 protos.
- "proto_library",
- "sh_binary",
- "sh_library");
+ static final Set<String> ALLOWED_RULES_IN_DEPS =
+ ImmutableSet.of(
+ "cc_binary", // NB: linkshared=1
+ "cc_library",
+ "genrule",
+ "genproto", // TODO(bazel-team): we should filter using providers instead (skylark rule).
+ "java_import",
+ "java_library",
+ "java_proto_library",
+ "proto_library",
+ "sh_binary",
+ "sh_library");
/**
* Common attributes for Java 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
new file mode 100644
index 0000000000..3d7aa18a7e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
@@ -0,0 +1,35 @@
+// 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.
+
+package com.google.devtools.build.lib.bazel.rules.java.proto;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics;
+import com.google.devtools.build.lib.rules.java.proto.JavaProtoAspect;
+
+/** An Aspect which BazelJavaProtoLibrary injects to build Java SPEED protos. */
+public class BazelJavaProtoAspect extends JavaProtoAspect {
+
+ static final String SPEED_PROTO_RUNTIME_ATTR = "$aspect_java_lib";
+ static final String SPEED_PROTO_RUNTIME_LABEL = "//third_party/protobuf:protobuf";
+
+ public BazelJavaProtoAspect() {
+ super(
+ BazelJavaSemantics.INSTANCE,
+ SPEED_PROTO_RUNTIME_ATTR,
+ SPEED_PROTO_RUNTIME_LABEL,
+ null, /* jacocoAttr */
+ ImmutableList.of("shared", "immutable"));
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibrary.java
new file mode 100644
index 0000000000..a6f2e849e4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibrary.java
@@ -0,0 +1,20 @@
+// 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.
+
+package com.google.devtools.build.lib.bazel.rules.java.proto;
+
+import com.google.devtools.build.lib.rules.java.proto.JavaProtoLibrary;
+
+/** Implementation of the java_proto_library rule. */
+public class BazelJavaProtoLibrary extends JavaProtoLibrary {}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibraryRule.java
new file mode 100644
index 0000000000..990f0d2166
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoLibraryRule.java
@@ -0,0 +1,101 @@
+// 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.
+
+package com.google.devtools.build.lib.bazel.rules.java.proto;
+
+import static com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaProtoAspect.SPEED_PROTO_RUNTIME_ATTR;
+import static com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaProtoAspect.SPEED_PROTO_RUNTIME_LABEL;
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
+
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.RuleClass;
+
+/** Declaration of the {@code java_proto_library} rule. */
+public class BazelJavaProtoLibraryRule implements RuleDefinition {
+
+ private final BazelJavaProtoAspect javaProtoAspect;
+
+ public BazelJavaProtoLibraryRule(BazelJavaProtoAspect javaProtoAspect) {
+ this.javaProtoAspect = javaProtoAspect;
+ }
+
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
+ return builder
+ // This rule isn't ready for use yet.
+ .setUndocumented()
+ /* <!-- #BLAZE_RULE(java_proto_library).ATTRIBUTE(deps) -->
+ The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
+ rules to generate Java code for.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .override(
+ attr("deps", LABEL_LIST)
+ .allowedRuleClasses("proto_library")
+ .allowedFileTypes()
+ .aspect(javaProtoAspect))
+ .add(
+ attr(SPEED_PROTO_RUNTIME_ATTR, LABEL)
+ .legacyAllowAnyFileType()
+ .value(Label.parseAbsoluteUnchecked(SPEED_PROTO_RUNTIME_LABEL)))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("java_proto_library")
+ .factoryClass(BazelJavaProtoLibrary.class)
+ .ancestors(BaseRuleClasses.RuleBase.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = java_proto_library, TYPE = LIBRARY, FAMILY = Java) -->
+
+<p>
+<code>java_proto_library</code> generates Java code from <code>.proto</code> files.
+</p>
+
+<p>
+<code>deps</code> must point to <a href="protocol-buffer.html#proto_library"><code>proto_library
+</code></a> rules.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre class="code">
+java_library(
+ name = "lib",
+ deps = [":foo"],
+)
+
+java_proto_library(
+ name = "foo",
+ deps = [":bar"],
+)
+
+proto_library(
+ name = "bar",
+)
+</pre>
+
+
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
index f7ccb344c0..18792318e1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
@@ -131,6 +131,7 @@ public final class JavaConfiguration extends Fragment {
private final boolean useHeaderCompilation;
private final boolean optimizeHeaderCompilationAnnotationProcessing;
private final boolean generateJavaDeps;
+ private final boolean javaProtoLibraryDepsAreStrict;
private final JavaClasspathMode javaClasspath;
private final ImmutableList<String> javaWarns;
private final ImmutableList<String> defaultJvmFlags;
@@ -172,6 +173,7 @@ public final class JavaConfiguration extends Fragment {
this.javaToolchain = javaToolchain;
this.javaOptimizationMode = javaOptions.javaOptimizationMode;
this.legacyBazelJavaTest = javaOptions.legacyBazelJavaTest;
+ this.javaProtoLibraryDepsAreStrict = javaOptions.javaProtoLibraryDepsAreStrict;
ImmutableList.Builder<Label> translationsBuilder = ImmutableList.builder();
for (String s : javaOptions.translationTargets) {
@@ -336,4 +338,9 @@ public final class JavaConfiguration extends Fragment {
public boolean useLegacyBazelJavaTest() {
return legacyBazelJavaTest;
}
+
+ // TODO(b/29867858): Replace with a BUILD-level attribute.
+ public boolean javaProtoLibraryDepsAreStrict() {
+ return javaProtoLibraryDepsAreStrict;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
index 025c1e0820..745aaf8dc3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
@@ -348,6 +348,19 @@ public class JavaOptions extends FragmentOptions {
help = "Use the legacy mode of Bazel for java_test.")
public boolean legacyBazelJavaTest;
+ @Option(
+ name = "java_proto_library_deps_are_strict",
+ defaultValue = "false",
+ category = "undocumented",
+ help =
+ "This only applies to java_proto_library. "
+ + "If true: (1) if a Java file uses proto Foo, it must depend on a "
+ + "java_{lite,...}_proto_library that directly depends on a proto_library that has Foo "
+ + "in its srcs. (2) strict-deps violations are reported for the proto_library rules "
+ + "themselves."
+ )
+ public boolean javaProtoLibraryDepsAreStrict;
+
@Override
public FragmentOptions getHost(boolean fallback) {
JavaOptions host = (JavaOptions) getDefault();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaCompilationArgsAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaCompilationArgsAspectProvider.java
new file mode 100644
index 0000000000..1169eb4193
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaCompilationArgsAspectProvider.java
@@ -0,0 +1,48 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import com.google.common.base.Function;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
+
+import javax.annotation.Nullable;
+
+/**
+ * A wrapper around {@link JavaCompilationArgsProvider}.
+ */
+public class JavaCompilationArgsAspectProvider implements TransitiveInfoProvider {
+
+ /**
+ * A long way to say (wrapper) -> wrapper.provider.
+ */
+ public static final Function<
+ ? super JavaCompilationArgsAspectProvider, ? extends JavaCompilationArgsProvider>
+ GET_PROVIDER =
+ new Function<JavaCompilationArgsAspectProvider, JavaCompilationArgsProvider>() {
+ @Nullable
+ @Override
+ public JavaCompilationArgsProvider apply(
+ @Nullable JavaCompilationArgsAspectProvider wrapper) {
+ return wrapper == null ? null : wrapper.provider;
+ }
+ };
+
+ public final JavaCompilationArgsProvider provider;
+
+ public JavaCompilationArgsAspectProvider(JavaCompilationArgsProvider provider) {
+ this.provider = provider;
+ }
+}
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
new file mode 100644
index 0000000000..aad0e51d72
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
@@ -0,0 +1,275 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+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.packages.Attribute.ConfigurationTransition.HOST;
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static com.google.devtools.build.lib.rules.java.proto.JavaCompilationArgsAspectProvider.GET_PROVIDER;
+import static com.google.devtools.build.lib.rules.java.proto.JavaProtoLibraryTransitiveFilesToBuildProvider.GET_JARS;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredAspect;
+import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
+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.TransitiveInfoProvider;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.AspectDefinition;
+import com.google.devtools.build.lib.packages.AspectParameters;
+import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.NativeAspectClass;
+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.java.JavaLibraryHelper;
+import com.google.devtools.build.lib.rules.java.JavaRuntimeJarProvider;
+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.java.JavaToolchainProvider;
+import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
+import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
+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.Map;
+
+import javax.annotation.Nullable;
+
+/** An Aspect which JavaProtoLibrary injects to build Java SPEED protos. */
+public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspectFactory {
+
+ private final JavaSemantics javaSemantics;
+ private final String protoRuntimeAttr;
+ private final String protoRuntimeLabel;
+
+ @Nullable private final String jacocoLabel;
+ private final ImmutableList<String> protoCompilerPluginOptions;
+
+ protected JavaProtoAspect(
+ JavaSemantics javaSemantics,
+ String protoRuntimeAttr,
+ String protoRuntimeLabel,
+ @Nullable String jacocoLabel,
+ ImmutableList<String> protoCompilerPluginOptions) {
+ this.javaSemantics = javaSemantics;
+ this.protoRuntimeAttr = protoRuntimeAttr;
+ this.protoRuntimeLabel = protoRuntimeLabel;
+ this.jacocoLabel = jacocoLabel;
+ this.protoCompilerPluginOptions = protoCompilerPluginOptions;
+ }
+
+ @Override
+ public ConfiguredAspect create(
+ ConfiguredTarget base, RuleContext ruleContext, AspectParameters parameters)
+ throws InterruptedException {
+ ConfiguredAspect.Builder aspect =
+ new ConfiguredAspect.Builder(getClass().getSimpleName(), ruleContext);
+
+ // Get SupportData, which is provided by the proto_library rule we attach to.
+ SupportData supportData =
+ checkNotNull(base.getProvider(ProtoSupportDataProvider.class)).getSupportData();
+
+ aspect.addProviders(
+ new Impl(
+ ruleContext,
+ supportData,
+ protoRuntimeAttr,
+ protoCompilerPluginOptions,
+ javaSemantics)
+ .createProviders());
+
+ return aspect.build();
+ }
+
+ @Override
+ public AspectDefinition getDefinition(AspectParameters aspectParameters) {
+ AspectDefinition.Builder result =
+ new AspectDefinition.Builder(getClass().getSimpleName())
+ .attributeAspect("deps", this)
+ .requiresConfigurationFragments(
+ JavaConfiguration.class, ProtoConfiguration.class)
+ .requireProvider(ProtoSourcesProvider.class)
+ .add(
+ attr(protoRuntimeAttr, LABEL)
+ .legacyAllowAnyFileType()
+ .value(Label.parseAbsoluteUnchecked(protoRuntimeLabel)))
+ .add(attr(":host_jdk", LABEL).cfg(HOST).value(JavaSemantics.HOST_JDK))
+ .add(
+ attr(":java_toolchain", LABEL)
+ .allowedRuleClasses("java_toolchain")
+ .value(JavaSemantics.JAVA_TOOLCHAIN));
+
+ Attribute.Builder<Label> jacocoAttr = attr("$jacoco_instrumentation", LABEL).cfg(HOST);
+
+ if (jacocoLabel != null) {
+ jacocoAttr.value(Label.parseAbsoluteUnchecked(jacocoLabel));
+ }
+ return result.add(jacocoAttr).build();
+ }
+
+ private static class Impl {
+
+ private final RuleContext ruleContext;
+ private final SupportData supportData;
+
+ private final boolean isStrictDeps;
+ private final String protoRuntimeAttr;
+ private final JavaSemantics javaSemantics;
+
+ /**
+ * Compilation-args from all dependencies, merged together. This is typically the input to a
+ * Java compilation action.
+ */
+ private final JavaCompilationArgsProvider dependencyCompilationArgs;
+ private final ImmutableList<String> protoCompilerPluginOptions;
+
+ Impl(
+ final RuleContext ruleContext,
+ final SupportData supportData,
+ String protoRuntimeAttr,
+ ImmutableList<String> protoCompilerPluginOptions,
+ JavaSemantics javaSemantics) {
+ this.ruleContext = ruleContext;
+ this.supportData = supportData;
+ this.protoRuntimeAttr = protoRuntimeAttr;
+ this.protoCompilerPluginOptions = protoCompilerPluginOptions;
+ this.javaSemantics = javaSemantics;
+
+ isStrictDeps =
+ ruleContext.getFragment(JavaConfiguration.class).javaProtoLibraryDepsAreStrict();
+
+ dependencyCompilationArgs =
+ JavaCompilationArgsProvider.merge(
+ Iterables.<JavaCompilationArgsAspectProvider, JavaCompilationArgsProvider>transform(
+ this.<JavaCompilationArgsAspectProvider>getDeps(
+ JavaCompilationArgsAspectProvider.class),
+ GET_PROVIDER));
+ }
+
+ Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> createProviders() {
+ ImmutableMap.Builder<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> result =
+ ImmutableMap.builder();
+
+ // Represents the result of compiling the code generated for this proto, including all of its
+ // dependencies.
+ JavaCompilationArgsProvider generatedCompilationArgsProvider;
+
+ // The jars that this proto and its dependencies produce. Used to roll-up jars up to the
+ // java_proto_library, to be put into filesToBuild.
+ NestedSetBuilder<Artifact> transitiveOutputJars =
+ NestedSetBuilder.fromNestedSets(
+ transform(getDeps(JavaProtoLibraryTransitiveFilesToBuildProvider.class), GET_JARS));
+
+ if (supportData.hasProtoSources()) {
+ Artifact sourceJar = getSourceJarArtifact();
+ createProtoCompileAction(sourceJar);
+ Artifact outputJar = getOutputJarArtifact();
+
+ generatedCompilationArgsProvider = createJavaCompileAction(sourceJar, outputJar);
+
+ NestedSet<Artifact> javaSourceJars =
+ NestedSetBuilder.<Artifact>stableOrder().add(sourceJar).build();
+ transitiveOutputJars.add(outputJar);
+
+ result
+ .put(
+ JavaRuntimeJarAspectProvider.class,
+ new JavaRuntimeJarAspectProvider(
+ new JavaRuntimeJarProvider(ImmutableList.of(outputJar))))
+ .put(
+ JavaSourceJarsAspectProvider.class,
+ new JavaSourceJarsAspectProvider(
+ new JavaSourceJarsProvider(
+ NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER), javaSourceJars)));
+ } else {
+ // No sources - this proto_library is an alias library, which exports its dependencies.
+ // Simply propagate the compilation-args from its dependencies.
+ generatedCompilationArgsProvider = dependencyCompilationArgs;
+ }
+
+ return result
+ .put(
+ JavaProtoLibraryTransitiveFilesToBuildProvider.class,
+ new JavaProtoLibraryTransitiveFilesToBuildProvider(transitiveOutputJars.build()))
+ .put(
+ JavaCompilationArgsAspectProvider.class,
+ new JavaCompilationArgsAspectProvider(generatedCompilationArgsProvider))
+ .build();
+ }
+
+ private void createProtoCompileAction(Artifact sourceJar) {
+ ProtoCompileActionBuilder actionBuilder =
+ new ProtoCompileActionBuilder(
+ ruleContext, supportData, "Java", "java", ImmutableList.of(sourceJar))
+ .allowServices(true)
+ .setLangParameter(
+ ProtoCompileActionBuilder.buildProtoArg(
+ "java_out", sourceJar.getExecPathString(), protoCompilerPluginOptions));
+ ruleContext.registerAction(actionBuilder.build());
+ }
+
+ private JavaCompilationArgsProvider createJavaCompileAction(
+ Artifact sourceJar, Artifact outputJar) {
+ JavaLibraryHelper helper =
+ new JavaLibraryHelper(ruleContext)
+ .setOutput(outputJar)
+ .addSourceJars(sourceJar)
+ .setJavacOpts(constructJavacOpts());
+ helper.addDep(dependencyCompilationArgs);
+ helper
+ .addDep(
+ ruleContext.getPrerequisite(
+ protoRuntimeAttr, Mode.TARGET, JavaCompilationArgsProvider.class))
+ .setStrictDepsMode(isStrictDeps ? StrictDepsMode.WARN : StrictDepsMode.OFF);
+ return helper.buildCompilationArgsProvider(helper.build(javaSemantics));
+ }
+
+ private Artifact getSourceJarArtifact() {
+ return ruleContext.getGenfilesArtifact(ruleContext.getLabel().getName() + "-speed-src.jar");
+ }
+
+ private Artifact getOutputJarArtifact() {
+ return ruleContext.getBinArtifact("lib" + ruleContext.getLabel().getName() + "-speed.jar");
+ }
+
+ /**
+ * Returns javacopts for compiling the Java source files generated by the proto compiler.
+ * Ensures that they are compiled so that they can be used by App Engine targets.
+ */
+ private ImmutableList<String> constructJavacOpts() {
+ JavaToolchainProvider toolchain = JavaToolchainProvider.fromRuleContext(ruleContext);
+ ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
+ listBuilder.addAll(toolchain.getJavacOptions());
+ listBuilder.add("-source", "7", "-target", "7");
+ return listBuilder.build();
+ }
+
+ private <C extends TransitiveInfoProvider> Iterable<C> getDeps(Class<C> clazz) {
+ return ruleContext.getPrerequisites("deps", TARGET, clazz);
+ }
+ }
+}
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
new file mode 100644
index 0000000000..4ca16ae508
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
@@ -0,0 +1,100 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.TARGET;
+import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER;
+
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.OutputGroupProvider;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.Runfiles;
+import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
+import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider;
+import com.google.devtools.build.lib.rules.java.JavaRunfilesProvider;
+import com.google.devtools.build.lib.rules.java.JavaRuntimeJarProvider;
+import com.google.devtools.build.lib.rules.java.JavaSkylarkApiProvider;
+import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
+
+/** Implementation of the java_proto_library rule. */
+public class JavaProtoLibrary implements RuleConfiguredTargetFactory {
+
+ @Override
+ public ConfiguredTarget create(final RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+
+ JavaCompilationArgsProvider dependencyArgsProviders =
+ JavaCompilationArgsProvider.merge(
+ Iterables.<JavaCompilationArgsAspectProvider, JavaCompilationArgsProvider>transform(
+ this.<JavaCompilationArgsAspectProvider>getDeps(
+ ruleContext, JavaCompilationArgsAspectProvider.class),
+ JavaCompilationArgsAspectProvider.GET_PROVIDER));
+
+ Runfiles runfiles =
+ new Runfiles.Builder(ruleContext.getWorkspaceName())
+ .addArtifacts(
+ dependencyArgsProviders.getRecursiveJavaCompilationArgs().getRuntimeJars())
+ .build();
+
+ JavaSourceJarsProvider sourceJarsProvider =
+ JavaSourceJarsProvider.merge(
+ Iterables.<JavaSourceJarsAspectProvider, JavaSourceJarsProvider>transform(
+ this.<JavaSourceJarsAspectProvider>getDeps(
+ ruleContext, JavaSourceJarsAspectProvider.class),
+ JavaSourceJarsAspectProvider.GET_PROVIDER));
+
+ NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
+
+ filesToBuild.addAll(sourceJarsProvider.getSourceJars());
+
+ for (JavaProtoLibraryTransitiveFilesToBuildProvider provider :
+ ruleContext.getPrerequisites(
+ "deps", Mode.TARGET, JavaProtoLibraryTransitiveFilesToBuildProvider.class)) {
+ filesToBuild.addTransitive(provider.getJars());
+ }
+
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .setFilesToBuild(filesToBuild.build())
+ .addProvider(RunfilesProvider.class, RunfilesProvider.withData(Runfiles.EMPTY, runfiles))
+ .addOutputGroup(
+ OutputGroupProvider.DEFAULT, NestedSetBuilder.<Artifact>emptySet(STABLE_ORDER))
+ .add(
+ JavaRuntimeJarProvider.class,
+ JavaRuntimeJarProvider.merge(
+ Iterables.<JavaRuntimeJarAspectProvider, JavaRuntimeJarProvider>transform(
+ this.<JavaRuntimeJarAspectProvider>getDeps(
+ ruleContext, JavaRuntimeJarAspectProvider.class),
+ JavaRuntimeJarAspectProvider.GET_PROVIDER)))
+ .add(JavaCompilationArgsProvider.class, dependencyArgsProviders)
+ .add(JavaSourceJarsProvider.class, sourceJarsProvider)
+ .add(JavaRunfilesProvider.class, new JavaRunfilesProvider(runfiles))
+ .add(JavaRuleOutputJarsProvider.class, JavaRuleOutputJarsProvider.builder().build())
+ .addSkylarkTransitiveInfo(JavaSkylarkApiProvider.NAME, new JavaSkylarkApiProvider())
+ .build();
+ }
+
+ private <C extends TransitiveInfoProvider> Iterable<C> getDeps(
+ RuleContext ruleContext, Class<C> clazz) {
+ return ruleContext.getPrerequisites("deps", TARGET, clazz);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryTransitiveFilesToBuildProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryTransitiveFilesToBuildProvider.java
new file mode 100644
index 0000000000..aaf4ee26d2
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryTransitiveFilesToBuildProvider.java
@@ -0,0 +1,47 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import com.google.common.base.Function;
+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 javax.annotation.Nullable;
+
+/** Used by java_{lite,...}_proto_library to roll up jars to build. */
+public class JavaProtoLibraryTransitiveFilesToBuildProvider implements TransitiveInfoProvider {
+ private final NestedSet<Artifact> jars;
+
+ /** A long way to say (JavaProtoLibraryTransitiveFilesToBuildProvider p) -> p.getJars() */
+ public static final Function<JavaProtoLibraryTransitiveFilesToBuildProvider, NestedSet<Artifact>>
+ GET_JARS =
+ new Function<JavaProtoLibraryTransitiveFilesToBuildProvider, NestedSet<Artifact>>() {
+ @Nullable
+ @Override
+ public NestedSet<Artifact> apply(
+ @Nullable JavaProtoLibraryTransitiveFilesToBuildProvider p) {
+ return p == null ? null : p.getJars();
+ }
+ };
+
+ public JavaProtoLibraryTransitiveFilesToBuildProvider(NestedSet<Artifact> jars) {
+ this.jars = jars;
+ }
+
+ public NestedSet<Artifact> getJars() {
+ return jars;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaRuntimeJarAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaRuntimeJarAspectProvider.java
new file mode 100644
index 0000000000..9979a8c78e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaRuntimeJarAspectProvider.java
@@ -0,0 +1,46 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import com.google.common.base.Function;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.rules.java.JavaRuntimeJarProvider;
+
+import javax.annotation.Nullable;
+
+/**
+ * A wrapper around {@link JavaRuntimeJarProvider}.
+ */
+public class JavaRuntimeJarAspectProvider implements TransitiveInfoProvider {
+ /**
+ * A long way to say (wrapper) -> wrapper.provider.
+ */
+ public static final Function<
+ ? super JavaRuntimeJarAspectProvider, ? extends JavaRuntimeJarProvider>
+ GET_PROVIDER =
+ new Function<JavaRuntimeJarAspectProvider, JavaRuntimeJarProvider>() {
+ @Nullable
+ @Override
+ public JavaRuntimeJarProvider apply(@Nullable JavaRuntimeJarAspectProvider wrapper) {
+ return wrapper == null ? null : wrapper.provider;
+ }
+ };
+
+ public final JavaRuntimeJarProvider provider;
+
+ public JavaRuntimeJarAspectProvider(JavaRuntimeJarProvider provider) {
+ this.provider = provider;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaSourceJarsAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaSourceJarsAspectProvider.java
new file mode 100644
index 0000000000..962f93dfb6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaSourceJarsAspectProvider.java
@@ -0,0 +1,44 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.java.proto;
+
+import com.google.common.base.Function;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
+
+import javax.annotation.Nullable;
+
+/** A wrapper around {@link JavaSourceJarsProvider}. */
+public class JavaSourceJarsAspectProvider implements TransitiveInfoProvider {
+ /**
+ * A long way to say (wrapper) -> wrapper.provider.
+ */
+ public static final Function<
+ ? super JavaSourceJarsAspectProvider, ? extends JavaSourceJarsProvider>
+ GET_PROVIDER =
+ new Function<JavaSourceJarsAspectProvider, JavaSourceJarsProvider>() {
+ @Nullable
+ @Override
+ public JavaSourceJarsProvider apply(@Nullable JavaSourceJarsAspectProvider wrapper) {
+ return wrapper == null ? null : wrapper.provider;
+ }
+ };
+
+ public final JavaSourceJarsProvider provider;
+
+ public JavaSourceJarsAspectProvider(JavaSourceJarsProvider provider) {
+ this.provider = provider;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
index 97cb0e9043..4fb8a85839 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.proto;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -21,6 +22,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
@@ -49,9 +51,18 @@ public class BazelProtoLibrary implements RuleConfiguredTargetFactory {
ProtoSourcesProvider.create(
transitiveImports, transitiveImports, protoSources, checkDepsProtoSources);
+ final SupportData supportData =
+ SupportData.create(
+ Predicates.<TransitiveInfoCollection>alwaysTrue() /* nonWeakDepsPredicate */,
+ protoSources,
+ transitiveImports,
+ null /* usedDirectDeps */,
+ !protoSources.isEmpty());
+
return new RuleConfiguredTargetBuilder(ruleContext)
.add(RunfilesProvider.class, runfilesProvider)
.addProvider(ProtoSourcesProvider.class, sourcesProvider)
+ .addProvider(ProtoSupportDataProvider.class, new ProtoSupportDataProvider(supportData))
.addSkylarkTransitiveInfo(ProtoSourcesProvider.SKYLARK_NAME, sourcesProvider)
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
index 3dfafb2ced..1f8b223b1f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java
@@ -14,12 +14,19 @@
package com.google.devtools.build.lib.rules.proto;
+import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.util.FileType;
@@ -29,24 +36,38 @@ import com.google.devtools.build.lib.util.FileType;
*/
public final class BazelProtoLibraryRule implements RuleDefinition {
+ private static final Attribute.LateBoundLabel<BuildConfiguration> PROTO_COMPILER =
+ new Attribute.LateBoundLabel<BuildConfiguration>(
+ "//third_party/protobuf:protoc", ProtoConfiguration.class) {
+ @Override
+ public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
+ Label label = configuration.getFragment(ProtoConfiguration.class).protoCompiler();
+ return label != null ? label : getDefault();
+ }
+ };
+
@Override
public RuleClass build(Builder builder, final RuleDefinitionEnvironment env) {
return builder
+ .requiresConfigurationFragments(ProtoConfiguration.class)
// This rule works, but does nothing, in open-source Bazel, due to the
// lack of protoc support. Users can theoretically write their own Skylark rules,
// but these are still 'experimental' according to the documentation.
.setUndocumented()
.setOutputToGenfiles()
+ .add(
+ attr(":proto_compiler", LABEL)
+ .cfg(HOST)
+ .exec()
+ .value(PROTO_COMPILER))
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(deps) -->
The list of other <code>proto_library</code> rules that the target depends upon.
A <code>proto_library</code> may only depend on other
<code>proto_library</code> targets.
It may not depend on language-specific libraries.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .override(attr("deps", LABEL_LIST)
- .allowedRuleClasses("proto_library")
- .allowedFileTypes())
+ .override(attr("deps", LABEL_LIST).allowedRuleClasses("proto_library").allowedFileTypes())
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(srcs) -->
The list of <code>.proto</code> files that are processed to create the target.
This is usually a non empty list. One usecase where <code>srcs</code> can be
@@ -54,9 +75,10 @@ public final class BazelProtoLibraryRule implements RuleDefinition {
more other proto_library in <code>deps</code>. This pattern can be used to
e.g. export a public api under a persistent name.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr("srcs", LABEL_LIST)
- .direct_compile_time_input()
- .allowedFileTypes(FileType.of(".proto")))
+ .add(
+ attr("srcs", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedFileTypes(FileType.of(".proto")))
.advertiseProvider(ProtoSourcesProvider.class)
.build();
}