diff options
Diffstat (limited to 'src/main/java')
4 files changed, 229 insertions, 0 deletions
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 f1eb576ca0..c94f88af7b 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 @@ -148,6 +148,7 @@ 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.proto.ProtoLangToolchainRule; 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; @@ -361,6 +362,7 @@ public class BazelRuleClassProvider { builder.addConfigurationOptions(ProtoConfiguration.Options.class); builder.addConfigurationFragment(new ProtoConfiguration.Loader()); builder.addRuleDefinition(new BazelProtoLibraryRule()); + builder.addRuleDefinition(new ProtoLangToolchainRule()); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java new file mode 100644 index 0000000000..83b57c7b17 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java @@ -0,0 +1,54 @@ +// 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.proto; + +import static com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode.HOST; +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.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; +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.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; +import com.google.devtools.build.lib.syntax.Type; + +/** Implements {code proto_lang_toolchain}. */ +public class ProtoLangToolchain implements RuleConfiguredTargetFactory { + @Override + public ConfiguredTarget create(RuleContext ruleContext) + throws InterruptedException, RuleErrorException { + NestedSetBuilder<Artifact> blacklistedProtos = NestedSetBuilder.stableOrder(); + for (ProtoSourcesProvider protos : + ruleContext.getPrerequisites("blacklisted_protos", TARGET, ProtoSourcesProvider.class)) { + blacklistedProtos.addAll(protos.getDirectProtoSources()); + } + + return new RuleConfiguredTargetBuilder(ruleContext) + .addProvider( + ProtoLangToolchainProvider.create( + ruleContext.attributes().get("command_line", Type.STRING), + ruleContext.getPrerequisite("plugin", HOST, FilesToRunProvider.class), + ruleContext.getPrerequisite("runtime", TARGET), + blacklistedProtos.build())) + .setFilesToBuild(NestedSetBuilder.<Artifact>emptySet(STABLE_ORDER)) + .addProvider(RunfilesProvider.simple(Runfiles.EMPTY)) + .build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java new file mode 100644 index 0000000000..988bc4ef15 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java @@ -0,0 +1,51 @@ +// 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.proto; + +import com.google.auto.value.AutoValue; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import javax.annotation.Nullable; + +// Note: AutoValue v1.4-rc1 has AutoValue.CopyAnnotations which makes it work with Skylark. No need +// to un-AutoValue this class to expose it to Skylark. +/** + * Specifies how to generate language-specific code from .proto files. Used by LANG_proto_library + * rules. + */ +@AutoValue +public abstract class ProtoLangToolchainProvider implements TransitiveInfoProvider { + public abstract String commandLine(); + + @Nullable + public abstract FilesToRunProvider pluginExecutable(); + + @Nullable + public abstract TransitiveInfoCollection runtime(); + + public abstract NestedSet<Artifact> blacklistedProtos(); + + public static ProtoLangToolchainProvider create( + String commandLine, + FilesToRunProvider pluginExecutable, + TransitiveInfoCollection runtime, + NestedSet<Artifact> blacklistedProtos) { + return new AutoValue_ProtoLangToolchainProvider( + commandLine, pluginExecutable, runtime, blacklistedProtos); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java new file mode 100644 index 0000000000..2643357f42 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java @@ -0,0 +1,122 @@ +// 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.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.common.collect.ImmutableList; +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.TransitiveInfoProvider; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.syntax.Type; + +/** Implements {code proto_lang_toolchain}. */ +public class ProtoLangToolchainRule implements RuleDefinition { + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder + + /* <!-- #BLAZE_RULE(proto_lang_toolchain).ATTRIBUTE(command_line) --> + This value will be passed to proto-compiler to generate the code. Only include the parts + specific to this code-generator/plugin (e.g., do not include -I parameters) + <ul> + <li><code>$(OUT)</code> is LANG_proto_library-specific. The rules are expected to define + how they interpret this variable. For Java, for example, $(OUT) will be replaced with + the src-jar filename to create.</li> + <li><code>$(PLUGIN_out)</code> will be substituted to work with a + `--plugin=protoc-gen-PLUGIN` command line.</li> + </ul> + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("command_line", Type.STRING).mandatory()) + + /* <!-- #BLAZE_RULE(proto_lang_toolchain).ATTRIBUTE(plugin) --> + If provided, will be made available to the action that calls the proto-compiler, and will be + passed to the proto-compiler: + <code>--plugin=protoc-gen-PLUGIN=<executable>.</code> + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("plugin", LABEL).exec().cfg(HOST).allowedFileTypes()) + + /* <!-- #BLAZE_RULE(proto_lang_toolchain).ATTRIBUTE(runtime) --> + A language-specific library that the generated code is compiled against. + The exact behavior is LANG_proto_librar-specific. + Java, for example, should compile against the runtime. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("runtime", LABEL).allowedFileTypes()) + + /* <!-- #BLAZE_RULE(proto_lang_toolchain).ATTRIBUTE(blacklisted_protos) --> + No code will be generated for files in the <code>srcs</code> attribute of + <code>blacklisted_protos</code>. + This is used for .proto files that are already linked into proto runtimes, such as + <code>any.proto</code>. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add( + attr("blacklisted_protos", LABEL_LIST) + .allowedFileTypes() + .mandatoryNativeProviders( + ImmutableList.<Class<? extends TransitiveInfoProvider>>of( + ProtoSourcesProvider.class))) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name("proto_lang_toolchain") + .ancestors(BaseRuleClasses.RuleBase.class) + .factoryClass(ProtoLangToolchain.class) + .build(); + } +} + +/*<!-- #BLAZE_RULE (NAME = proto_lang_toolchain, TYPE = LIBRARY, FAMILY = Protocol Buffer) --> + +<p> +Specifies how a LANG_proto_library rule (e.g., <code>java_proto_library</code>) should invoke the +proto-compiler. +Some LANG_proto_library rules allow specifying which toolchain to use using command-line flags; +consult their documentation. +</p> + +<p>Normally you should not write those kind of rules unless you want to +tune your Java compiler.</p> + +<p> +There's no compiler. The proto-compiler is taken from the proto_library rule we attach to. It is +passed as a command-line flag to Blaze. +Several features require a proto-compiler to be invoked on the proto_library rule itself. +It's beneficial to enforce the compiler that LANG_proto_library uses is the same as the one +<code>proto_library</code> does. +</p> + +<h4>Examples</h4> + +<p>A simple example would be: +</p> + +<pre class="code"> +proto_lang_toolchain( + name = "java_stubby1_immutable", + command_line = "--$(PLUGIN_out)=no_enforce_api_compatibility,java_stubby_version=1,immutable:$(OUT)", + plugin = "//net/rpc/compiler:proto2_java_plugin", + runtime = "//java/com/google/net/rpc3:rpc3", +) +</pre> + +<!-- #END_BLAZE_RULE -->*/ |