// Copyright 2015 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.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.syntax.Type.STRING;

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.HostTransition;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.util.FileType;

/**
 * Rule definition for the proto_library rule.
 */
public final class BazelProtoLibraryRule implements RuleDefinition {

  private static final Label DEFAULT_PROTO_COMPILER =
      Label.parseAbsoluteUnchecked("@com_google_protobuf//:protoc");
  private static final Attribute.LabelLateBoundDefault<?> PROTO_COMPILER =
      Attribute.LabelLateBoundDefault.fromTargetConfiguration(
          ProtoConfiguration.class,
          DEFAULT_PROTO_COMPILER,
          (rule, attributes, protoConfig) ->
              protoConfig.protoCompiler() != null
                  ? protoConfig.protoCompiler()
                  : DEFAULT_PROTO_COMPILER);

  @Override
  public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {

    return builder
        .requiresConfigurationFragments(ProtoConfiguration.class)
        .setOutputToGenfiles()
        .add(
            attr(":proto_compiler", LABEL)
                .cfg(HostTransition.INSTANCE)
                .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())
        /* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(srcs) -->
        The list of <code>.proto</code> and <code>.protodevel</code> files that are
        processed to create the target. This is usually a non empty list. One usecase
        where <code>srcs</code> can be empty is an <i>alias-library</i>. This is a
        proto_library rule having one or 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"), FileType.of(".protodevel")))
        /* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(proto_source_root) -->
        Directory containing .proto files. If set, it must be equal to the package name. If not set,
        the source root will be the workspace directory (default).
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("proto_source_root", STRING))
        /* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(exports) -->
        List of proto_library targets that can be referenced via "import public" in the proto
        source.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("exports", LABEL_LIST).allowedRuleClasses("proto_library").allowedFileTypes())
        /* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(strip_import_prefix) -->
        The prefix to strip from the paths of the .proto files in this rule.

        <p>When set, .proto source files in the <code>srcs</code> attribute of this rule are
        accessible at their path with this prefix cut off.

        <p>If it's a relative path (not starting with a slash), it's taken as a package-relative
        one. If it's an absolute one, it's understood as a repository-relative path.

        <p>The prefix in the <code>import_prefix</code> attribute is added after this prefix is
        stripped.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("strip_import_prefix", STRING))
        /* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(import_prefix) -->
        The prefix to add to the paths of the .proto files in this rule.

        <p>When set, the .proto source files in the <code>srcs</code> attribute of this rule are
        accessible at is the value of this attribute prepended to their repository-relative path.

        <p>The prefix in the <code>strip_import_prefix</code> attribute is removed before this
        prefix is added.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("import_prefix", STRING))
        .advertiseSkylarkProvider(ProtoInfo.PROVIDER.id())
        .build();
  }

  @Override
  public Metadata getMetadata() {
    return RuleDefinition.Metadata.builder()
        .name("proto_library")
        .ancestors(BaseRuleClasses.RuleBase.class)
        .factoryClass(BazelProtoLibrary.class)
        .build();
  }
}

/*<!-- #BLAZE_RULE (NAME = proto_library, TYPE = LIBRARY, FAMILY = Protocol Buffer) -->

<p>Use <code>proto_library</code> to define libraries of protocol buffers
   which may be used from multiple languages. A <code>proto_library</code> may be listed
   in the <code>deps</code> clause of supported rules, such as <code>java_proto_library</code>.
</p>

<p>When compiled on the command-line, a <code>proto_library</code> creates a file named
   <code>foo-descriptor-set.proto.bin</code>, which is the descriptor set for the
   messages the rule srcs. The file is a serialized <code>FileDescriptorSet</code>, which is
   described in
   <a href="https://developers.google.com/protocol-buffers/docs/techniques#self-description">
   https://developers.google.com/protocol-buffers/docs/techniques#self-description</a>.
</p>

<p>It only contains information about the <code>.proto</code> files directly mentioned by a
<code>proto_library</code> rule; the collection of transitive descriptor sets is available through
the <code>[ProtoInfo].transitive_descriptor_sets</code> Skylark provider.
See documentation in <code>ProtoInfo.java</code>.</p>

<p>Recommended code organization:</p>

<ul>
<li> One <code>proto_library</code> rule per <code>.proto</code> file.
<li> A file named <code>foo.proto</code> will be in a rule named <code>foo_proto</code>, which
   is located in the same package.
<li> A <code>[language]_proto_library</code> that wraps a <code>proto_library</code> named
  <code>foo_proto</code> should be called
   <code>foo_[language]_proto</code>, and be located in the same package.
</ul>

<!-- #END_BLAZE_RULE -->*/
