// Copyright 2020 Google LLC
//
// 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 = "proto3";

package google.cloud.datacatalog.v1beta1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.DataCatalog.V1Beta1";
option go_package = "google.golang.org/genproto/googleapis/cloud/datacatalog/v1beta1;datacatalog";
option java_multiple_files = true;
option java_package = "com.google.cloud.datacatalog.v1beta1";
option php_namespace = "Google\\Cloud\\DataCatalog\\V1beta1";
option ruby_package = "Google::Cloud::DataCatalog::V1beta1";

// Tags are used to attach custom metadata to Data Catalog resources. Tags
// conform to the specifications within their tag template.
//
// See [Data Catalog
// IAM](https://cloud.google.com/data-catalog/docs/concepts/iam) for information
// on the permissions needed to create or view tags.
message Tag {
  option (google.api.resource) = {
    type: "datacatalog.googleapis.com/Tag"
    pattern: "projects/{project}/locations/{location}/entryGroups/{entry_group}/entries/{entry}/tags/{tag}"
  };

  // The resource name of the tag in URL format. Example:
  //
  // * projects/{project_id}/locations/{location}/entrygroups/{entry_group_id}/entries/{entry_id}/tags/{tag_id}
  //
  // where `tag_id` is a system-generated identifier.
  // Note that this Tag may not actually be stored in the location in this name.
  string name = 1;

  // Required. The resource name of the tag template that this tag uses. Example:
  //
  // * projects/{project_id}/locations/{location}/tagTemplates/{tag_template_id}
  //
  // This field cannot be modified after creation.
  string template = 2 [(google.api.field_behavior) = REQUIRED];

  // Output only. The display name of the tag template.
  string template_display_name = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The scope within the parent resource that this tag is attached to. If not
  // provided, the tag is attached to the parent resource itself.
  // Deleting the scope from the parent resource will delete all tags attached
  // to that scope. These fields cannot be updated after creation.
  oneof scope {
    // Resources like Entry can have schemas associated with them. This scope
    // allows users to attach tags to an individual column based on that schema.
    //
    // For attaching a tag to a nested column, use `.` to separate the column
    // names. Example:
    //
    // * `outer_column.inner_column`
    string column = 4;
  }

  // Required. This maps the ID of a tag field to the value of and additional information
  // about that field. Valid field IDs are defined by the tag's template. A tag
  // must have at least 1 field and at most 500 fields.
  map<string, TagField> fields = 3 [(google.api.field_behavior) = REQUIRED];
}

// Contains the value and supporting information for a field within
// a [Tag][google.cloud.datacatalog.v1beta1.Tag].
message TagField {
  // Holds an enum value.
  message EnumValue {
    // The display name of the enum value.
    string display_name = 1;
  }

  // Output only. The display name of this field.
  string display_name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The value of this field.
  oneof kind {
    // Holds the value for a tag field with double type.
    double double_value = 2;

    // Holds the value for a tag field with string type.
    string string_value = 3;

    // Holds the value for a tag field with boolean type.
    bool bool_value = 4;

    // Holds the value for a tag field with timestamp type.
    google.protobuf.Timestamp timestamp_value = 5;

    // Holds the value for a tag field with enum type. This value must be
    // one of the allowed values in the definition of this enum.
    EnumValue enum_value = 6;
  }

  // Output only. The order of this field with respect to other fields in this tag. It can be
  // set in [Tag][google.cloud.datacatalog.v1beta1.TagTemplateField.order]. For
  // example, a higher value can indicate a more important field. The value can
  // be negative. Multiple fields can have the same order, and field orders
  // within a tag do not have to be sequential.
  int32 order = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A tag template defines a tag, which can have one or more typed fields.
// The template is used to create and attach the tag to GCP resources.
// [Tag template
// roles](https://cloud.google.com/iam/docs/understanding-roles#data-catalog-roles)
// provide permissions to create, edit, and use the template. See, for example,
// the [TagTemplate
// User](https://cloud.google.com/data-catalog/docs/how-to/template-user) role,
// which includes permission to use the tag template to tag resources.
message TagTemplate {
  option (google.api.resource) = {
    type: "datacatalog.googleapis.com/TagTemplate"
    pattern: "projects/{project}/locations/{location}/tagTemplates/{tag_template}"
  };

  // The resource name of the tag template in URL format. Example:
  //
  // * projects/{project_id}/locations/{location}/tagTemplates/{tag_template_id}
  //
  // Note that this TagTemplate and its child resources may not actually be
  // stored in the location in this name.
  string name = 1;

  // The display name for this template. Defaults to an empty string.
  string display_name = 2;

  // Required. Map of tag template field IDs to the settings for the field.
  // This map is an exhaustive list of the allowed fields. This map must contain
  // at least one field and at most 500 fields.
  //
  // The keys to this map are tag template field IDs. Field IDs can contain
  // letters (both uppercase and lowercase), numbers (0-9) and underscores (_).
  // Field IDs must be at least 1 character long and at most
  // 64 characters long. Field IDs must start with a letter or underscore.
  map<string, TagTemplateField> fields = 3 [(google.api.field_behavior) = REQUIRED];
}

// The template for an individual field within a tag template.
message TagTemplateField {
  option (google.api.resource) = {
    type: "datacatalog.googleapis.com/TagTemplateField"
    pattern: "projects/{project}/locations/{location}/tagTemplates/{tag_template}/fields/{field}"
  };

  // Output only. The resource name of the tag template field in URL format. Example:
  //
  // * projects/{project_id}/locations/{location}/tagTemplates/{tag_template}/fields/{field}
  //
  // Note that this TagTemplateField may not actually be stored in the location
  // in this name.
  string name = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The display name for this field. Defaults to an empty string.
  string display_name = 1;

  // Required. The type of value this tag field can contain.
  FieldType type = 2 [(google.api.field_behavior) = REQUIRED];

  // Whether this is a required field. Defaults to false.
  bool is_required = 3;

  // The order of this field with respect to other fields in this tag
  // template.  A higher value indicates a more important field. The value can
  // be negative. Multiple fields can have the same order, and field orders
  // within a tag do not have to be sequential.
  int32 order = 5;
}

message FieldType {
  message EnumType {
    message EnumValue {
      // Required. The display name of the enum value. Must not be an empty string.
      string display_name = 1 [(google.api.field_behavior) = REQUIRED];
    }

    // Required on create; optional on update. The set of allowed values for
    // this enum. This set must not be empty, the display names of the values in
    // this set must not be empty and the display names of the values must be
    // case-insensitively unique within this set. Currently, enum values can
    // only be added to the list of allowed values. Deletion and renaming of
    // enum values are not supported. Can have up to 500 allowed values.
    repeated EnumValue allowed_values = 1;
  }

  enum PrimitiveType {
    // This is the default invalid value for a type.
    PRIMITIVE_TYPE_UNSPECIFIED = 0;

    // A double precision number.
    DOUBLE = 1;

    // An UTF-8 string.
    STRING = 2;

    // A boolean value.
    BOOL = 3;

    // A timestamp.
    TIMESTAMP = 4;
  }

  // Required.
  oneof type_decl {
    // Represents primitive types - string, bool etc.
    PrimitiveType primitive_type = 1;

    // Represents an enum type.
    EnumType enum_type = 2;
  }
}
