// Copyright 2024 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.v1;

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.V1";
option go_package = "cloud.google.com/go/datacatalog/apiv1/datacatalogpb;datacatalogpb";
option java_multiple_files = true;
option java_package = "com.google.cloud.datacatalog.v1";
option php_namespace = "Google\\Cloud\\DataCatalog\\V1";
option ruby_package = "Google::Cloud::DataCatalog::V1";

// Tags contain custom metadata and are attached to Data Catalog resources. Tags
// conform with the specification of 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 where tag ID is a
  // system-generated identifier.
  //
  // Note: The tag itself might not be stored in the location specified in its
  // name.
  string name = 1;

  // Required. The resource name of the tag template 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 deletes 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 you to attach tags to an individual column based on that schema.
    //
    // To attach a tag to a nested column, separate column names with a dot
    // (`.`). Example: `column.nested_column`.
    string column = 4;
  }

  // Required. Maps the ID of a tag field to its value and additional
  // information about that field.
  //
  // Tag template defines valid field IDs. 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 additional information on a field within
// a [Tag][google.cloud.datacatalog.v1.Tag].
message TagField {
  // 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 {
    // The value of a tag field with a double type.
    double double_value = 2;

    // The value of a tag field with a string type.
    //
    // The maximum length is 2000 UTF-8 characters.
    string string_value = 3;

    // The value of a tag field with a boolean type.
    bool bool_value = 4;

    // The value of a tag field with a timestamp type.
    google.protobuf.Timestamp timestamp_value = 5;

    // The value of a tag field with an enum type.
    //
    // This value must be one of the allowed values listed in this enum.
    EnumValue enum_value = 6;

    // The value of a tag field with a rich text type.
    //
    // The maximum length is 10 MiB as this value holds HTML descriptions
    // including encoded images. The maximum length of the text without images
    // is 100 KiB.
    string richtext_value = 8;
  }

  // Output only. The order of this field with respect to other fields in this
  // tag. Can be set by
  // [Tag][google.cloud.datacatalog.v1.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 don't have to be sequential.
  int32 order = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A tag template defines a tag that can have one or more typed fields.
//
// The template is used to create tags that are attached to Google Cloud
//  resources. [Tag template roles]
// (https://cloud.google.com/iam/docs/understanding-roles#data-catalog-roles)
// provide permissions to create, edit, and use the template. For example,
// see the [TagTemplate User]
// (https://cloud.google.com/data-catalog/docs/how-to/template-user) role
// that includes a 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.
  //
  // Note: The tag template itself and its child resources might not be
  // stored in the location specified in its name.
  string name = 1;

  // Display name for this template. Defaults to an empty string.
  //
  // The name must contain only Unicode letters, numbers (0-9), underscores (_),
  // dashes (-), spaces ( ), and can't start or end with spaces.
  // The maximum length is 200 characters.
  string display_name = 2;

  // Indicates whether tags created with this template are public. Public tags
  // do not require tag template access to appear in
  // [ListTags][google.cloud.datacatalog.v1.ListTags] API response.
  //
  // Additionally, you can search for a public tag by value with a
  // simple search query in addition to using a ``tag:`` predicate.
  bool is_publicly_readable = 5;

  // Required. Map of tag template field IDs to the settings for the field.
  // This map is an exhaustive list of the allowed fields. The map must contain
  // at least one field and at most 500 fields.
  //
  // The keys to this map are tag template field IDs. The IDs have the
  // following limitations:
  //
  // * Can contain uppercase and lowercase letters, numbers (0-9) and
  //   underscores (_).
  // * Must be at least 1 character and at most 64 characters long.
  // * 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: The tag template field itself might not be stored in the location
  // specified in its name.
  //
  // The name must contain only letters (a-z, A-Z), numbers (0-9),
  // or underscores (_), and must start with a letter or underscore.
  // The maximum length is 64 characters.
  string name = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The display name for this field. Defaults to an empty string.
  //
  // The name must contain only Unicode letters, numbers (0-9), underscores (_),
  // dashes (-), spaces ( ), and can't start or end with spaces.
  // The maximum length is 200 characters.
  string display_name = 1;

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

  // If true, this field is required. Defaults to false.
  bool is_required = 3;

  // The description for this field. Defaults to an empty string.
  string description = 4;

  // The order of this field with respect to other fields in this tag
  // template.
  //
  // 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 don't have to be sequential.
  int32 order = 5;
}

message FieldType {
  enum PrimitiveType {
    // 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;

    // A Richtext description.
    RICHTEXT = 5;
  }

  message EnumType {
    message EnumValue {
      // Required. The display name of the enum value. Must not be an empty
      // string.
      //
      // The name must contain only Unicode letters, numbers (0-9), underscores
      // (_), dashes (-), spaces ( ), and can't start or end with spaces. The
      // maximum length is 200 characters.
      string display_name = 1 [(google.api.field_behavior) = REQUIRED];
    }

    // The set of allowed values for this enum.
    //
    // This set must not be empty and can include up to 100 allowed values.
    // The display names of the values in this set must not be empty and must
    // be case-insensitively unique within this set.
    //
    // The order of items in this set is preserved. This field can be used to
    // create, remove, and reorder enum values. To rename enum values, use the
    // `RenameTagTemplateFieldEnumValue` method.
    repeated EnumValue allowed_values = 1;
  }

  // Required.
  oneof type_decl {
    // Primitive types, such as string, boolean, etc.
    PrimitiveType primitive_type = 1;

    // An enum type.
    EnumType enum_type = 2;
  }
}
