// Copyright 2014 The Closure Compiler Authors.
//
// 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.

syntax = "proto2";

package jscomp;

option java_package = "com.google.javascript.jscomp";
option java_multiple_files = true;

// A container to describe code requirements
message ConformanceConfig {
  repeated Requirement requirement = 1;
}

// A specification of code requirements
message Requirement {

  // Required: The message to report when a requirement is violated. This should
  // reference a document describing the reasoning for the requirement
  // and contacts.
  optional string error_message = 1;

  // Optional: A list of source paths that are exempt from the requirement.
  repeated string whitelist = 2;

  // Optional: A list of source paths regexs that are exempt from the
  // requirement.
  repeated string whitelist_regexp = 3;

  // Optional: A list of source paths that will be checked for the requirement
  // (the opposite of whitelist). It is an error to specify both
  // (whitelist/whitelist_regexp) and (only_apply_to/only_apply_to_regexp).
  repeated string only_apply_to = 4;

  // Optional: A list of source path regexps that will be checked for
  // the requirement (the opposite of whitelist_regexp).
  // It is an error to specify both
  // (whitelist/whitelist_regexp) and (only_apply_to/only_apply_to_regexp).
  repeated string only_apply_to_regexp = 5;

  // A classification of the requirement and how it is enforced.
  enum Type {
    // A requirement enforced with code a external java class.
    CUSTOM = 1;

    // A forbidden source file
    BANNED_DEPENDENCY = 2;

    // A forbidden fully distinguished name. For example:
    //  - A global name like "eval" or "goog"
    //  - A namespaced value or type:  namespace.Banned
    //  - A 'static' property:  "namespace.Foo.banned"
    BANNED_NAME = 3;

    // A banned instance property, for example:
    //  - An 'instance' property:   "namespace.Foo.prototype.banned"
    //  - All properties of a given name "Object.prototype.banned"
    BANNED_PROPERTY = 4;

    // A banned reading from an instance property, for example:
    //  - An 'instance' property:   "namespace.Foo.prototype.banned"
    //  - All properties of a given name "Object.prototype.banned"
    // Unlike BANNED_PROPERTY, this only bans reads to the property,
    // i.e. its use as an rvalue.
    BANNED_PROPERTY_READ = 5;

    // A banned write to an instance property, for example:
    //  - An 'instance' property:   "namespace.Foo.prototype.banned"
    //  - All properties of a given name "Object.prototype.banned"
    // Unlike BANNED_PROPERTY, this only bans assignments to the property,
    // i.e. its use as an lvalue.
    BANNED_PROPERTY_WRITE = 6;

    // A restricted call, for example:
    //  - the "parseInt" call must be called with a radix:
    //  parseInt:function(string, int)
    RESTRICTED_NAME_CALL = 7;

    // A restricted call, for example:
    //  - The unsafe opt_html parameter must not be passed to createNode:
    //  goog.ui.tree.TreeControl.prototype.createNode:function()
    RESTRICTED_METHOD_CALL = 8;

    // A banned code pattern. This check is done using against an AST.
    // To ban a call to eval:
    //    "/** @param {?} a */ function template(a) {eval(a);}"
    BANNED_CODE_PATTERN = 9;

    // A banned function call. for example:
    //  - An 'instance' property: "namespace.Foo.prototype.banned"
    //  - All properties of a given name "Object.prototype.banned"
    // Unlike BANNED_PROPERTY, this only bans calls to the property
    // i.e. using the property as a value is allowed.
    BANNED_PROPERTY_CALL = 10;
  }

  // Required: The type of requirement.
  optional Type type = 6;

  // The value banned, optional for "custom" requirements.
  repeated string value = 7;

  // For "custom" requirements, the Java class used to enforce the requirement.
  // Ignored otherwise.
  optional string java_class = 8;

  // Gives the rule an unique ID that can be used for extending in other rules
  // through 'extends'. An example of ID is 'closure:innerHtml'.
  optional string rule_id = 9;

  // Allows extending whitelists of rules with the specified rule_id. If this
  // field is specified then all fields except whitelist, whitelist_regexp,
  // only_apply_to and only_apply_to_regexp are ignored.
  optional string extends = 10;

  // CUSTOM requirements may use extensions, each extension should use
  // a CL number as a unique identifier.
  extensions 1000000 to max;
}
