// Copyright 2025 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/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/datacatalog/v1/common.proto";
import "google/cloud/datacatalog/v1/timestamps.proto";
import "google/iam/v1/iam_policy.proto";
import "google/iam/v1/policy.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

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_outer_classname = "PolicyTagManagerProto";
option java_package = "com.google.cloud.datacatalog.v1";
option php_namespace = "Google\\Cloud\\DataCatalog\\V1";
option ruby_package = "Google::Cloud::DataCatalog::V1";

// Policy Tag Manager API service allows you to manage your policy tags and
// taxonomies.
//
// Policy tags are used to tag BigQuery columns and apply additional access
// control policies. A taxonomy is a hierarchical grouping of policy tags that
// classify data along a common axis.
service PolicyTagManager {
  option (google.api.default_host) = "datacatalog.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Creates a taxonomy in a specified project.
  //
  // The taxonomy is initially empty, that is, it doesn't contain policy tags.
  rpc CreateTaxonomy(CreateTaxonomyRequest) returns (Taxonomy) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/taxonomies"
      body: "taxonomy"
    };
    option (google.api.method_signature) = "parent,taxonomy";
  }

  // Deletes a taxonomy, including all policy tags in this
  // taxonomy, their associated policies, and the policy tags references from
  // BigQuery columns.
  rpc DeleteTaxonomy(DeleteTaxonomyRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/taxonomies/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a taxonomy, including its display name,
  // description, and activated policy types.
  rpc UpdateTaxonomy(UpdateTaxonomyRequest) returns (Taxonomy) {
    option (google.api.http) = {
      patch: "/v1/{taxonomy.name=projects/*/locations/*/taxonomies/*}"
      body: "taxonomy"
    };
    option (google.api.method_signature) = "taxonomy";
  }

  // Lists all taxonomies in a project in a particular location that you
  // have a permission to view.
  rpc ListTaxonomies(ListTaxonomiesRequest) returns (ListTaxonomiesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/taxonomies"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a taxonomy.
  rpc GetTaxonomy(GetTaxonomyRequest) returns (Taxonomy) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/taxonomies/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a policy tag in a taxonomy.
  rpc CreatePolicyTag(CreatePolicyTagRequest) returns (PolicyTag) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/taxonomies/*}/policyTags"
      body: "policy_tag"
    };
    option (google.api.method_signature) = "parent,policy_tag";
  }

  // Deletes a policy tag together with the following:
  //
  // * All of its descendant policy tags, if any
  // * Policies associated with the policy tag and its descendants
  // * References from BigQuery table schema of the policy tag and its
  //   descendants
  rpc DeletePolicyTag(DeletePolicyTagRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/taxonomies/*/policyTags/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a policy tag, including its display
  // name, description, and parent policy tag.
  rpc UpdatePolicyTag(UpdatePolicyTagRequest) returns (PolicyTag) {
    option (google.api.http) = {
      patch: "/v1/{policy_tag.name=projects/*/locations/*/taxonomies/*/policyTags/*}"
      body: "policy_tag"
    };
    option (google.api.method_signature) = "policy_tag";
  }

  // Lists all policy tags in a taxonomy.
  rpc ListPolicyTags(ListPolicyTagsRequest) returns (ListPolicyTagsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/taxonomies/*}/policyTags"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a policy tag.
  rpc GetPolicyTag(GetPolicyTagRequest) returns (PolicyTag) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/taxonomies/*/policyTags/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets the IAM policy for a policy tag or a taxonomy.
  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/taxonomies/*}:getIamPolicy"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/taxonomies/*/policyTags/*}:getIamPolicy"
        body: "*"
      }
    };
  }

  // Sets the IAM policy for a policy tag or a taxonomy.
  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/taxonomies/*}:setIamPolicy"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/taxonomies/*/policyTags/*}:setIamPolicy"
        body: "*"
      }
    };
  }

  // Returns your permissions on a specified policy tag or
  // taxonomy.
  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest)
      returns (google.iam.v1.TestIamPermissionsResponse) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/locations/*/taxonomies/*}:testIamPermissions"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/locations/*/taxonomies/*/policyTags/*}:testIamPermissions"
        body: "*"
      }
    };
  }
}

// A taxonomy is a collection of hierarchical policy tags that classify data
// along a common axis.
//
// For example, a "data sensitivity" taxonomy might contain the following policy
// tags:
//
// ```
// + PII
//   + Account number
//   + Age
//   + SSN
//   + Zipcode
// + Financials
//   + Revenue
// ```
//
// A "data origin" taxonomy might contain the following policy tags:
//
// ```
// + User data
// + Employee data
// + Partner data
// + Public data
// ```
message Taxonomy {
  option (google.api.resource) = {
    type: "datacatalog.googleapis.com/Taxonomy"
    pattern: "projects/{project}/locations/{location}/taxonomies/{taxonomy}"
  };

  // Defines policy types where the policy tags can be used for.
  enum PolicyType {
    // Unspecified policy type.
    POLICY_TYPE_UNSPECIFIED = 0;

    // Fine-grained access control policy that enables access control on
    // tagged sub-resources.
    FINE_GRAINED_ACCESS_CONTROL = 1;
  }

  // The source system of the Taxonomy.
  message Service {
    // The Google Cloud service name.
    ManagingSystem name = 1;

    // The service agent for the service.
    string identity = 2;
  }

  // Identifier. Resource name of this taxonomy in URL format.
  //
  // Note: Policy tag manager generates unique taxonomy IDs.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Required. User-defined name of this taxonomy.
  //
  // The name can't start or end with spaces, must contain only Unicode letters,
  // numbers, underscores, dashes, and spaces, and be at most 200 bytes long
  // when encoded in UTF-8.
  //
  // The taxonomy display name must be unique within an organization.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Description of this taxonomy. If not set, defaults to empty.
  //
  // The description must contain only Unicode characters, tabs, newlines,
  // carriage returns, and page breaks, and be at most 2000 bytes long when
  // encoded in UTF-8.
  string description = 3 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Number of policy tags in this taxonomy.
  int32 policy_tag_count = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Creation and modification timestamps of this taxonomy.
  SystemTimestamps taxonomy_timestamps = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. A list of policy types that are activated for this taxonomy. If
  // not set, defaults to an empty list.
  repeated PolicyType activated_policy_types = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. Identity of the service which owns the Taxonomy. This field is
  // only populated when the taxonomy is created by a Google Cloud service.
  // Currently only 'DATAPLEX' is supported.
  Service service = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Denotes one policy tag in a taxonomy, for example, SSN.
//
// Policy tags can be defined in a hierarchy. For example:
//
// ```
// + Geolocation
//   + LatLong
//   + City
//   + ZipCode
// ```
//
// Where the "Geolocation" policy tag contains three children.
message PolicyTag {
  option (google.api.resource) = {
    type: "datacatalog.googleapis.com/PolicyTag"
    pattern: "projects/{project}/locations/{location}/taxonomies/{taxonomy}/policyTags/{policy_tag}"
  };

  // Identifier. Resource name of this policy tag in the URL format.
  //
  // The policy tag manager generates unique taxonomy IDs and policy tag IDs.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Required. User-defined name of this policy tag.
  //
  // The name can't start or end with spaces and must be unique within the
  // parent taxonomy, contain only Unicode letters, numbers, underscores, dashes
  // and spaces, and be at most 200 bytes long when encoded in UTF-8.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Description of this policy tag. If not set, defaults to empty.
  //
  // The description must contain only Unicode characters,
  // tabs, newlines, carriage returns and page breaks, and be at most 2000 bytes
  // long when encoded in UTF-8.
  string description = 3;

  // Resource name of this policy tag's parent policy tag. If empty, this is a
  // top level tag. If not set, defaults to an empty string.
  //
  // For example, for the "LatLong" policy tag in the example above, this field
  // contains the resource name of the "Geolocation" policy tag, and, for
  // "Geolocation", this field is empty.
  string parent_policy_tag = 4;

  // Output only. Resource names of child policy tags of this policy tag.
  repeated string child_policy_tags = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for
// [CreateTaxonomy][google.cloud.datacatalog.v1.PolicyTagManager.CreateTaxonomy].
message CreateTaxonomyRequest {
  // Required. Resource name of the project that the taxonomy will belong to.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datacatalog.googleapis.com/Taxonomy"
    }
  ];

  // The taxonomy to create.
  Taxonomy taxonomy = 2;
}

// Request message for
// [DeleteTaxonomy][google.cloud.datacatalog.v1.PolicyTagManager.DeleteTaxonomy].
message DeleteTaxonomyRequest {
  // Required. Resource name of the taxonomy to delete.
  //
  // Note: All policy tags in this taxonomy are also deleted.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datacatalog.googleapis.com/Taxonomy"
    }
  ];
}

// Request message for
// [UpdateTaxonomy][google.cloud.datacatalog.v1.PolicyTagManager.UpdateTaxonomy].
message UpdateTaxonomyRequest {
  // The taxonomy to update. You can update only its description, display name,
  // and activated policy types.
  Taxonomy taxonomy = 1;

  // Specifies fields to update. If not set, defaults to all fields you can
  // update.
  //
  // For more information, see [FieldMask]
  // (https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask).
  google.protobuf.FieldMask update_mask = 2;
}

// Request message for
// [ListTaxonomies][google.cloud.datacatalog.v1.PolicyTagManager.ListTaxonomies].
message ListTaxonomiesRequest {
  // Required. Resource name of the project to list the taxonomies of.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datacatalog.googleapis.com/Taxonomy"
    }
  ];

  // The maximum number of items to return. Must be a value between 1 and 1000
  // inclusively. If not set, defaults to 50.
  int32 page_size = 2;

  // The pagination token of the next results page. If not set,
  // the first page is returned.
  //
  // The token is returned in the response to a previous list request.
  string page_token = 3;

  // Supported field for filter is 'service' and value is 'dataplex'.
  // Eg: service=dataplex.
  string filter = 4;
}

// Response message for
// [ListTaxonomies][google.cloud.datacatalog.v1.PolicyTagManager.ListTaxonomies].
message ListTaxonomiesResponse {
  // Taxonomies that the project contains.
  repeated Taxonomy taxonomies = 1;

  // Pagination token of the next results page. Empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

// Request message for
// [GetTaxonomy][google.cloud.datacatalog.v1.PolicyTagManager.GetTaxonomy].
message GetTaxonomyRequest {
  // Required. Resource name of the taxonomy to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datacatalog.googleapis.com/Taxonomy"
    }
  ];
}

// Request message for
// [CreatePolicyTag][google.cloud.datacatalog.v1.PolicyTagManager.CreatePolicyTag].
message CreatePolicyTagRequest {
  // Required. Resource name of the taxonomy that the policy tag will belong to.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datacatalog.googleapis.com/PolicyTag"
    }
  ];

  // The policy tag to create.
  PolicyTag policy_tag = 2;
}

// Request message for
// [DeletePolicyTag][google.cloud.datacatalog.v1.PolicyTagManager.DeletePolicyTag].
message DeletePolicyTagRequest {
  // Required. Resource name of the policy tag to delete.
  //
  // Note: All of its descendant policy tags are also deleted.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datacatalog.googleapis.com/PolicyTag"
    }
  ];
}

// Request message for
// [UpdatePolicyTag][google.cloud.datacatalog.v1.PolicyTagManager.UpdatePolicyTag].
message UpdatePolicyTagRequest {
  // The policy tag to update. You can update only its description, display
  // name, and parent policy tag fields.
  PolicyTag policy_tag = 1;

  // Specifies the fields to update.
  //
  // You can update only display name, description, and parent policy tag.
  // If not set, defaults to all updatable fields.
  // For more information, see [FieldMask]
  // (https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask).
  google.protobuf.FieldMask update_mask = 2;
}

// Request message for
// [ListPolicyTags][google.cloud.datacatalog.v1.PolicyTagManager.ListPolicyTags].
message ListPolicyTagsRequest {
  // Required. Resource name of the taxonomy to list the policy tags of.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datacatalog.googleapis.com/PolicyTag"
    }
  ];

  // The maximum number of items to return. Must be a value between 1 and 1000
  // inclusively.
  // If not set, defaults to 50.
  int32 page_size = 2;

  // The pagination token of the next results page. If not set, returns the
  // first page.
  //
  // The token is returned in the response to a previous list request.
  string page_token = 3;
}

// Response message for
// [ListPolicyTags][google.cloud.datacatalog.v1.PolicyTagManager.ListPolicyTags].
message ListPolicyTagsResponse {
  // The policy tags that belong to the taxonomy.
  repeated PolicyTag policy_tags = 1;

  // Pagination token of the next results page. Empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

// Request message for
// [GetPolicyTag][google.cloud.datacatalog.v1.PolicyTagManager.GetPolicyTag].
message GetPolicyTagRequest {
  // Required. Resource name of the policy tag.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datacatalog.googleapis.com/PolicyTag"
    }
  ];
}
