// 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.privacy.dlp.v2;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/privacy/dlp/v2/storage.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";
import "google/type/date.proto";
import "google/type/dayofweek.proto";
import "google/type/timeofday.proto";

option csharp_namespace = "Google.Cloud.Dlp.V2";
option go_package = "cloud.google.com/go/dlp/apiv2/dlppb;dlppb";
option java_multiple_files = true;
option java_outer_classname = "DlpProto";
option java_package = "com.google.privacy.dlp.v2";
option php_namespace = "Google\\Cloud\\Dlp\\V2";
option ruby_package = "Google::Cloud::Dlp::V2";
option (google.api.resource_definition) = {
  type: "dlp.googleapis.com/DlpContent"
  pattern: "projects/{project}/dlpContent"
  pattern: "projects/{project}/locations/{location}/dlpContent"
};
option (google.api.resource_definition) = {
  type: "dlp.googleapis.com/OrganizationLocation"
  pattern: "organizations/{organization}/locations/{location}"
};

// Sensitive Data Protection provides access to a powerful sensitive data
// inspection, classification, and de-identification platform that works
// on text, images, and Google Cloud storage repositories.
// To learn more about concepts and find how-to guides see
// https://cloud.google.com/sensitive-data-protection/docs/.
service DlpService {
  option (google.api.default_host) = "dlp.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Finds potentially sensitive info in content.
  // This method has limits on input size, processing time, and output size.
  //
  // When no InfoTypes or CustomInfoTypes are specified in this request, the
  // system will automatically choose what detectors to run. By default this may
  // be all types, but may change over time as detectors are updated.
  //
  // For how to guides, see
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-images
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-text,
  rpc InspectContent(InspectContentRequest) returns (InspectContentResponse) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/content:inspect"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/content:inspect"
        body: "*"
      }
    };
  }

  // Redacts potentially sensitive info from an image.
  // This method has limits on input size, processing time, and output size.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/redacting-sensitive-data-images
  // to learn more.
  //
  // When no InfoTypes or CustomInfoTypes are specified in this request, the
  // system will automatically choose what detectors to run. By default this may
  // be all types, but may change over time as detectors are updated.
  //
  // Only the first frame of each multiframe image is redacted. Metadata and
  // other frames are omitted in the response.
  rpc RedactImage(RedactImageRequest) returns (RedactImageResponse) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/image:redact"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/image:redact"
        body: "*"
      }
    };
  }

  // De-identifies potentially sensitive info from a ContentItem.
  // This method has limits on input size and output size.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/deidentify-sensitive-data
  // to learn more.
  //
  // When no InfoTypes or CustomInfoTypes are specified in this request, the
  // system will automatically choose what detectors to run. By default this may
  // be all types, but may change over time as detectors are updated.
  rpc DeidentifyContent(DeidentifyContentRequest)
      returns (DeidentifyContentResponse) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/content:deidentify"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/content:deidentify"
        body: "*"
      }
    };
  }

  // Re-identifies content that has been de-identified.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/pseudonymization#re-identification_in_free_text_code_example
  // to learn more.
  rpc ReidentifyContent(ReidentifyContentRequest)
      returns (ReidentifyContentResponse) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/content:reidentify"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/content:reidentify"
        body: "*"
      }
    };
  }

  // Returns a list of the sensitive information types that the DLP API
  // supports. See
  // https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference
  // to learn more.
  rpc ListInfoTypes(ListInfoTypesRequest) returns (ListInfoTypesResponse) {
    option (google.api.http) = {
      get: "/v2/infoTypes"
      additional_bindings { get: "/v2/{parent=locations/*}/infoTypes" }
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/infoTypes"
      }
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/infoTypes"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Creates an InspectTemplate for reusing frequently used configuration
  // for inspecting content, images, and storage.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates
  // to learn more.
  rpc CreateInspectTemplate(CreateInspectTemplateRequest)
      returns (InspectTemplate) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*/locations/*}/inspectTemplates"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/inspectTemplates"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=projects/*}/inspectTemplates"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=organizations/*}/inspectTemplates"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,inspect_template";
  }

  // Updates the InspectTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates
  // to learn more.
  rpc UpdateInspectTemplate(UpdateInspectTemplateRequest)
      returns (InspectTemplate) {
    option (google.api.http) = {
      patch: "/v2/{name=projects/*/locations/*/inspectTemplates/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/inspectTemplates/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=projects/*/inspectTemplates/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=organizations/*/inspectTemplates/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name,inspect_template,update_mask";
  }

  // Gets an InspectTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates
  // to learn more.
  rpc GetInspectTemplate(GetInspectTemplateRequest) returns (InspectTemplate) {
    option (google.api.http) = {
      get: "/v2/{name=projects/*/locations/*/inspectTemplates/*}"
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/inspectTemplates/*}"
      }
      additional_bindings { get: "/v2/{name=projects/*/inspectTemplates/*}" }
      additional_bindings {
        get: "/v2/{name=organizations/*/inspectTemplates/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists InspectTemplates.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates
  // to learn more.
  rpc ListInspectTemplates(ListInspectTemplatesRequest)
      returns (ListInspectTemplatesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*/locations/*}/inspectTemplates"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/inspectTemplates"
      }
      additional_bindings { get: "/v2/{parent=projects/*}/inspectTemplates" }
      additional_bindings {
        get: "/v2/{parent=organizations/*}/inspectTemplates"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes an InspectTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates
  // to learn more.
  rpc DeleteInspectTemplate(DeleteInspectTemplateRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=projects/*/locations/*/inspectTemplates/*}"
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/inspectTemplates/*}"
      }
      additional_bindings { delete: "/v2/{name=projects/*/inspectTemplates/*}" }
      additional_bindings {
        delete: "/v2/{name=organizations/*/inspectTemplates/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a DeidentifyTemplate for reusing frequently used configuration
  // for de-identifying content, images, and storage.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates-deid
  // to learn more.
  rpc CreateDeidentifyTemplate(CreateDeidentifyTemplateRequest)
      returns (DeidentifyTemplate) {
    option (google.api.http) = {
      post: "/v2/{parent=organizations/*}/deidentifyTemplates"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/deidentifyTemplates"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=projects/*}/deidentifyTemplates"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/deidentifyTemplates"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,deidentify_template";
  }

  // Updates the DeidentifyTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates-deid
  // to learn more.
  rpc UpdateDeidentifyTemplate(UpdateDeidentifyTemplateRequest)
      returns (DeidentifyTemplate) {
    option (google.api.http) = {
      patch: "/v2/{name=organizations/*/deidentifyTemplates/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/deidentifyTemplates/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=projects/*/deidentifyTemplates/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=projects/*/locations/*/deidentifyTemplates/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) =
        "name,deidentify_template,update_mask";
  }

  // Gets a DeidentifyTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates-deid
  // to learn more.
  rpc GetDeidentifyTemplate(GetDeidentifyTemplateRequest)
      returns (DeidentifyTemplate) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/deidentifyTemplates/*}"
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/deidentifyTemplates/*}"
      }
      additional_bindings { get: "/v2/{name=projects/*/deidentifyTemplates/*}" }
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/deidentifyTemplates/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists DeidentifyTemplates.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates-deid
  // to learn more.
  rpc ListDeidentifyTemplates(ListDeidentifyTemplatesRequest)
      returns (ListDeidentifyTemplatesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*}/deidentifyTemplates"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/deidentifyTemplates"
      }
      additional_bindings { get: "/v2/{parent=projects/*}/deidentifyTemplates" }
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/deidentifyTemplates"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes a DeidentifyTemplate.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-templates-deid
  // to learn more.
  rpc DeleteDeidentifyTemplate(DeleteDeidentifyTemplateRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=organizations/*/deidentifyTemplates/*}"
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/deidentifyTemplates/*}"
      }
      additional_bindings {
        delete: "/v2/{name=projects/*/deidentifyTemplates/*}"
      }
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/deidentifyTemplates/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a job trigger to run DLP actions such as scanning storage for
  // sensitive information on a set schedule.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-job-triggers
  // to learn more.
  rpc CreateJobTrigger(CreateJobTriggerRequest) returns (JobTrigger) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/jobTriggers"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/jobTriggers"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/jobTriggers"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,job_trigger";
  }

  // Updates a job trigger.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-job-triggers
  // to learn more.
  rpc UpdateJobTrigger(UpdateJobTriggerRequest) returns (JobTrigger) {
    option (google.api.http) = {
      patch: "/v2/{name=projects/*/jobTriggers/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=projects/*/locations/*/jobTriggers/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/jobTriggers/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name,job_trigger,update_mask";
  }

  // Inspect hybrid content and store findings to a trigger. The inspection
  // will be processed asynchronously. To review the findings monitor the
  // jobs within the trigger.
  rpc HybridInspectJobTrigger(HybridInspectJobTriggerRequest)
      returns (HybridInspectResponse) {
    option (google.api.http) = {
      post: "/v2/{name=projects/*/locations/*/jobTriggers/*}:hybridInspect"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets a job trigger.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-job-triggers
  // to learn more.
  rpc GetJobTrigger(GetJobTriggerRequest) returns (JobTrigger) {
    option (google.api.http) = {
      get: "/v2/{name=projects/*/jobTriggers/*}"
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/jobTriggers/*}"
      }
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/jobTriggers/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists job triggers.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-job-triggers
  // to learn more.
  rpc ListJobTriggers(ListJobTriggersRequest)
      returns (ListJobTriggersResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*}/jobTriggers"
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/jobTriggers"
      }
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/jobTriggers"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes a job trigger.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-job-triggers
  // to learn more.
  rpc DeleteJobTrigger(DeleteJobTriggerRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=projects/*/jobTriggers/*}"
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/jobTriggers/*}"
      }
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/jobTriggers/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Activate a job trigger. Causes the immediate execute of a trigger
  // instead of waiting on the trigger event to occur.
  rpc ActivateJobTrigger(ActivateJobTriggerRequest) returns (DlpJob) {
    option (google.api.http) = {
      post: "/v2/{name=projects/*/jobTriggers/*}:activate"
      body: "*"
      additional_bindings {
        post: "/v2/{name=projects/*/locations/*/jobTriggers/*}:activate"
        body: "*"
      }
    };
  }

  // Creates a config for discovery to scan and profile storage.
  rpc CreateDiscoveryConfig(CreateDiscoveryConfigRequest)
      returns (DiscoveryConfig) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*/locations/*}/discoveryConfigs"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/discoveryConfigs"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,discovery_config";
  }

  // Updates a discovery configuration.
  rpc UpdateDiscoveryConfig(UpdateDiscoveryConfigRequest)
      returns (DiscoveryConfig) {
    option (google.api.http) = {
      patch: "/v2/{name=projects/*/locations/*/discoveryConfigs/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/discoveryConfigs/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name,discovery_config,update_mask";
  }

  // Gets a discovery configuration.
  rpc GetDiscoveryConfig(GetDiscoveryConfigRequest) returns (DiscoveryConfig) {
    option (google.api.http) = {
      get: "/v2/{name=projects/*/locations/*/discoveryConfigs/*}"
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/discoveryConfigs/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists discovery configurations.
  rpc ListDiscoveryConfigs(ListDiscoveryConfigsRequest)
      returns (ListDiscoveryConfigsResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*/locations/*}/discoveryConfigs"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/discoveryConfigs"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes a discovery configuration.
  rpc DeleteDiscoveryConfig(DeleteDiscoveryConfigRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=projects/*/locations/*/discoveryConfigs/*}"
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/discoveryConfigs/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new job to inspect storage or calculate risk metrics.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-storage
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/compute-risk-analysis
  // to learn more.
  //
  // When no InfoTypes or CustomInfoTypes are specified in inspect jobs, the
  // system will automatically choose what detectors to run. By default this may
  // be all types, but may change over time as detectors are updated.
  rpc CreateDlpJob(CreateDlpJobRequest) returns (DlpJob) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*}/dlpJobs"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/dlpJobs"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,inspect_job";
    option (google.api.method_signature) = "parent,risk_job";
  }

  // Lists DlpJobs that match the specified filter in the request.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-storage
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/compute-risk-analysis
  // to learn more.
  rpc ListDlpJobs(ListDlpJobsRequest) returns (ListDlpJobsResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*}/dlpJobs"
      additional_bindings { get: "/v2/{parent=projects/*/locations/*}/dlpJobs" }
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/dlpJobs"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets the latest state of a long-running DlpJob.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-storage
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/compute-risk-analysis
  // to learn more.
  rpc GetDlpJob(GetDlpJobRequest) returns (DlpJob) {
    option (google.api.http) = {
      get: "/v2/{name=projects/*/dlpJobs/*}"
      additional_bindings { get: "/v2/{name=projects/*/locations/*/dlpJobs/*}" }
    };
    option (google.api.method_signature) = "name";
  }

  // Deletes a long-running DlpJob. This method indicates that the client is
  // no longer interested in the DlpJob result. The job will be canceled if
  // possible.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-storage
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/compute-risk-analysis
  // to learn more.
  rpc DeleteDlpJob(DeleteDlpJobRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=projects/*/dlpJobs/*}"
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/dlpJobs/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Starts asynchronous cancellation on a long-running DlpJob. The server
  // makes a best effort to cancel the DlpJob, but success is not
  // guaranteed.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/inspecting-storage
  // and
  // https://cloud.google.com/sensitive-data-protection/docs/compute-risk-analysis
  // to learn more.
  rpc CancelDlpJob(CancelDlpJobRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v2/{name=projects/*/dlpJobs/*}:cancel"
      body: "*"
      additional_bindings {
        post: "/v2/{name=projects/*/locations/*/dlpJobs/*}:cancel"
        body: "*"
      }
    };
  }

  // Creates a pre-built stored infoType to be used for inspection.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-stored-infotypes
  // to learn more.
  rpc CreateStoredInfoType(CreateStoredInfoTypeRequest)
      returns (StoredInfoType) {
    option (google.api.http) = {
      post: "/v2/{parent=organizations/*}/storedInfoTypes"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/storedInfoTypes"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=projects/*}/storedInfoTypes"
        body: "*"
      }
      additional_bindings {
        post: "/v2/{parent=projects/*/locations/*}/storedInfoTypes"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,config";
  }

  // Updates the stored infoType by creating a new version. The existing version
  // will continue to be used until the new version is ready.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-stored-infotypes
  // to learn more.
  rpc UpdateStoredInfoType(UpdateStoredInfoTypeRequest)
      returns (StoredInfoType) {
    option (google.api.http) = {
      patch: "/v2/{name=organizations/*/storedInfoTypes/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/storedInfoTypes/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=projects/*/storedInfoTypes/*}"
        body: "*"
      }
      additional_bindings {
        patch: "/v2/{name=projects/*/locations/*/storedInfoTypes/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name,config,update_mask";
  }

  // Gets a stored infoType.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-stored-infotypes
  // to learn more.
  rpc GetStoredInfoType(GetStoredInfoTypeRequest) returns (StoredInfoType) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/storedInfoTypes/*}"
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/storedInfoTypes/*}"
      }
      additional_bindings { get: "/v2/{name=projects/*/storedInfoTypes/*}" }
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/storedInfoTypes/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists stored infoTypes.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-stored-infotypes
  // to learn more.
  rpc ListStoredInfoTypes(ListStoredInfoTypesRequest)
      returns (ListStoredInfoTypesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*}/storedInfoTypes"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/storedInfoTypes"
      }
      additional_bindings { get: "/v2/{parent=projects/*}/storedInfoTypes" }
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/storedInfoTypes"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes a stored infoType.
  // See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-stored-infotypes
  // to learn more.
  rpc DeleteStoredInfoType(DeleteStoredInfoTypeRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=organizations/*/storedInfoTypes/*}"
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/storedInfoTypes/*}"
      }
      additional_bindings { delete: "/v2/{name=projects/*/storedInfoTypes/*}" }
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/storedInfoTypes/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists project data profiles for an organization.
  rpc ListProjectDataProfiles(ListProjectDataProfilesRequest)
      returns (ListProjectDataProfilesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*/locations/*}/projectDataProfiles"
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/projectDataProfiles"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists table data profiles for an organization.
  rpc ListTableDataProfiles(ListTableDataProfilesRequest)
      returns (ListTableDataProfilesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*/locations/*}/tableDataProfiles"
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/tableDataProfiles"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists column data profiles for an organization.
  rpc ListColumnDataProfiles(ListColumnDataProfilesRequest)
      returns (ListColumnDataProfilesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*/locations/*}/columnDataProfiles"
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/columnDataProfiles"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a project data profile.
  rpc GetProjectDataProfile(GetProjectDataProfileRequest)
      returns (ProjectDataProfile) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/locations/*/projectDataProfiles/*}"
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/projectDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists file store data profiles for an organization.
  rpc ListFileStoreDataProfiles(ListFileStoreDataProfilesRequest)
      returns (ListFileStoreDataProfilesResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=organizations/*/locations/*}/fileStoreDataProfiles"
      additional_bindings {
        get: "/v2/{parent=projects/*/locations/*}/fileStoreDataProfiles"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a file store data profile.
  rpc GetFileStoreDataProfile(GetFileStoreDataProfileRequest)
      returns (FileStoreDataProfile) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/locations/*/fileStoreDataProfiles/*}"
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/fileStoreDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Delete a FileStoreDataProfile. Will not prevent the profile from being
  // regenerated if the resource is still included in a discovery configuration.
  rpc DeleteFileStoreDataProfile(DeleteFileStoreDataProfileRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=organizations/*/locations/*/fileStoreDataProfiles/*}"
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/fileStoreDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Gets a table data profile.
  rpc GetTableDataProfile(GetTableDataProfileRequest)
      returns (TableDataProfile) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/locations/*/tableDataProfiles/*}"
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/tableDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Gets a column data profile.
  rpc GetColumnDataProfile(GetColumnDataProfileRequest)
      returns (ColumnDataProfile) {
    option (google.api.http) = {
      get: "/v2/{name=organizations/*/locations/*/columnDataProfiles/*}"
      additional_bindings {
        get: "/v2/{name=projects/*/locations/*/columnDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Delete a TableDataProfile. Will not prevent the profile from being
  // regenerated if the table is still included in a discovery configuration.
  rpc DeleteTableDataProfile(DeleteTableDataProfileRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=organizations/*/locations/*/tableDataProfiles/*}"
      additional_bindings {
        delete: "/v2/{name=projects/*/locations/*/tableDataProfiles/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Inspect hybrid content and store findings to a job.
  // To review the findings, inspect the job. Inspection will occur
  // asynchronously.
  rpc HybridInspectDlpJob(HybridInspectDlpJobRequest)
      returns (HybridInspectResponse) {
    option (google.api.http) = {
      post: "/v2/{name=projects/*/locations/*/dlpJobs/*}:hybridInspect"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }

  // Finish a running hybrid DlpJob. Triggers the finalization steps and running
  // of any enabled actions that have not yet run.
  rpc FinishDlpJob(FinishDlpJobRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v2/{name=projects/*/locations/*/dlpJobs/*}:finish"
      body: "*"
    };
  }

  // Create a Connection to an external data source.
  rpc CreateConnection(CreateConnectionRequest) returns (Connection) {
    option (google.api.http) = {
      post: "/v2/{parent=projects/*/locations/*}/connections"
      body: "*"
      additional_bindings {
        post: "/v2/{parent=organizations/*/locations/*}/connections"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent, connection";
  }

  // Get a Connection by name.
  rpc GetConnection(GetConnectionRequest) returns (Connection) {
    option (google.api.http) = {
      get: "/v2/{name=projects/*/locations/*/connections/*}"
      additional_bindings {
        get: "/v2/{name=organizations/*/locations/*/connections/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists Connections in a parent. Use SearchConnections to see all connections
  // within an organization.
  rpc ListConnections(ListConnectionsRequest)
      returns (ListConnectionsResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*/locations/*}/connections"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/connections"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Searches for Connections in a parent.
  rpc SearchConnections(SearchConnectionsRequest)
      returns (SearchConnectionsResponse) {
    option (google.api.http) = {
      get: "/v2/{parent=projects/*/locations/*}/connections:search"
      additional_bindings {
        get: "/v2/{parent=organizations/*/locations/*}/connections:search"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Delete a Connection.
  rpc DeleteConnection(DeleteConnectionRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v2/{name=projects/*/locations/*/connections/*}"
      additional_bindings {
        delete: "/v2/{name=organizations/*/locations/*/connections/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Update a Connection.
  rpc UpdateConnection(UpdateConnectionRequest) returns (Connection) {
    option (google.api.http) = {
      patch: "/v2/{name=projects/*/locations/*/connections/*}"
      body: "*"
      additional_bindings {
        patch: "/v2/{name=organizations/*/locations/*/connections/*}"
        body: "*"
      }
    };
    option (google.api.method_signature) = "name";
  }
}

// List of excluded infoTypes.
message ExcludeInfoTypes {
  // InfoType list in ExclusionRule rule drops a finding when it overlaps or
  // contained within with a finding of an infoType from this list. For
  // example, for `InspectionRuleSet.info_types` containing "PHONE_NUMBER"` and
  // `exclusion_rule` containing `exclude_info_types.info_types` with
  // "EMAIL_ADDRESS" the phone number findings are dropped if they overlap
  // with EMAIL_ADDRESS finding.
  // That leads to "555-222-2222@example.org" to generate only a single
  // finding, namely email address.
  repeated InfoType info_types = 1;
}

// The rule to exclude findings based on a hotword. For record inspection of
// tables, column names are considered hotwords. An example of this is to
// exclude a finding if it belongs to a BigQuery column that matches a specific
// pattern.
message ExcludeByHotword {
  // Regular expression pattern defining what qualifies as a hotword.
  CustomInfoType.Regex hotword_regex = 1;

  // Range of characters within which the entire hotword must reside.
  // The total length of the window cannot exceed 1000 characters.
  // The windowBefore property in proximity should be set to 1 if the hotword
  // needs to be included in a column header.
  CustomInfoType.DetectionRule.Proximity proximity = 2;
}

// The rule that specifies conditions when findings of infoTypes specified in
// `InspectionRuleSet` are removed from results.
message ExclusionRule {
  // Exclusion rule types.
  oneof type {
    // Dictionary which defines the rule.
    CustomInfoType.Dictionary dictionary = 1;

    // Regular expression which defines the rule.
    CustomInfoType.Regex regex = 2;

    // Set of infoTypes for which findings would affect this rule.
    ExcludeInfoTypes exclude_info_types = 3;

    // Drop if the hotword rule is contained in the proximate context. For
    // tabular data, the context includes the column name.
    ExcludeByHotword exclude_by_hotword = 5;
  }

  // How the rule is applied, see MatchingType documentation for details.
  MatchingType matching_type = 4;
}

// A single inspection rule to be applied to infoTypes, specified in
// `InspectionRuleSet`.
message InspectionRule {
  // Inspection rule types.
  oneof type {
    // Hotword-based detection rule.
    CustomInfoType.DetectionRule.HotwordRule hotword_rule = 1;

    // Exclusion rule.
    ExclusionRule exclusion_rule = 2;
  }
}

// Rule set for modifying a set of infoTypes to alter behavior under certain
// circumstances, depending on the specific details of the rules within the set.
message InspectionRuleSet {
  // List of infoTypes this rule set is applied to.
  repeated InfoType info_types = 1;

  // Set of rules to be applied to infoTypes. The rules are applied in order.
  repeated InspectionRule rules = 2;
}

// Configuration description of the scanning process.
// When used with redactContent only info_types and min_likelihood are currently
// used.
message InspectConfig {
  // Configuration for setting a minimum likelihood per infotype. Used to
  // customize the minimum likelihood level for specific infotypes in the
  // request. For example, use this if you want to lower the precision for
  // PERSON_NAME without lowering the precision for the other infotypes in the
  // request.
  message InfoTypeLikelihood {
    // Type of information the likelihood threshold applies to. Only one
    // likelihood per info_type should be provided. If InfoTypeLikelihood does
    // not have an info_type, the configuration fails.
    InfoType info_type = 1;

    // Only returns findings equal to or above this threshold. This field is
    // required or else the configuration fails.
    Likelihood min_likelihood = 2;
  }

  // Configuration to control the number of findings returned for inspection.
  // This is not used for de-identification or data profiling.
  //
  // When redacting sensitive data from images, finding limits don't apply. They
  // can cause unexpected or inconsistent results, where only some data is
  // redacted. Don't include finding limits in
  // [RedactImage][google.privacy.dlp.v2.DlpService.RedactImage]
  // requests. Otherwise, Cloud DLP returns an error.
  message FindingLimits {
    // Max findings configuration per infoType, per content item or long
    // running DlpJob.
    message InfoTypeLimit {
      // Type of information the findings limit applies to. Only one limit per
      // info_type should be provided. If InfoTypeLimit does not have an
      // info_type, the DLP API applies the limit against all info_types that
      // are found but not specified in another InfoTypeLimit.
      InfoType info_type = 1;

      // Max findings limit for the given infoType.
      int32 max_findings = 2;
    }

    // Max number of findings that are returned for each item scanned.
    //
    // When set within an
    // [InspectContentRequest][google.privacy.dlp.v2.InspectContentRequest],
    // this field is ignored.
    //
    // This value isn't a hard limit. If the number of findings for an item
    // reaches this limit, the inspection of that item ends gradually, not
    // abruptly. Therefore, the actual number of findings that Cloud DLP returns
    // for the item can be multiple times higher than this value.
    int32 max_findings_per_item = 1;

    // Max number of findings that are returned per request or job.
    //
    // If you set this field in an
    // [InspectContentRequest][google.privacy.dlp.v2.InspectContentRequest], the
    // resulting maximum value is the value that you set or 3,000, whichever is
    // lower.
    //
    // This value isn't a hard limit. If an inspection reaches this limit, the
    // inspection ends gradually, not abruptly. Therefore, the actual number of
    // findings that Cloud DLP returns can be multiple times higher than this
    // value.
    int32 max_findings_per_request = 2;

    // Configuration of findings limit given for specified infoTypes.
    repeated InfoTypeLimit max_findings_per_info_type = 3;
  }

  // Restricts what info_types to look for. The values must correspond to
  // InfoType values returned by ListInfoTypes or listed at
  // https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference.
  //
  // When no InfoTypes or CustomInfoTypes are specified in a request, the
  // system may automatically choose a default list of detectors to run, which
  // may change over time.
  //
  // If you need precise control and predictability as to what detectors are
  // run you should specify specific InfoTypes listed in the reference,
  // otherwise a default list will be used, which may change over time.
  repeated InfoType info_types = 1;

  // Only returns findings equal to or above this threshold. The default is
  // POSSIBLE.
  //
  // In general, the highest likelihood setting yields the fewest findings in
  // results and the lowest chance of a false positive. For more information,
  // see [Match
  // likelihood](https://cloud.google.com/sensitive-data-protection/docs/likelihood).
  Likelihood min_likelihood = 2;

  // Minimum likelihood per infotype. For each infotype, a user can specify a
  // minimum likelihood. The system only returns a finding if its likelihood is
  // above this threshold. If this field is not set, the system uses the
  // InspectConfig min_likelihood.
  repeated InfoTypeLikelihood min_likelihood_per_info_type = 11;

  // Configuration to control the number of findings returned.
  // This is not used for data profiling.
  //
  // When redacting sensitive data from images, finding limits don't apply. They
  // can cause unexpected or inconsistent results, where only some data is
  // redacted. Don't include finding limits in
  // [RedactImage][google.privacy.dlp.v2.DlpService.RedactImage]
  // requests. Otherwise, Cloud DLP returns an error.
  //
  // When set within an
  // [InspectJobConfig][google.privacy.dlp.v2.InspectJobConfig], the specified
  // maximum values aren't hard limits. If an inspection job reaches these
  // limits, the job ends gradually, not abruptly. Therefore, the actual number
  // of findings that Cloud DLP returns can be multiple times higher than these
  // maximum values.
  FindingLimits limits = 3;

  // When true, a contextual quote from the data that triggered a finding is
  // included in the response; see
  // [Finding.quote][google.privacy.dlp.v2.Finding.quote]. This is not used for
  // data profiling.
  bool include_quote = 4;

  // When true, excludes type information of the findings.
  // This is not used for data profiling.
  bool exclude_info_types = 5;

  // CustomInfoTypes provided by the user. See
  // https://cloud.google.com/sensitive-data-protection/docs/creating-custom-infotypes
  // to learn more.
  repeated CustomInfoType custom_info_types = 6;

  // Deprecated and unused.
  repeated ContentOption content_options = 8;

  // Set of rules to apply to the findings for this InspectConfig.
  // Exclusion rules, contained in the set are executed in the end, other
  // rules are executed in the order they are specified for each info type.
  repeated InspectionRuleSet rule_set = 10;
}

// Container for bytes to inspect or redact.
message ByteContentItem {
  // The type of data being sent for inspection. To learn more, see
  // [Supported file
  // types](https://cloud.google.com/sensitive-data-protection/docs/supported-file-types).
  //
  // Only the first frame of each multiframe image is inspected. Metadata and
  // other frames aren't inspected.
  enum BytesType {
    // Unused
    BYTES_TYPE_UNSPECIFIED = 0;

    // Any image type.
    IMAGE = 6;

    // jpeg
    IMAGE_JPEG = 1;

    // bmp
    IMAGE_BMP = 2;

    // png
    IMAGE_PNG = 3;

    // svg
    IMAGE_SVG = 4;

    // plain text
    TEXT_UTF8 = 5;

    // docx, docm, dotx, dotm
    WORD_DOCUMENT = 7;

    // pdf
    PDF = 8;

    // pptx, pptm, potx, potm, pot
    POWERPOINT_DOCUMENT = 9;

    // xlsx, xlsm, xltx, xltm
    EXCEL_DOCUMENT = 10;

    // avro
    AVRO = 11;

    // csv
    CSV = 12;

    // tsv
    TSV = 13;

    // Audio file types. Only used for profiling.
    AUDIO = 15;

    // Video file types. Only used for profiling.
    VIDEO = 16;

    // Executable file types. Only used for profiling.
    EXECUTABLE = 17;

    // AI model file types. Only used for profiling.
    AI_MODEL = 18;
  }

  // The type of data stored in the bytes string. Default will be TEXT_UTF8.
  BytesType type = 1;

  // Content data to inspect or redact.
  bytes data = 2;
}

// Type of content to inspect.
message ContentItem {
  // Data of the item either in the byte array or UTF-8 string form, or table.
  oneof data_item {
    // String data to inspect or redact.
    string value = 3;

    // Structured content for inspection. See
    // https://cloud.google.com/sensitive-data-protection/docs/inspecting-text#inspecting_a_table
    // to learn more.
    Table table = 4;

    // Content data to inspect or redact. Replaces `type` and `data`.
    ByteContentItem byte_item = 5;
  }
}

// Structured content to inspect. Up to 50,000 `Value`s per request allowed. See
// https://cloud.google.com/sensitive-data-protection/docs/inspecting-structured-text#inspecting_a_table
// to learn more.
message Table {
  // Values of the row.
  message Row {
    // Individual cells.
    repeated Value values = 1;
  }

  // Headers of the table.
  repeated FieldId headers = 1;

  // Rows of the table.
  repeated Row rows = 2;
}

// All the findings for a single scanned item.
message InspectResult {
  // List of findings for an item.
  repeated Finding findings = 1;

  // If true, then this item might have more findings than were returned,
  // and the findings returned are an arbitrary subset of all findings.
  // The findings list might be truncated because the input items were too
  // large, or because the server reached the maximum amount of resources
  // allowed for a single API call. For best results, divide the input into
  // smaller batches.
  bool findings_truncated = 2;
}

// Represents a piece of potentially sensitive content.
message Finding {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/Finding"
    pattern: "projects/{project}/locations/{location}/findings/{finding}"
  };

  // Resource name in format
  // projects/{project}/locations/{location}/findings/{finding} Populated only
  // when viewing persisted findings.
  string name = 14;

  // The content that was found. Even if the content is not textual, it
  // may be converted to a textual representation here.
  // Provided if `include_quote` is true and the finding is
  // less than or equal to 4096 bytes long. If the finding exceeds 4096 bytes
  // in length, the quote may be omitted.
  string quote = 1;

  // The type of content that might have been found.
  // Provided if `excluded_types` is false.
  InfoType info_type = 2;

  // Confidence of how likely it is that the `info_type` is correct.
  Likelihood likelihood = 3;

  // Where the content was found.
  Location location = 4;

  // Timestamp when finding was detected.
  google.protobuf.Timestamp create_time = 6;

  // Contains data parsed from quotes. Only populated if include_quote was set
  // to true and a supported infoType was requested. Currently supported
  // infoTypes: DATE, DATE_OF_BIRTH and TIME.
  QuoteInfo quote_info = 7;

  // The job that stored the finding.
  string resource_name = 8
      [(google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }];

  // Job trigger name, if applicable, for this finding.
  string trigger_name = 9 [
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];

  // The labels associated with this `Finding`.
  //
  // Label keys must be between 1 and 63 characters long and must conform
  // to the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
  //
  // Label values must be between 0 and 63 characters long and must conform
  // to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
  //
  // No more than 10 labels can be associated with a given finding.
  //
  // Examples:
  //
  // * `"environment" : "production"`
  // * `"pipeline" : "etl"`
  map<string, string> labels = 10;

  // Time the job started that produced this finding.
  google.protobuf.Timestamp job_create_time = 11;

  // The job that stored the finding.
  string job_name = 13
      [(google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }];

  // The unique finding id.
  string finding_id = 15;
}

// Specifies the location of the finding.
message Location {
  // Zero-based byte offsets delimiting the finding.
  // These are relative to the finding's containing element.
  // Note that when the content is not textual, this references
  // the UTF-8 encoded textual representation of the content.
  // Omitted if content is an image.
  Range byte_range = 1;

  // Unicode character offsets delimiting the finding.
  // These are relative to the finding's containing element.
  // Provided when the content is text.
  Range codepoint_range = 2;

  // List of nested objects pointing to the precise location of the finding
  // within the file or record.
  repeated ContentLocation content_locations = 7;

  // Information about the container where this finding occurred, if available.
  Container container = 8;
}

// Precise location of the finding within a document, record, image, or metadata
// container.
message ContentLocation {
  // Name of the container where the finding is located.
  // The top level name is the source file name or table name. Names of some
  // common storage containers are formatted as follows:
  //
  // * BigQuery tables:  `{project_id}:{dataset_id}.{table_id}`
  // * Cloud Storage files: `gs://{bucket}/{path}`
  // * Datastore namespace: {namespace}
  //
  // Nested names could be absent if the embedded object has no string
  // identifier (for example, an image contained within a document).
  string container_name = 1;

  // Type of the container within the file with location of the finding.
  oneof location {
    // Location within a row or record of a database table.
    RecordLocation record_location = 2;

    // Location within an image's pixels.
    ImageLocation image_location = 3;

    // Location data for document files.
    DocumentLocation document_location = 5;

    // Location within the metadata for inspected content.
    MetadataLocation metadata_location = 8;
  }

  // Finding container modification timestamp, if applicable. For Cloud Storage,
  // this field contains the last file modification timestamp. For a BigQuery
  // table, this field contains the last_modified_time property. For Datastore,
  // this field isn't populated.
  google.protobuf.Timestamp container_timestamp = 6;

  // Finding container version, if available
  // ("generation" for Cloud Storage).
  string container_version = 7;
}

// Metadata Location
message MetadataLocation {
  // Type of metadata containing the finding.
  MetadataType type = 1;

  // Label of the piece of metadata containing the finding, for example -
  // latitude, author, caption.
  oneof label {
    // Storage metadata.
    StorageMetadataLabel storage_label = 3;
  }
}

// Storage metadata label to indicate which metadata entry contains findings.
message StorageMetadataLabel {
  // Label name.
  string key = 1;
}

// Location of a finding within a document.
message DocumentLocation {
  // Offset of the line, from the beginning of the file, where the finding
  // is located.
  int64 file_offset = 1;
}

// Location of a finding within a row or record.
message RecordLocation {
  // Key of the finding.
  RecordKey record_key = 1;

  // Field id of the field containing the finding.
  FieldId field_id = 2;

  // Location within a `ContentItem.Table`.
  TableLocation table_location = 3;
}

// Location of a finding within a table.
message TableLocation {
  // The zero-based index of the row where the finding is located. Only
  // populated for resources that have a natural ordering, not BigQuery. In
  // BigQuery, to identify the row a finding came from, populate
  // BigQueryOptions.identifying_fields with your primary key column names and
  // when you store the findings the value of those columns will be stored
  // inside of Finding.
  int64 row_index = 1;
}

// Represents a container that may contain DLP findings.
// Examples of a container include a file, table, or database record.
message Container {
  // Container type, for example BigQuery or Cloud Storage.
  string type = 1;

  // Project where the finding was found.
  // Can be different from the project that owns the finding.
  string project_id = 2;

  // A string representation of the full container name.
  // Examples:
  // - BigQuery: 'Project:DataSetId.TableId'
  // - Cloud Storage: 'gs://Bucket/folders/filename.txt'
  string full_path = 3;

  // The root of the container.
  // Examples:
  //
  // - For BigQuery table `project_id:dataset_id.table_id`, the root is
  //  `dataset_id`
  // - For Cloud Storage file `gs://bucket/folder/filename.txt`, the root
  //  is `gs://bucket`
  string root_path = 4;

  // The rest of the path after the root.
  // Examples:
  //
  // - For BigQuery table `project_id:dataset_id.table_id`, the relative path is
  //  `table_id`
  // - For Cloud Storage file `gs://bucket/folder/filename.txt`, the relative
  //  path is `folder/filename.txt`
  string relative_path = 5;

  // Findings container modification timestamp, if applicable. For Cloud
  // Storage, this field contains the last file modification timestamp. For a
  // BigQuery table, this field contains the last_modified_time property. For
  // Datastore, this field isn't populated.
  google.protobuf.Timestamp update_time = 6;

  // Findings container version, if available
  // ("generation" for Cloud Storage).
  string version = 7;
}

// Generic half-open interval [start, end)
message Range {
  // Index of the first character of the range (inclusive).
  int64 start = 1;

  // Index of the last character of the range (exclusive).
  int64 end = 2;
}

// Location of the finding within an image.
message ImageLocation {
  // Bounding boxes locating the pixels within the image containing the finding.
  repeated BoundingBox bounding_boxes = 1;
}

// Bounding box encompassing detected text within an image.
message BoundingBox {
  // Top coordinate of the bounding box. (0,0) is upper left.
  int32 top = 1;

  // Left coordinate of the bounding box. (0,0) is upper left.
  int32 left = 2;

  // Width of the bounding box in pixels.
  int32 width = 3;

  // Height of the bounding box in pixels.
  int32 height = 4;
}

// Request to search for potentially sensitive info in an image and redact it
// by covering it with a colored rectangle.
message RedactImageRequest {
  // Configuration for determining how redaction of images should occur.
  message ImageRedactionConfig {
    // Type of information to redact from images.
    oneof target {
      // Only one per info_type should be provided per request. If not
      // specified, and redact_all_text is false, the DLP API will redact all
      // text that it matches against all info_types that are found, but not
      // specified in another ImageRedactionConfig.
      InfoType info_type = 1;

      // If true, all text found in the image, regardless whether it matches an
      // info_type, is redacted. Only one should be provided.
      bool redact_all_text = 2;
    }

    // The color to use when redacting content from an image. If not specified,
    // the default is black.
    Color redaction_color = 3;
  }

  // Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [(google.api.resource_reference) = {
    child_type: "dlp.googleapis.com/DlpContent"
  }];

  // Deprecated. This field has no effect.
  string location_id = 8;

  // Configuration for the inspector.
  InspectConfig inspect_config = 2;

  // The configuration for specifying what content to redact from images.
  repeated ImageRedactionConfig image_redaction_configs = 5;

  // Whether the response should include findings along with the redacted
  // image.
  bool include_findings = 6;

  // The content must be PNG, JPEG, SVG or BMP.
  ByteContentItem byte_item = 7;
}

// Represents a color in the RGB color space.
message Color {
  // The amount of red in the color as a value in the interval [0, 1].
  float red = 1;

  // The amount of green in the color as a value in the interval [0, 1].
  float green = 2;

  // The amount of blue in the color as a value in the interval [0, 1].
  float blue = 3;
}

// Results of redacting an image.
message RedactImageResponse {
  // The redacted image. The type will be the same as the original image.
  bytes redacted_image = 1;

  // If an image was being inspected and the InspectConfig's include_quote was
  // set to true, then this field will include all text, if any, that was found
  // in the image.
  string extracted_text = 2;

  // The findings. Populated when include_findings in the request is true.
  InspectResult inspect_result = 3;
}

// Request to de-identify a ContentItem.
message DeidentifyContentRequest {
  // Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [(google.api.resource_reference) = {
    child_type: "dlp.googleapis.com/DlpContent"
  }];

  // Configuration for the de-identification of the content item.
  // Items specified here will override the template referenced by the
  // deidentify_template_name argument.
  DeidentifyConfig deidentify_config = 2;

  // Configuration for the inspector.
  // Items specified here will override the template referenced by the
  // inspect_template_name argument.
  InspectConfig inspect_config = 3;

  // The item to de-identify. Will be treated as text.
  //
  // This value must be of type
  // [Table][google.privacy.dlp.v2.Table] if your
  // [deidentify_config][google.privacy.dlp.v2.DeidentifyContentRequest.deidentify_config]
  // is a
  // [RecordTransformations][google.privacy.dlp.v2.RecordTransformations]
  // object.
  ContentItem item = 4;

  // Template to use. Any configuration directly specified in
  // inspect_config will override those set in the template. Singular fields
  // that are set in this request will replace their corresponding fields in the
  // template. Repeated fields are appended. Singular sub-messages and groups
  // are recursively merged.
  string inspect_template_name = 5;

  // Template to use. Any configuration directly specified in
  // deidentify_config will override those set in the template. Singular fields
  // that are set in this request will replace their corresponding fields in the
  // template. Repeated fields are appended. Singular sub-messages and groups
  // are recursively merged.
  string deidentify_template_name = 6;

  // Deprecated. This field has no effect.
  string location_id = 7;
}

// Results of de-identifying a ContentItem.
message DeidentifyContentResponse {
  // The de-identified item.
  ContentItem item = 1;

  // An overview of the changes that were made on the `item`.
  TransformationOverview overview = 2;
}

// Request to re-identify an item.
message ReidentifyContentRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DlpContent"
    }
  ];

  // Configuration for the re-identification of the content item.
  // This field shares the same proto message type that is used for
  // de-identification, however its usage here is for the reversal of the
  // previous de-identification. Re-identification is performed by examining
  // the transformations used to de-identify the items and executing the
  // reverse. This requires that only reversible transformations
  // be provided here. The reversible transformations are:
  //
  //  - `CryptoDeterministicConfig`
  //  - `CryptoReplaceFfxFpeConfig`
  DeidentifyConfig reidentify_config = 2;

  // Configuration for the inspector.
  InspectConfig inspect_config = 3;

  // The item to re-identify. Will be treated as text.
  ContentItem item = 4;

  // Template to use. Any configuration directly specified in
  // `inspect_config` will override those set in the template. Singular fields
  // that are set in this request will replace their corresponding fields in the
  // template. Repeated fields are appended. Singular sub-messages and groups
  // are recursively merged.
  string inspect_template_name = 5;

  // Template to use. References an instance of `DeidentifyTemplate`.
  // Any configuration directly specified in `reidentify_config` or
  // `inspect_config` will override those set in the template. The
  // `DeidentifyTemplate` used must include only reversible transformations.
  // Singular fields that are set in this request will replace their
  // corresponding fields in the template. Repeated fields are appended.
  // Singular sub-messages and groups are recursively merged.
  string reidentify_template_name = 6;

  // Deprecated. This field has no effect.
  string location_id = 7;
}

// Results of re-identifying an item.
message ReidentifyContentResponse {
  // The re-identified item.
  ContentItem item = 1;

  // An overview of the changes that were made to the `item`.
  TransformationOverview overview = 2;
}

// Request to search for potentially sensitive info in a ContentItem.
message InspectContentRequest {
  // Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [(google.api.resource_reference) = {
    child_type: "dlp.googleapis.com/DlpContent"
  }];

  // Configuration for the inspector. What specified here will override
  // the template referenced by the inspect_template_name argument.
  InspectConfig inspect_config = 2;

  // The item to inspect.
  ContentItem item = 3;

  // Template to use. Any configuration directly specified in
  // inspect_config will override those set in the template. Singular fields
  // that are set in this request will replace their corresponding fields in the
  // template. Repeated fields are appended. Singular sub-messages and groups
  // are recursively merged.
  string inspect_template_name = 4;

  // Deprecated. This field has no effect.
  string location_id = 5;
}

// Results of inspecting an item.
message InspectContentResponse {
  // The findings.
  InspectResult result = 1;
}

// Cloud repository for storing output.
message OutputStorageConfig {
  // Predefined schemas for storing findings.
  // Only for use with external storage.
  enum OutputSchema {
    // Unused.
    OUTPUT_SCHEMA_UNSPECIFIED = 0;

    // Basic schema including only `info_type`, `quote`, `certainty`, and
    // `timestamp`.
    BASIC_COLUMNS = 1;

    // Schema tailored to findings from scanning Cloud Storage.
    GCS_COLUMNS = 2;

    // Schema tailored to findings from scanning Google Datastore.
    DATASTORE_COLUMNS = 3;

    // Schema tailored to findings from scanning Google BigQuery.
    BIG_QUERY_COLUMNS = 4;

    // Schema containing all columns.
    ALL_COLUMNS = 5;
  }

  // Output storage types.
  oneof type {
    // Store findings in an existing table or a new table in an existing
    // dataset. If table_id is not set a new one will be generated
    // for you with the following format:
    // dlp_googleapis_yyyy_mm_dd_[dlp_job_id]. Pacific time zone will be used
    // for generating the date details.
    //
    // For Inspect, each column in an existing output table must have the same
    // name, type, and mode of a field in the `Finding` object.
    //
    // For Risk, an existing output table should be the output of a previous
    // Risk analysis job run on the same source table, with the same privacy
    // metric and quasi-identifiers. Risk jobs that analyze the same table but
    // compute a different privacy metric, or use different sets of
    // quasi-identifiers, cannot store their results in the same table.
    BigQueryTable table = 1;
  }

  // Schema used for writing the findings for Inspect jobs. This field is only
  // used for Inspect and must be unspecified for Risk jobs. Columns are derived
  // from the `Finding` object. If appending to an existing table, any columns
  // from the predefined schema that are missing will be added. No columns in
  // the existing table will be deleted.
  //
  // If unspecified, then all available columns will be used for a new table or
  // an (existing) table with no schema, and no changes will be made to an
  // existing table that has a schema.
  // Only for use with external storage.
  OutputSchema output_schema = 3;
}

// Statistics regarding a specific InfoType.
message InfoTypeStats {
  // The type of finding this stat is for.
  InfoType info_type = 1;

  // Number of findings for this infoType.
  int64 count = 2;
}

// The results of an inspect DataSource job.
message InspectDataSourceDetails {
  // Snapshot of the inspection configuration.
  message RequestedOptions {
    // If run with an InspectTemplate, a snapshot of its state at the time of
    // this run.
    InspectTemplate snapshot_inspect_template = 1;

    // Inspect config.
    InspectJobConfig job_config = 3;
  }

  // All result fields mentioned below are updated while the job is processing.
  message Result {
    // Total size in bytes that were processed.
    int64 processed_bytes = 1;

    // Estimate of the number of bytes to process.
    int64 total_estimated_bytes = 2;

    // Statistics of how many instances of each info type were found during
    // inspect job.
    repeated InfoTypeStats info_type_stats = 3;

    // Number of rows scanned after sampling and time filtering (applicable for
    // row based stores such as BigQuery).
    int64 num_rows_processed = 5;

    // Statistics related to the processing of hybrid inspect.
    HybridInspectStatistics hybrid_stats = 7;
  }

  // The configuration used for this job.
  RequestedOptions requested_options = 2;

  // A summary of the outcome of this inspection job.
  Result result = 3;
}

// The schema of data to be saved to the BigQuery table when the
// `DataProfileAction` is enabled.
message DataProfileBigQueryRowSchema {
  // Data profile type.
  oneof data_profile {
    // Table data profile column
    TableDataProfile table_profile = 1;

    // Column data profile column
    ColumnDataProfile column_profile = 2;

    // File store data profile column.
    FileStoreDataProfile file_store_profile = 3;
  }
}

// Statistics related to processing hybrid inspect requests.
message HybridInspectStatistics {
  // The number of hybrid inspection requests processed within this job.
  int64 processed_count = 1;

  // The number of hybrid inspection requests aborted because the job ran
  // out of quota or was ended before they could be processed.
  int64 aborted_count = 2;

  // The number of hybrid requests currently being processed. Only populated
  // when called via method `getDlpJob`.
  // A burst of traffic may cause hybrid inspect requests to be enqueued.
  // Processing will take place as quickly as possible, but resource limitations
  // may impact how long a request is enqueued for.
  int64 pending_count = 3;
}

// The results of an [Action][google.privacy.dlp.v2.Action].
message ActionDetails {
  // Summary of what occurred in the actions.
  oneof details {
    // Outcome of a de-identification action.
    DeidentifyDataSourceDetails deidentify_details = 1;
  }
}

// Summary of what was modified during a transformation.
message DeidentifyDataSourceStats {
  // Total size in bytes that were transformed in some way.
  int64 transformed_bytes = 1;

  // Number of successfully applied transformations.
  int64 transformation_count = 2;

  // Number of errors encountered while trying to apply transformations.
  int64 transformation_error_count = 3;
}

// The results of a [Deidentify][google.privacy.dlp.v2.Action.Deidentify] action
// from an inspect job.
message DeidentifyDataSourceDetails {
  // De-identification options.
  message RequestedDeidentifyOptions {
    // Snapshot of the state of the `DeidentifyTemplate` from the
    // [Deidentify][google.privacy.dlp.v2.Action.Deidentify] action at the time
    // this job was run.
    DeidentifyTemplate snapshot_deidentify_template = 1;

    // Snapshot of the state of the structured `DeidentifyTemplate` from the
    // `Deidentify` action at the time this job was run.
    DeidentifyTemplate snapshot_structured_deidentify_template = 2;

    // Snapshot of the state of the image transformation `DeidentifyTemplate`
    // from the `Deidentify` action at the time this job was run.
    DeidentifyTemplate snapshot_image_redact_template = 3;
  }

  // De-identification config used for the request.
  RequestedDeidentifyOptions requested_options = 1;

  // Stats about the de-identification operation.
  DeidentifyDataSourceStats deidentify_stats = 2;
}

// InfoType description.
message InfoTypeDescription {
  // Internal name of the infoType.
  string name = 1;

  // Human readable form of the infoType name.
  string display_name = 2;

  // Which parts of the API supports this InfoType.
  repeated InfoTypeSupportedBy supported_by = 3;

  // Description of the infotype. Translated when language is provided in the
  // request.
  string description = 4;

  // A sample that is a true positive for this infoType.
  string example = 8;

  // A list of available versions for the infotype.
  repeated VersionDescription versions = 9;

  // The category of the infoType.
  repeated InfoTypeCategory categories = 10;

  // The default sensitivity of the infoType.
  SensitivityScore sensitivity_score = 11;

  // If this field is set, this infoType is a general infoType and these
  // specific infoTypes are contained within it.
  // General infoTypes are infoTypes that encompass multiple specific infoTypes.
  // For example, the "GEOGRAPHIC_DATA" general infoType would have set for this
  // field "LOCATION", "LOCATION_COORDINATES", and "STREET_ADDRESS".
  repeated string specific_info_types = 12;
}

// Classification of infoTypes to organize them according to geographic
// location, industry, and data type.
message InfoTypeCategory {
  // Enum of the current locations.
  // We might add more locations in the future.
  enum LocationCategory {
    // Unused location
    LOCATION_UNSPECIFIED = 0;

    // The infoType is not issued by or tied to a specific region, but is used
    // almost everywhere.
    GLOBAL = 1;

    // The infoType is typically used in Argentina.
    ARGENTINA = 2;

    // The infoType is typically used in Armenia.
    ARMENIA = 51;

    // The infoType is typically used in Australia.
    AUSTRALIA = 3;

    // The infoType is typically used in Azerbaijan.
    AZERBAIJAN = 48;

    // The infoType is typically used in Belarus.
    BELARUS = 50;

    // The infoType is typically used in Belgium.
    BELGIUM = 4;

    // The infoType is typically used in Brazil.
    BRAZIL = 5;

    // The infoType is typically used in Canada.
    CANADA = 6;

    // The infoType is typically used in Chile.
    CHILE = 7;

    // The infoType is typically used in China.
    CHINA = 8;

    // The infoType is typically used in Colombia.
    COLOMBIA = 9;

    // The infoType is typically used in Croatia.
    CROATIA = 42;

    // The infoType is typically used in Czechia.
    CZECHIA = 52;

    // The infoType is typically used in Denmark.
    DENMARK = 10;

    // The infoType is typically used in France.
    FRANCE = 11;

    // The infoType is typically used in Finland.
    FINLAND = 12;

    // The infoType is typically used in Germany.
    GERMANY = 13;

    // The infoType is typically used in Hong Kong.
    HONG_KONG = 14;

    // The infoType is typically used in India.
    INDIA = 15;

    // The infoType is typically used in Indonesia.
    INDONESIA = 16;

    // The infoType is typically used in Ireland.
    IRELAND = 17;

    // The infoType is typically used in Israel.
    ISRAEL = 18;

    // The infoType is typically used in Italy.
    ITALY = 19;

    // The infoType is typically used in Japan.
    JAPAN = 20;

    // The infoType is typically used in Kazakhstan.
    KAZAKHSTAN = 47;

    // The infoType is typically used in Korea.
    KOREA = 21;

    // The infoType is typically used in Mexico.
    MEXICO = 22;

    // The infoType is typically used in the Netherlands.
    THE_NETHERLANDS = 23;

    // The infoType is typically used in New Zealand.
    NEW_ZEALAND = 41;

    // The infoType is typically used in Norway.
    NORWAY = 24;

    // The infoType is typically used in Paraguay.
    PARAGUAY = 25;

    // The infoType is typically used in Peru.
    PERU = 26;

    // The infoType is typically used in Poland.
    POLAND = 27;

    // The infoType is typically used in Portugal.
    PORTUGAL = 28;

    // The infoType is typically used in Russia.
    RUSSIA = 44;

    // The infoType is typically used in Singapore.
    SINGAPORE = 29;

    // The infoType is typically used in South Africa.
    SOUTH_AFRICA = 30;

    // The infoType is typically used in Spain.
    SPAIN = 31;

    // The infoType is typically used in Sweden.
    SWEDEN = 32;

    // The infoType is typically used in Switzerland.
    SWITZERLAND = 43;

    // The infoType is typically used in Taiwan.
    TAIWAN = 33;

    // The infoType is typically used in Thailand.
    THAILAND = 34;

    // The infoType is typically used in Turkey.
    TURKEY = 35;

    // The infoType is typically used in Ukraine.
    UKRAINE = 45;

    // The infoType is typically used in the United Kingdom.
    UNITED_KINGDOM = 36;

    // The infoType is typically used in the United States.
    UNITED_STATES = 37;

    // The infoType is typically used in Uruguay.
    URUGUAY = 38;

    // The infoType is typically used in Uzbekistan.
    UZBEKISTAN = 46;

    // The infoType is typically used in Venezuela.
    VENEZUELA = 39;

    // The infoType is typically used in Google internally.
    INTERNAL = 40;
  }

  // Enum of the current industries in the category.
  // We might add more industries in the future.
  enum IndustryCategory {
    // Unused industry
    INDUSTRY_UNSPECIFIED = 0;

    // The infoType is typically used in the finance industry.
    FINANCE = 1;

    // The infoType is typically used in the health industry.
    HEALTH = 2;

    // The infoType is typically used in the telecommunications industry.
    TELECOMMUNICATIONS = 3;
  }

  // Enum of the current types in the category.
  // We might add more types in the future.
  enum TypeCategory {
    // Unused type
    TYPE_UNSPECIFIED = 0;

    // Personally identifiable information, for example, a
    // name or phone number
    PII = 1;

    // Personally identifiable information that is especially sensitive, for
    // example, a passport number.
    SPII = 2;

    // Attributes that can partially identify someone, especially in
    // combination with other attributes, like age, height, and gender.
    DEMOGRAPHIC = 3;

    // Confidential or secret information, for example, a password.
    CREDENTIAL = 4;

    // An identification document issued by a government.
    GOVERNMENT_ID = 5;

    // A document, for example, a resume or source code.
    DOCUMENT = 6;

    // Information that is not sensitive on its own, but provides details about
    // the circumstances surrounding an entity or an event.
    CONTEXTUAL_INFORMATION = 7;

    // Category for `CustomInfoType` types.
    CUSTOM = 8;
  }

  // Categories of infotypes.
  oneof category {
    // The region or country that issued the ID or document represented by the
    // infoType.
    LocationCategory location_category = 1;

    // The group of relevant businesses where this infoType is commonly used
    IndustryCategory industry_category = 2;

    // The class of identifiers where this infoType belongs
    TypeCategory type_category = 3;
  }
}

// Details about each available version for an infotype.
message VersionDescription {
  // Name of the version
  string version = 1;

  // Description of the version.
  string description = 2;
}

// Request for the list of infoTypes.
message ListInfoTypesRequest {
  // The parent resource name.
  //
  // The format of this value is as follows:
  //
  //     `locations/{location_id}`
  string parent = 4;

  // BCP-47 language code for localized infoType friendly
  // names. If omitted, or if localized strings are not available,
  // en-US strings will be returned.
  string language_code = 1;

  // filter to only return infoTypes supported by certain parts of the
  // API. Defaults to supported_by=INSPECT.
  string filter = 2;

  // Deprecated. This field has no effect.
  string location_id = 3;
}

// Response to the ListInfoTypes request.
message ListInfoTypesResponse {
  // Set of sensitive infoTypes.
  repeated InfoTypeDescription info_types = 1;
}

// Configuration for a risk analysis job. See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-risk-analysis
// to learn more.
message RiskAnalysisJobConfig {
  // Privacy metric to compute.
  PrivacyMetric privacy_metric = 1;

  // Input dataset to compute metrics over.
  BigQueryTable source_table = 2;

  // Actions to execute at the completion of the job. Are executed in the order
  // provided.
  repeated Action actions = 3;
}

// A column with a semantic tag attached.
message QuasiId {
  // Required. Identifies the column.
  FieldId field = 1 [(google.api.field_behavior) = REQUIRED];

  // Semantic tag that identifies what a column contains, to determine which
  // statistical model to use to estimate the reidentifiability of each
  // value. [required]
  oneof tag {
    // A column can be tagged with a InfoType to use the relevant public
    // dataset as a statistical model of population, if available. We
    // currently support US ZIP codes, region codes, ages and genders.
    // To programmatically obtain the list of supported InfoTypes, use
    // ListInfoTypes with the supported_by=RISK_ANALYSIS filter.
    InfoType info_type = 2;

    // A column can be tagged with a custom tag. In this case, the user must
    // indicate an auxiliary table that contains statistical information on
    // the possible values of this column (below).
    string custom_tag = 3;

    // If no semantic tag is indicated, we infer the statistical model from
    // the distribution of values in the input data
    google.protobuf.Empty inferred = 4;
  }
}

// An auxiliary table containing statistical information on the relative
// frequency of different quasi-identifiers values. It has one or several
// quasi-identifiers columns, and one column that indicates the relative
// frequency of each quasi-identifier tuple.
// If a tuple is present in the data but not in the auxiliary table, the
// corresponding relative frequency is assumed to be zero (and thus, the
// tuple is highly reidentifiable).
message StatisticalTable {
  // A quasi-identifier column has a custom_tag, used to know which column
  // in the data corresponds to which column in the statistical model.
  message QuasiIdentifierField {
    // Identifies the column.
    FieldId field = 1;

    // A column can be tagged with a custom tag. In this case, the user must
    // indicate an auxiliary table that contains statistical information on
    // the possible values of this column (below).
    string custom_tag = 2;
  }

  // Required. Auxiliary table location.
  BigQueryTable table = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Quasi-identifier columns.
  repeated QuasiIdentifierField quasi_ids = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The relative frequency column must contain a floating-point
  // number between 0 and 1 (inclusive). Null values are assumed to be zero.
  FieldId relative_frequency = 2 [(google.api.field_behavior) = REQUIRED];
}

// Privacy metric to compute for reidentification risk analysis.
message PrivacyMetric {
  // Compute numerical stats over an individual column, including
  // min, max, and quantiles.
  message NumericalStatsConfig {
    // Field to compute numerical stats on. Supported types are
    // integer, float, date, datetime, timestamp, time.
    FieldId field = 1;
  }

  // Compute numerical stats over an individual column, including
  // number of distinct values and value count distribution.
  message CategoricalStatsConfig {
    // Field to compute categorical stats on. All column types are
    // supported except for arrays and structs. However, it may be more
    // informative to use NumericalStats when the field type is supported,
    // depending on the data.
    FieldId field = 1;
  }

  // k-anonymity metric, used for analysis of reidentification risk.
  message KAnonymityConfig {
    // Set of fields to compute k-anonymity over. When multiple fields are
    // specified, they are considered a single composite key. Structs and
    // repeated data types are not supported; however, nested fields are
    // supported so long as they are not structs themselves or nested within
    // a repeated field.
    repeated FieldId quasi_ids = 1;

    // Message indicating that multiple rows might be associated to a
    // single individual. If the same entity_id is associated to multiple
    // quasi-identifier tuples over distinct rows, we consider the entire
    // collection of tuples as the composite quasi-identifier. This collection
    // is a multiset: the order in which the different tuples appear in the
    // dataset is ignored, but their frequency is taken into account.
    //
    // Important note: a maximum of 1000 rows can be associated to a single
    // entity ID. If more rows are associated with the same entity ID, some
    // might be ignored.
    EntityId entity_id = 2;
  }

  // l-diversity metric, used for analysis of reidentification risk.
  message LDiversityConfig {
    // Set of quasi-identifiers indicating how equivalence classes are
    // defined for the l-diversity computation. When multiple fields are
    // specified, they are considered a single composite key.
    repeated FieldId quasi_ids = 1;

    // Sensitive field for computing the l-value.
    FieldId sensitive_attribute = 2;
  }

  // Reidentifiability metric. This corresponds to a risk model similar to what
  // is called "journalist risk" in the literature, except the attack dataset is
  // statistically modeled instead of being perfectly known. This can be done
  // using publicly available data (like the US Census), or using a custom
  // statistical model (indicated as one or several BigQuery tables), or by
  // extrapolating from the distribution of values in the input dataset.
  message KMapEstimationConfig {
    // A column with a semantic tag attached.
    message TaggedField {
      // Required. Identifies the column.
      FieldId field = 1 [(google.api.field_behavior) = REQUIRED];

      // Semantic tag that identifies what a column contains, to determine which
      // statistical model to use to estimate the reidentifiability of each
      // value. [required]
      oneof tag {
        // A column can be tagged with a InfoType to use the relevant public
        // dataset as a statistical model of population, if available. We
        // currently support US ZIP codes, region codes, ages and genders.
        // To programmatically obtain the list of supported InfoTypes, use
        // ListInfoTypes with the supported_by=RISK_ANALYSIS filter.
        InfoType info_type = 2;

        // A column can be tagged with a custom tag. In this case, the user must
        // indicate an auxiliary table that contains statistical information on
        // the possible values of this column (below).
        string custom_tag = 3;

        // If no semantic tag is indicated, we infer the statistical model from
        // the distribution of values in the input data
        google.protobuf.Empty inferred = 4;
      }
    }

    // An auxiliary table contains statistical information on the relative
    // frequency of different quasi-identifiers values. It has one or several
    // quasi-identifiers columns, and one column that indicates the relative
    // frequency of each quasi-identifier tuple.
    // If a tuple is present in the data but not in the auxiliary table, the
    // corresponding relative frequency is assumed to be zero (and thus, the
    // tuple is highly reidentifiable).
    message AuxiliaryTable {
      // A quasi-identifier column has a custom_tag, used to know which column
      // in the data corresponds to which column in the statistical model.
      message QuasiIdField {
        // Identifies the column.
        FieldId field = 1;

        // A auxiliary field.
        string custom_tag = 2;
      }

      // Required. Auxiliary table location.
      BigQueryTable table = 3 [(google.api.field_behavior) = REQUIRED];

      // Required. Quasi-identifier columns.
      repeated QuasiIdField quasi_ids = 1
          [(google.api.field_behavior) = REQUIRED];

      // Required. The relative frequency column must contain a floating-point
      // number between 0 and 1 (inclusive). Null values are assumed to be zero.
      FieldId relative_frequency = 2 [(google.api.field_behavior) = REQUIRED];
    }

    // Required. Fields considered to be quasi-identifiers. No two columns can
    // have the same tag.
    repeated TaggedField quasi_ids = 1 [(google.api.field_behavior) = REQUIRED];

    // ISO 3166-1 alpha-2 region code to use in the statistical modeling.
    // Set if no column is tagged with a region-specific InfoType (like
    // US_ZIP_5) or a region code.
    string region_code = 2;

    // Several auxiliary tables can be used in the analysis. Each custom_tag
    // used to tag a quasi-identifiers column must appear in exactly one column
    // of one auxiliary table.
    repeated AuxiliaryTable auxiliary_tables = 3;
  }

  // δ-presence metric, used to estimate how likely it is for an attacker to
  // figure out that one given individual appears in a de-identified dataset.
  // Similarly to the k-map metric, we cannot compute δ-presence exactly without
  // knowing the attack dataset, so we use a statistical model instead.
  message DeltaPresenceEstimationConfig {
    // Required. Fields considered to be quasi-identifiers. No two fields can
    // have the same tag.
    repeated QuasiId quasi_ids = 1 [(google.api.field_behavior) = REQUIRED];

    // ISO 3166-1 alpha-2 region code to use in the statistical modeling.
    // Set if no column is tagged with a region-specific InfoType (like
    // US_ZIP_5) or a region code.
    string region_code = 2;

    // Several auxiliary tables can be used in the analysis. Each custom_tag
    // used to tag a quasi-identifiers field must appear in exactly one
    // field of one auxiliary table.
    repeated StatisticalTable auxiliary_tables = 3;
  }

  // Types of analysis.
  oneof type {
    // Numerical stats
    NumericalStatsConfig numerical_stats_config = 1;

    // Categorical stats
    CategoricalStatsConfig categorical_stats_config = 2;

    // K-anonymity
    KAnonymityConfig k_anonymity_config = 3;

    // l-diversity
    LDiversityConfig l_diversity_config = 4;

    // k-map
    KMapEstimationConfig k_map_estimation_config = 5;

    // delta-presence
    DeltaPresenceEstimationConfig delta_presence_estimation_config = 6;
  }
}

// Result of a risk analysis operation request.
message AnalyzeDataSourceRiskDetails {
  // Result of the numerical stats computation.
  message NumericalStatsResult {
    // Minimum value appearing in the column.
    Value min_value = 1;

    // Maximum value appearing in the column.
    Value max_value = 2;

    // List of 99 values that partition the set of field values into 100 equal
    // sized buckets.
    repeated Value quantile_values = 4;
  }

  // Result of the categorical stats computation.
  message CategoricalStatsResult {
    // Histogram of value frequencies in the column.
    message CategoricalStatsHistogramBucket {
      // Lower bound on the value frequency of the values in this bucket.
      int64 value_frequency_lower_bound = 1;

      // Upper bound on the value frequency of the values in this bucket.
      int64 value_frequency_upper_bound = 2;

      // Total number of values in this bucket.
      int64 bucket_size = 3;

      // Sample of value frequencies in this bucket. The total number of
      // values returned per bucket is capped at 20.
      repeated ValueFrequency bucket_values = 4;

      // Total number of distinct values in this bucket.
      int64 bucket_value_count = 5;
    }

    // Histogram of value frequencies in the column.
    repeated CategoricalStatsHistogramBucket value_frequency_histogram_buckets =
        5;
  }

  // Result of the k-anonymity computation.
  message KAnonymityResult {
    // The set of columns' values that share the same ldiversity value
    message KAnonymityEquivalenceClass {
      // Set of values defining the equivalence class. One value per
      // quasi-identifier column in the original KAnonymity metric message.
      // The order is always the same as the original request.
      repeated Value quasi_ids_values = 1;

      // Size of the equivalence class, for example number of rows with the
      // above set of values.
      int64 equivalence_class_size = 2;
    }

    // Histogram of k-anonymity equivalence classes.
    message KAnonymityHistogramBucket {
      // Lower bound on the size of the equivalence classes in this bucket.
      int64 equivalence_class_size_lower_bound = 1;

      // Upper bound on the size of the equivalence classes in this bucket.
      int64 equivalence_class_size_upper_bound = 2;

      // Total number of equivalence classes in this bucket.
      int64 bucket_size = 3;

      // Sample of equivalence classes in this bucket. The total number of
      // classes returned per bucket is capped at 20.
      repeated KAnonymityEquivalenceClass bucket_values = 4;

      // Total number of distinct equivalence classes in this bucket.
      int64 bucket_value_count = 5;
    }

    // Histogram of k-anonymity equivalence classes.
    repeated KAnonymityHistogramBucket equivalence_class_histogram_buckets = 5;
  }

  // Result of the l-diversity computation.
  message LDiversityResult {
    // The set of columns' values that share the same ldiversity value.
    message LDiversityEquivalenceClass {
      // Quasi-identifier values defining the k-anonymity equivalence
      // class. The order is always the same as the original request.
      repeated Value quasi_ids_values = 1;

      // Size of the k-anonymity equivalence class.
      int64 equivalence_class_size = 2;

      // Number of distinct sensitive values in this equivalence class.
      int64 num_distinct_sensitive_values = 3;

      // Estimated frequencies of top sensitive values.
      repeated ValueFrequency top_sensitive_values = 4;
    }

    // Histogram of l-diversity equivalence class sensitive value frequencies.
    message LDiversityHistogramBucket {
      // Lower bound on the sensitive value frequencies of the equivalence
      // classes in this bucket.
      int64 sensitive_value_frequency_lower_bound = 1;

      // Upper bound on the sensitive value frequencies of the equivalence
      // classes in this bucket.
      int64 sensitive_value_frequency_upper_bound = 2;

      // Total number of equivalence classes in this bucket.
      int64 bucket_size = 3;

      // Sample of equivalence classes in this bucket. The total number of
      // classes returned per bucket is capped at 20.
      repeated LDiversityEquivalenceClass bucket_values = 4;

      // Total number of distinct equivalence classes in this bucket.
      int64 bucket_value_count = 5;
    }

    // Histogram of l-diversity equivalence class sensitive value frequencies.
    repeated LDiversityHistogramBucket
        sensitive_value_frequency_histogram_buckets = 5;
  }

  // Result of the reidentifiability analysis. Note that these results are an
  // estimation, not exact values.
  message KMapEstimationResult {
    // A tuple of values for the quasi-identifier columns.
    message KMapEstimationQuasiIdValues {
      // The quasi-identifier values.
      repeated Value quasi_ids_values = 1;

      // The estimated anonymity for these quasi-identifier values.
      int64 estimated_anonymity = 2;
    }

    // A KMapEstimationHistogramBucket message with the following values:
    //   min_anonymity: 3
    //   max_anonymity: 5
    //   frequency: 42
    // means that there are 42 records whose quasi-identifier values correspond
    // to 3, 4 or 5 people in the overlying population. An important particular
    // case is when min_anonymity = max_anonymity = 1: the frequency field then
    // corresponds to the number of uniquely identifiable records.
    message KMapEstimationHistogramBucket {
      // Always positive.
      int64 min_anonymity = 1;

      // Always greater than or equal to min_anonymity.
      int64 max_anonymity = 2;

      // Number of records within these anonymity bounds.
      int64 bucket_size = 5;

      // Sample of quasi-identifier tuple values in this bucket. The total
      // number of classes returned per bucket is capped at 20.
      repeated KMapEstimationQuasiIdValues bucket_values = 6;

      // Total number of distinct quasi-identifier tuple values in this bucket.
      int64 bucket_value_count = 7;
    }

    // The intervals [min_anonymity, max_anonymity] do not overlap. If a value
    // doesn't correspond to any such interval, the associated frequency is
    // zero. For example, the following records:
    //   {min_anonymity: 1, max_anonymity: 1, frequency: 17}
    //   {min_anonymity: 2, max_anonymity: 3, frequency: 42}
    //   {min_anonymity: 5, max_anonymity: 10, frequency: 99}
    // mean that there are no record with an estimated anonymity of 4, 5, or
    // larger than 10.
    repeated KMapEstimationHistogramBucket k_map_estimation_histogram = 1;
  }

  // Result of the δ-presence computation. Note that these results are an
  // estimation, not exact values.
  message DeltaPresenceEstimationResult {
    // A tuple of values for the quasi-identifier columns.
    message DeltaPresenceEstimationQuasiIdValues {
      // The quasi-identifier values.
      repeated Value quasi_ids_values = 1;

      // The estimated probability that a given individual sharing these
      // quasi-identifier values is in the dataset. This value, typically
      // called δ, is the ratio between the number of records in the dataset
      // with these quasi-identifier values, and the total number of individuals
      // (inside *and* outside the dataset) with these quasi-identifier values.
      // For example, if there are 15 individuals in the dataset who share the
      // same quasi-identifier values, and an estimated 100 people in the entire
      // population with these values, then δ is 0.15.
      double estimated_probability = 2;
    }

    // A DeltaPresenceEstimationHistogramBucket message with the following
    // values:
    //   min_probability: 0.1
    //   max_probability: 0.2
    //   frequency: 42
    // means that there are 42 records for which δ is in [0.1, 0.2). An
    // important particular case is when min_probability = max_probability = 1:
    // then, every individual who shares this quasi-identifier combination is in
    // the dataset.
    message DeltaPresenceEstimationHistogramBucket {
      // Between 0 and 1.
      double min_probability = 1;

      // Always greater than or equal to min_probability.
      double max_probability = 2;

      // Number of records within these probability bounds.
      int64 bucket_size = 5;

      // Sample of quasi-identifier tuple values in this bucket. The total
      // number of classes returned per bucket is capped at 20.
      repeated DeltaPresenceEstimationQuasiIdValues bucket_values = 6;

      // Total number of distinct quasi-identifier tuple values in this bucket.
      int64 bucket_value_count = 7;
    }

    // The intervals [min_probability, max_probability) do not overlap. If a
    // value doesn't correspond to any such interval, the associated frequency
    // is zero. For example, the following records:
    //   {min_probability: 0, max_probability: 0.1, frequency: 17}
    //   {min_probability: 0.2, max_probability: 0.3, frequency: 42}
    //   {min_probability: 0.3, max_probability: 0.4, frequency: 99}
    // mean that there are no record with an estimated probability in [0.1, 0.2)
    // nor larger or equal to 0.4.
    repeated DeltaPresenceEstimationHistogramBucket
        delta_presence_estimation_histogram = 1;
  }

  // Risk analysis options.
  message RequestedRiskAnalysisOptions {
    // The job config for the risk job.
    RiskAnalysisJobConfig job_config = 1;
  }

  // Privacy metric to compute.
  PrivacyMetric requested_privacy_metric = 1;

  // Input dataset to compute metrics over.
  BigQueryTable requested_source_table = 2;

  // Values associated with this metric.
  oneof result {
    // Numerical stats result
    NumericalStatsResult numerical_stats_result = 3;

    // Categorical stats result
    CategoricalStatsResult categorical_stats_result = 4;

    // K-anonymity result
    KAnonymityResult k_anonymity_result = 5;

    // L-divesity result
    LDiversityResult l_diversity_result = 6;

    // K-map result
    KMapEstimationResult k_map_estimation_result = 7;

    // Delta-presence result
    DeltaPresenceEstimationResult delta_presence_estimation_result = 9;
  }

  // The configuration used for this job.
  RequestedRiskAnalysisOptions requested_options = 10;
}

// A value of a field, including its frequency.
message ValueFrequency {
  // A value contained in the field in question.
  Value value = 1;

  // How many times the value is contained in the field.
  int64 count = 2;
}

// Set of primitive values supported by the system.
// Note that for the purposes of inspection or transformation, the number
// of bytes considered to comprise a 'Value' is based on its representation
// as a UTF-8 encoded string. For example, if 'integer_value' is set to
// 123456789, the number of bytes would be counted as 9, even though an
// int64 only holds up to 8 bytes of data.
message Value {
  // Value types
  oneof type {
    // integer
    int64 integer_value = 1;

    // float
    double float_value = 2;

    // string
    string string_value = 3;

    // boolean
    bool boolean_value = 4;

    // timestamp
    google.protobuf.Timestamp timestamp_value = 5;

    // time of day
    google.type.TimeOfDay time_value = 6;

    // date
    google.type.Date date_value = 7;

    // day of week
    google.type.DayOfWeek day_of_week_value = 8;
  }
}

// Message for infoType-dependent details parsed from quote.
message QuoteInfo {
  // Object representation of the quote.
  oneof parsed_quote {
    // The date time indicated by the quote.
    DateTime date_time = 2;
  }
}

// Message for a date time object.
// e.g. 2018-01-01, 5th August.
message DateTime {
  // Time zone of the date time object.
  message TimeZone {
    // Set only if the offset can be determined. Positive for time ahead of UTC.
    // E.g. For "UTC-9", this value is -540.
    int32 offset_minutes = 1;
  }

  // One or more of the following must be set.
  // Must be a valid date or time value.
  google.type.Date date = 1;

  // Day of week
  google.type.DayOfWeek day_of_week = 2;

  // Time of day
  google.type.TimeOfDay time = 3;

  // Time zone
  TimeZone time_zone = 4;
}

// The configuration that controls how the data will change.
message DeidentifyConfig {
  // Type of transformation
  oneof transformation {
    // Treat the dataset as free-form text and apply the same free text
    // transformation everywhere.
    InfoTypeTransformations info_type_transformations = 1;

    // Treat the dataset as structured. Transformations can be applied to
    // specific locations within structured datasets, such as transforming
    // a column within a table.
    RecordTransformations record_transformations = 2;

    // Treat the dataset as an image and redact.
    ImageTransformations image_transformations = 4;
  }

  // Mode for handling transformation errors. If left unspecified, the default
  // mode is `TransformationErrorHandling.ThrowError`.
  TransformationErrorHandling transformation_error_handling = 3;
}

// A type of transformation that is applied over images.
message ImageTransformations {
  // Configuration for determining how redaction of images should occur.
  message ImageTransformation {
    // Apply transformation to the selected info_types.
    message SelectedInfoTypes {
      // Required. InfoTypes to apply the transformation to. Required. Provided
      // InfoType must be unique within the ImageTransformations message.
      repeated InfoType info_types = 5 [(google.api.field_behavior) = REQUIRED];
    }

    // Apply transformation to all findings.
    message AllInfoTypes {}

    // Apply to all text.
    message AllText {}

    // Part of the image to transform.
    oneof target {
      // Apply transformation to the selected info_types.
      SelectedInfoTypes selected_info_types = 4;

      // Apply transformation to all findings not specified in other
      // ImageTransformation's selected_info_types. Only one instance is allowed
      // within the ImageTransformations message.
      AllInfoTypes all_info_types = 5;

      // Apply transformation to all text that doesn't match an infoType. Only
      // one instance is allowed within the ImageTransformations message.
      AllText all_text = 6;
    }

    // The color to use when redacting content from an image. If not
    // specified, the default is black.
    Color redaction_color = 3;
  }

  // List of transforms to make.
  repeated ImageTransformation transforms = 2;
}

// How to handle transformation errors during de-identification. A
// transformation error occurs when the requested transformation is incompatible
// with the data. For example, trying to de-identify an IP address using a
// `DateShift` transformation would result in a transformation error, since date
// info cannot be extracted from an IP address.
// Information about any incompatible transformations, and how they were
// handled, is returned in the response as part of the
// `TransformationOverviews`.
message TransformationErrorHandling {
  // Throw an error and fail the request when a transformation error occurs.
  message ThrowError {}

  // Skips the data without modifying it if the requested transformation would
  // cause an error. For example, if a `DateShift` transformation were applied
  // an an IP address, this mode would leave the IP address unchanged in the
  // response.
  message LeaveUntransformed {}

  // How transformation errors should be handled.
  oneof mode {
    // Throw an error
    ThrowError throw_error = 1;

    // Ignore errors
    LeaveUntransformed leave_untransformed = 2;
  }
}

// A rule for transforming a value.
message PrimitiveTransformation {
  // Type of transformation.
  oneof transformation {
    // Replace with a specified value.
    ReplaceValueConfig replace_config = 1;

    // Redact
    RedactConfig redact_config = 2;

    // Mask
    CharacterMaskConfig character_mask_config = 3;

    // Ffx-Fpe. Strongly discouraged, consider using CryptoDeterministicConfig
    // instead. Fpe is computationally expensive incurring latency costs.
    CryptoReplaceFfxFpeConfig crypto_replace_ffx_fpe_config = 4;

    // Fixed size bucketing
    FixedSizeBucketingConfig fixed_size_bucketing_config = 5;

    // Bucketing
    BucketingConfig bucketing_config = 6;

    // Replace with infotype
    ReplaceWithInfoTypeConfig replace_with_info_type_config = 7;

    // Time extraction
    TimePartConfig time_part_config = 8;

    // Crypto
    CryptoHashConfig crypto_hash_config = 9;

    // Date Shift
    DateShiftConfig date_shift_config = 11;

    // Deterministic Crypto
    CryptoDeterministicConfig crypto_deterministic_config = 12;

    // Replace with a value randomly drawn (with replacement) from a dictionary.
    ReplaceDictionaryConfig replace_dictionary_config = 13;
  }
}

// For use with `Date`, `Timestamp`, and `TimeOfDay`, extract or preserve a
// portion of the value.
message TimePartConfig {
  // Components that make up time.
  enum TimePart {
    // Unused
    TIME_PART_UNSPECIFIED = 0;

    // [0-9999]
    YEAR = 1;

    // [1-12]
    MONTH = 2;

    // [1-31]
    DAY_OF_MONTH = 3;

    // [1-7]
    DAY_OF_WEEK = 4;

    // [1-53]
    WEEK_OF_YEAR = 5;

    // [0-23]
    HOUR_OF_DAY = 6;
  }

  // The part of the time to keep.
  TimePart part_to_extract = 1;
}

// Pseudonymization method that generates surrogates via cryptographic hashing.
// Uses SHA-256.
// The key size must be either 32 or 64 bytes.
// Outputs a base64 encoded representation of the hashed output
// (for example, L7k0BHmF1ha5U3NfGykjro4xWi1MPVQPjhMAZbSV9mM=).
// Currently, only string and integer values can be hashed.
// See https://cloud.google.com/sensitive-data-protection/docs/pseudonymization
// to learn more.
message CryptoHashConfig {
  // The key used by the hash function.
  CryptoKey crypto_key = 1;
}

// Pseudonymization method that generates deterministic encryption for the given
// input. Outputs a base64 encoded representation of the encrypted output.
// Uses AES-SIV based on the RFC https://tools.ietf.org/html/rfc5297.
message CryptoDeterministicConfig {
  // The key used by the encryption function. For deterministic encryption
  // using AES-SIV, the provided key is internally expanded to 64 bytes prior to
  // use.
  CryptoKey crypto_key = 1;

  // The custom info type to annotate the surrogate with.
  // This annotation will be applied to the surrogate by prefixing it with
  // the name of the custom info type followed by the number of
  // characters comprising the surrogate. The following scheme defines the
  // format: {info type name}({surrogate character count}):{surrogate}
  //
  // For example, if the name of custom info type is 'MY_TOKEN_INFO_TYPE' and
  // the surrogate is 'abc', the full replacement value
  // will be: 'MY_TOKEN_INFO_TYPE(3):abc'
  //
  // This annotation identifies the surrogate when inspecting content using the
  // custom info type 'Surrogate'. This facilitates reversal of the
  // surrogate when it occurs in free text.
  //
  // Note: For record transformations where the entire cell in a table is being
  // transformed, surrogates are not mandatory. Surrogates are used to denote
  // the location of the token and are necessary for re-identification in free
  // form text.
  //
  // In order for inspection to work properly, the name of this info type must
  // not occur naturally anywhere in your data; otherwise, inspection may either
  //
  // - reverse a surrogate that does not correspond to an actual identifier
  // - be unable to parse the surrogate and result in an error
  //
  // Therefore, choose your custom info type name carefully after considering
  // what your data looks like. One way to select a name that has a high chance
  // of yielding reliable detection is to include one or more unicode characters
  // that are highly improbable to exist in your data.
  // For example, assuming your data is entered from a regular ASCII keyboard,
  // the symbol with the hex code point 29DD might be used like so:
  // ⧝MY_TOKEN_TYPE.
  InfoType surrogate_info_type = 2;

  // A context may be used for higher security and maintaining
  // referential integrity such that the same identifier in two different
  // contexts will be given a distinct surrogate. The context is appended to
  // plaintext value being encrypted. On decryption the provided context is
  // validated against the value used during encryption. If a context was
  // provided during encryption, same context must be provided during decryption
  // as well.
  //
  // If the context is not set, plaintext would be used as is for encryption.
  // If the context is set but:
  //
  // 1. there is no record present when transforming a given value or
  // 2. the field is not present when transforming a given value,
  //
  // plaintext would be used as is for encryption.
  //
  // Note that case (1) is expected when an `InfoTypeTransformation` is
  // applied to both structured and unstructured `ContentItem`s.
  FieldId context = 3;
}

// Replace each input value with a given `Value`.
message ReplaceValueConfig {
  // Value to replace it with.
  Value new_value = 1;
}

// Replace each input value with a value randomly selected from the dictionary.
message ReplaceDictionaryConfig {
  // Type of dictionary.
  oneof type {
    // A list of words to select from for random replacement. The
    // [limits](https://cloud.google.com/sensitive-data-protection/limits) page
    // contains details about the size limits of dictionaries.
    CustomInfoType.Dictionary.WordList word_list = 1;
  }
}

// Replace each matching finding with the name of the info_type.
message ReplaceWithInfoTypeConfig {}

// Redact a given value. For example, if used with an `InfoTypeTransformation`
// transforming PHONE_NUMBER, and input 'My phone number is 206-555-0123', the
// output would be 'My phone number is '.
message RedactConfig {}

// Characters to skip when doing deidentification of a value. These will be left
// alone and skipped.
message CharsToIgnore {
  // Convenience enum for indicating common characters to not transform.
  enum CommonCharsToIgnore {
    // Unused.
    COMMON_CHARS_TO_IGNORE_UNSPECIFIED = 0;

    // 0-9
    NUMERIC = 1;

    // A-Z
    ALPHA_UPPER_CASE = 2;

    // a-z
    ALPHA_LOWER_CASE = 3;

    // US Punctuation, one of !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    PUNCTUATION = 4;

    // Whitespace character, one of [ \t\n\x0B\f\r]
    WHITESPACE = 5;
  }

  // Type of characters to skip.
  oneof characters {
    // Characters to not transform when masking.
    string characters_to_skip = 1;

    // Common characters to not transform when masking. Useful to avoid removing
    // punctuation.
    CommonCharsToIgnore common_characters_to_ignore = 2;
  }
}

// Partially mask a string by replacing a given number of characters with a
// fixed character. Masking can start from the beginning or end of the string.
// This can be used on data of any type (numbers, longs, and so on) and when
// de-identifying structured data we'll attempt to preserve the original data's
// type. (This allows you to take a long like 123 and modify it to a string like
// **3.
message CharacterMaskConfig {
  // Character to use to mask the sensitive values&mdash;for example, `*` for an
  // alphabetic string such as a name, or `0` for a numeric string such as ZIP
  // code or credit card number. This string must have a length of 1. If not
  // supplied, this value defaults to `*` for strings, and `0` for digits.
  string masking_character = 1;

  // Number of characters to mask. If not set, all matching chars will be
  // masked. Skipped characters do not count towards this tally.
  //
  // If `number_to_mask` is negative, this denotes inverse masking. Cloud DLP
  // masks all but a number of characters.
  // For example, suppose you have the following values:
  //
  // - `masking_character` is `*`
  // - `number_to_mask` is `-4`
  // - `reverse_order` is `false`
  // - `CharsToIgnore` includes `-`
  // - Input string is `1234-5678-9012-3456`
  //
  // The resulting de-identified string is
  // `****-****-****-3456`. Cloud DLP masks all but the last four characters.
  // If `reverse_order` is `true`, all but the first four characters are masked
  // as `1234-****-****-****`.
  int32 number_to_mask = 2;

  // Mask characters in reverse order. For example, if `masking_character` is
  // `0`, `number_to_mask` is `14`, and `reverse_order` is `false`, then the
  // input string `1234-5678-9012-3456` is masked as `00000000000000-3456`.
  // If `masking_character` is `*`, `number_to_mask` is `3`, and `reverse_order`
  // is `true`, then the string `12345` is masked as `12***`.
  bool reverse_order = 3;

  // When masking a string, items in this list will be skipped when replacing
  // characters. For example, if the input string is `555-555-5555` and you
  // instruct Cloud DLP to skip `-` and mask 5 characters with `*`, Cloud DLP
  // returns `***-**5-5555`.
  repeated CharsToIgnore characters_to_ignore = 4;
}

// Buckets values based on fixed size ranges. The
// Bucketing transformation can provide all of this functionality,
// but requires more configuration. This message is provided as a convenience to
// the user for simple bucketing strategies.
//
// The transformed value will be a hyphenated string of
// {lower_bound}-{upper_bound}. For example, if lower_bound = 10 and upper_bound
// = 20, all values that are within this bucket will be replaced with "10-20".
//
// This can be used on data of type: double, long.
//
// If the bound Value type differs from the type of data
// being transformed, we will first attempt converting the type of the data to
// be transformed to match the type of the bound before comparing.
//
// See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-bucketing to
// learn more.
message FixedSizeBucketingConfig {
  // Required. Lower bound value of buckets. All values less than `lower_bound`
  // are grouped together into a single bucket; for example if `lower_bound` =
  // 10, then all values less than 10 are replaced with the value "-10".
  Value lower_bound = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Upper bound value of buckets. All values greater than upper_bound
  // are grouped together into a single bucket; for example if `upper_bound` =
  // 89, then all values greater than 89 are replaced with the value "89+".
  Value upper_bound = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Size of each bucket (except for minimum and maximum buckets). So
  // if `lower_bound` = 10, `upper_bound` = 89, and `bucket_size` = 10, then the
  // following buckets would be used: -10, 10-20, 20-30, 30-40, 40-50, 50-60,
  // 60-70, 70-80, 80-89, 89+. Precision up to 2 decimals works.
  double bucket_size = 3 [(google.api.field_behavior) = REQUIRED];
}

// Generalization function that buckets values based on ranges. The ranges and
// replacement values are dynamically provided by the user for custom behavior,
// such as 1-30 -> LOW, 31-65 -> MEDIUM, 66-100 -> HIGH.
//
// This can be used on data of type: number, long, string, timestamp.
//
// If the bound `Value` type differs from the type of data being transformed, we
// will first attempt converting the type of the data to be transformed to match
// the type of the bound before comparing.
// See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-bucketing to
// learn more.
message BucketingConfig {
  // Bucket is represented as a range, along with replacement values.
  message Bucket {
    // Lower bound of the range, inclusive. Type should be the same as max if
    // used.
    Value min = 1;

    // Upper bound of the range, exclusive; type must match min.
    Value max = 2;

    // Required. Replacement value for this bucket.
    Value replacement_value = 3 [(google.api.field_behavior) = REQUIRED];
  }

  // Set of buckets. Ranges must be non-overlapping.
  repeated Bucket buckets = 1;
}

// Replaces an identifier with a surrogate using Format Preserving Encryption
// (FPE) with the FFX mode of operation; however when used in the
// `ReidentifyContent` API method, it serves the opposite function by reversing
// the surrogate back into the original identifier. The identifier must be
// encoded as ASCII. For a given crypto key and context, the same identifier
// will be replaced with the same surrogate. Identifiers must be at least two
// characters long. In the case that the identifier is the empty string, it will
// be skipped. See
// https://cloud.google.com/sensitive-data-protection/docs/pseudonymization to
// learn more.
//
// Note: We recommend using  CryptoDeterministicConfig for all use cases which
// do not require preserving the input alphabet space and size, plus warrant
// referential integrity. FPE incurs significant latency costs.
message CryptoReplaceFfxFpeConfig {
  // These are commonly used subsets of the alphabet that the FFX mode
  // natively supports. In the algorithm, the alphabet is selected using
  // the "radix". Therefore each corresponds to a particular radix.
  enum FfxCommonNativeAlphabet {
    // Unused.
    FFX_COMMON_NATIVE_ALPHABET_UNSPECIFIED = 0;

    // `[0-9]` (radix of 10)
    NUMERIC = 1;

    // `[0-9A-F]` (radix of 16)
    HEXADECIMAL = 2;

    // `[0-9A-Z]` (radix of 36)
    UPPER_CASE_ALPHA_NUMERIC = 3;

    // `[0-9A-Za-z]` (radix of 62)
    ALPHA_NUMERIC = 4;
  }

  // Required. The key used by the encryption algorithm.
  CryptoKey crypto_key = 1 [(google.api.field_behavior) = REQUIRED];

  // The 'tweak', a context may be used for higher security since the same
  // identifier in two different contexts won't be given the same surrogate. If
  // the context is not set, a default tweak will be used.
  //
  // If the context is set but:
  //
  // 1. there is no record present when transforming a given value or
  // 1. the field is not present when transforming a given value,
  //
  // a default tweak will be used.
  //
  // Note that case (1) is expected when an `InfoTypeTransformation` is
  // applied to both structured and unstructured `ContentItem`s.
  // Currently, the referenced field may be of value type integer or string.
  //
  // The tweak is constructed as a sequence of bytes in big endian byte order
  // such that:
  //
  // - a 64 bit integer is encoded followed by a single byte of value 1
  // - a string is encoded in UTF-8 format followed by a single byte of value 2
  FieldId context = 2;

  // Choose an alphabet which the data being transformed will be made up of.
  oneof alphabet {
    // Common alphabets.
    FfxCommonNativeAlphabet common_alphabet = 4;

    // This is supported by mapping these to the alphanumeric characters
    // that the FFX mode natively supports. This happens before/after
    // encryption/decryption.
    // Each character listed must appear only once.
    // Number of characters must be in the range [2, 95].
    // This must be encoded as ASCII.
    // The order of characters does not matter.
    // The full list of allowed characters is:
    // ``0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~`!@#$%^&*()_-+={[}]|\:;"'<,>.?/``
    string custom_alphabet = 5;

    // The native way to select the alphabet. Must be in the range [2, 95].
    int32 radix = 6;
  }

  // The custom infoType to annotate the surrogate with.
  // This annotation will be applied to the surrogate by prefixing it with
  // the name of the custom infoType followed by the number of
  // characters comprising the surrogate. The following scheme defines the
  // format: info_type_name(surrogate_character_count):surrogate
  //
  // For example, if the name of custom infoType is 'MY_TOKEN_INFO_TYPE' and
  // the surrogate is 'abc', the full replacement value
  // will be: 'MY_TOKEN_INFO_TYPE(3):abc'
  //
  // This annotation identifies the surrogate when inspecting content using the
  // custom infoType
  // [`SurrogateType`](https://cloud.google.com/sensitive-data-protection/docs/reference/rest/v2/InspectConfig#surrogatetype).
  // This facilitates reversal of the surrogate when it occurs in free text.
  //
  // In order for inspection to work properly, the name of this infoType must
  // not occur naturally anywhere in your data; otherwise, inspection may
  // find a surrogate that does not correspond to an actual identifier.
  // Therefore, choose your custom infoType name carefully after considering
  // what your data looks like. One way to select a name that has a high chance
  // of yielding reliable detection is to include one or more unicode characters
  // that are highly improbable to exist in your data.
  // For example, assuming your data is entered from a regular ASCII keyboard,
  // the symbol with the hex code point 29DD might be used like so:
  // ⧝MY_TOKEN_TYPE
  InfoType surrogate_info_type = 8;
}

// This is a data encryption key (DEK) (as opposed to
// a key encryption key (KEK) stored by Cloud Key Management Service
// (Cloud KMS).
// When using Cloud KMS to wrap or unwrap a DEK, be sure to set an appropriate
// IAM policy on the KEK to ensure an attacker cannot
// unwrap the DEK.
message CryptoKey {
  // Sources of crypto keys.
  oneof source {
    // Transient crypto key
    TransientCryptoKey transient = 1;

    // Unwrapped crypto key
    UnwrappedCryptoKey unwrapped = 2;

    // Key wrapped using Cloud KMS
    KmsWrappedCryptoKey kms_wrapped = 3;
  }
}

// Use this to have a random data crypto key generated.
// It will be discarded after the request finishes.
message TransientCryptoKey {
  // Required. Name of the key.
  // This is an arbitrary string used to differentiate different keys.
  // A unique key is generated per name: two separate `TransientCryptoKey`
  // protos share the same generated key if their names are the same.
  // When the data crypto key is generated, this name is not used in any way
  // (repeating the api call will result in a different key being generated).
  string name = 1 [(google.api.field_behavior) = REQUIRED];
}

// Using raw keys is prone to security risks due to accidentally
// leaking the key. Choose another type of key if possible.
message UnwrappedCryptoKey {
  // Required. A 128/192/256 bit key.
  bytes key = 1 [(google.api.field_behavior) = REQUIRED];
}

// Include to use an existing data crypto key wrapped by KMS.
// The wrapped key must be a 128-, 192-, or 256-bit key.
// Authorization requires the following IAM permissions when sending a request
// to perform a crypto transformation using a KMS-wrapped crypto key:
// dlp.kms.encrypt
//
// For more information, see [Creating a wrapped key]
// (https://cloud.google.com/sensitive-data-protection/docs/create-wrapped-key).
//
// Note: When you use Cloud KMS for cryptographic operations,
// [charges apply](https://cloud.google.com/kms/pricing).
message KmsWrappedCryptoKey {
  // Required. The wrapped data crypto key.
  bytes wrapped_key = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The resource name of the KMS CryptoKey to use for unwrapping.
  string crypto_key_name = 2 [(google.api.field_behavior) = REQUIRED];
}

// Shifts dates by random number of days, with option to be consistent for the
// same context. See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-date-shifting
// to learn more.
message DateShiftConfig {
  // Required. Range of shift in days. Actual shift will be selected at random
  // within this range (inclusive ends). Negative means shift to earlier in
  // time. Must not be more than 365250 days (1000 years) each direction.
  //
  // For example, 3 means shift date to at most 3 days into the future.
  int32 upper_bound_days = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. For example, -5 means shift date to at most 5 days back in the
  // past.
  int32 lower_bound_days = 2 [(google.api.field_behavior) = REQUIRED];

  // Points to the field that contains the context, for example, an entity id.
  // If set, must also set cryptoKey. If set, shift will be consistent for the
  // given context.
  FieldId context = 3;

  // Method for calculating shift that takes context into consideration. If
  // set, must also set context. Can only be applied to table items.
  oneof method {
    // Causes the shift to be computed based on this key and the context. This
    // results in the same shift for the same context and crypto_key. If
    // set, must also set context. Can only be applied to table items.
    CryptoKey crypto_key = 4;
  }
}

// A type of transformation that will scan unstructured text and
// apply various `PrimitiveTransformation`s to each finding, where the
// transformation is applied to only values that were identified as a specific
// info_type.
message InfoTypeTransformations {
  // A transformation to apply to text that is identified as a specific
  // info_type.
  message InfoTypeTransformation {
    // InfoTypes to apply the transformation to. An empty list will cause
    // this transformation to apply to all findings that correspond to
    // infoTypes that were requested in `InspectConfig`.
    repeated InfoType info_types = 1;

    // Required. Primitive transformation to apply to the infoType.
    PrimitiveTransformation primitive_transformation = 2
        [(google.api.field_behavior) = REQUIRED];
  }

  // Required. Transformation for each infoType. Cannot specify more than one
  // for a given infoType.
  repeated InfoTypeTransformation transformations = 1
      [(google.api.field_behavior) = REQUIRED];
}

// The transformation to apply to the field.
message FieldTransformation {
  // Required. Input field(s) to apply the transformation to.
  // When you have columns that reference their position within a list,
  // omit the index from the FieldId. FieldId name matching ignores the index.
  // For example, instead of "contact.nums[0].type", use "contact.nums.type".
  repeated FieldId fields = 1 [(google.api.field_behavior) = REQUIRED];

  // Only apply the transformation if the condition evaluates to true for the
  // given `RecordCondition`. The conditions are allowed to reference fields
  // that are not used in the actual transformation.
  //
  // Example Use Cases:
  //
  // - Apply a different bucket transformation to an age column if the zip code
  // column for the same record is within a specific range.
  // - Redact a field if the date of birth field is greater than 85.
  RecordCondition condition = 3;

  // Transformation to apply. [required]
  oneof transformation {
    // Apply the transformation to the entire field.
    PrimitiveTransformation primitive_transformation = 4;

    // Treat the contents of the field as free text, and selectively
    // transform content that matches an `InfoType`.
    InfoTypeTransformations info_type_transformations = 5;
  }
}

// A type of transformation that is applied over structured data such as a
// table.
message RecordTransformations {
  // Transform the record by applying various field transformations.
  repeated FieldTransformation field_transformations = 1;

  // Configuration defining which records get suppressed entirely. Records that
  // match any suppression rule are omitted from the output.
  repeated RecordSuppression record_suppressions = 2;
}

// Configuration to suppress records whose suppression conditions evaluate to
// true.
message RecordSuppression {
  // A condition that when it evaluates to true will result in the record being
  // evaluated to be suppressed from the transformed content.
  RecordCondition condition = 1;
}

// A condition for determining whether a transformation should be applied to
// a field.
message RecordCondition {
  // The field type of `value` and `field` do not need to match to be
  // considered equal, but not all comparisons are possible.
  // EQUAL_TO and NOT_EQUAL_TO attempt to compare even with incompatible types,
  // but all other comparisons are invalid with incompatible types.
  // A `value` of type:
  //
  // - `string` can be compared against all other types
  // - `boolean` can only be compared against other booleans
  // - `integer` can be compared against doubles or a string if the string value
  // can be parsed as an integer.
  // - `double` can be compared against integers or a string if the string can
  // be parsed as a double.
  // - `Timestamp` can be compared against strings in RFC 3339 date string
  // format.
  // - `TimeOfDay` can be compared against timestamps and strings in the format
  // of 'HH:mm:ss'.
  //
  // If we fail to compare do to type mismatch, a warning will be given and
  // the condition will evaluate to false.
  message Condition {
    // Required. Field within the record this condition is evaluated against.
    FieldId field = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. Operator used to compare the field or infoType to the value.
    RelationalOperator operator = 3 [(google.api.field_behavior) = REQUIRED];

    // Value to compare against. [Mandatory, except for `EXISTS` tests.]
    Value value = 4;
  }

  // A collection of conditions.
  message Conditions {
    // A collection of conditions.
    repeated Condition conditions = 1;
  }

  // An expression, consisting of an operator and conditions.
  message Expressions {
    // Logical operators for conditional checks.
    enum LogicalOperator {
      // Unused
      LOGICAL_OPERATOR_UNSPECIFIED = 0;

      // Conditional AND
      AND = 1;
    }

    // The operator to apply to the result of conditions. Default and currently
    // only supported value is `AND`.
    LogicalOperator logical_operator = 1;

    // Expression types.
    oneof type {
      // Conditions to apply to the expression.
      Conditions conditions = 3;
    }
  }

  // An expression.
  Expressions expressions = 3;
}

// Overview of the modifications that occurred.
message TransformationOverview {
  // Total size in bytes that were transformed in some way.
  int64 transformed_bytes = 2;

  // Transformations applied to the dataset.
  repeated TransformationSummary transformation_summaries = 3;
}

// Summary of a single transformation.
// Only one of 'transformation', 'field_transformation', or 'record_suppress'
// will be set.
message TransformationSummary {
  // Possible outcomes of transformations.
  enum TransformationResultCode {
    // Unused
    TRANSFORMATION_RESULT_CODE_UNSPECIFIED = 0;

    // Transformation completed without an error.
    SUCCESS = 1;

    // Transformation had an error.
    ERROR = 2;
  }

  // A collection that informs the user the number of times a particular
  // `TransformationResultCode` and error details occurred.
  message SummaryResult {
    // Number of transformations counted by this result.
    int64 count = 1;

    // Outcome of the transformation.
    TransformationResultCode code = 2;

    // A place for warnings or errors to show up if a transformation didn't
    // work as expected.
    string details = 3;
  }

  // Set if the transformation was limited to a specific InfoType.
  InfoType info_type = 1;

  // Set if the transformation was limited to a specific FieldId.
  FieldId field = 2;

  // The specific transformation these stats apply to.
  PrimitiveTransformation transformation = 3;

  // The field transformation that was applied.
  // If multiple field transformations are requested for a single field,
  // this list will contain all of them; otherwise, only one is supplied.
  repeated FieldTransformation field_transformations = 5;

  // The specific suppression option these stats apply to.
  RecordSuppression record_suppress = 6;

  // Collection of all transformations that took place or had an error.
  repeated SummaryResult results = 4;

  // Total size in bytes that were transformed in some way.
  int64 transformed_bytes = 7;
}

// A flattened description of a `PrimitiveTransformation` or
// `RecordSuppression`.
message TransformationDescription {
  // The transformation type.
  TransformationType type = 1;

  // A description of the transformation. This is empty for a
  // RECORD_SUPPRESSION, or is the output of calling toString() on the
  // `PrimitiveTransformation` protocol buffer message for any other type of
  // transformation.
  string description = 2;

  // A human-readable string representation of the `RecordCondition`
  // corresponding to this transformation. Set if a `RecordCondition` was used
  // to determine whether or not to apply this transformation.
  //
  // Examples:
  //     * (age_field > 85)
  //     * (age_field <= 18)
  //     * (zip_field exists)
  //     * (zip_field == 01234) && (city_field != "Springville")
  //     * (zip_field == 01234) && (age_field <= 18) && (city_field exists)
  string condition = 3;

  // Set if the transformation was limited to a specific `InfoType`.
  InfoType info_type = 4;
}

// Details about a single transformation. This object contains a description of
// the transformation, information about whether the transformation was
// successfully applied, and the precise location where the transformation
// occurred. These details are stored in a user-specified BigQuery table.
message TransformationDetails {
  // The name of the job that completed the transformation.
  string resource_name = 1;

  // The top level name of the container where the transformation is located
  // (this will be the source file name or table name).
  string container_name = 2;

  // Description of transformation. This would only contain more than one
  // element if there were multiple matching transformations and which one to
  // apply was ambiguous. Not set for states that contain no transformation,
  // currently only state that contains no transformation is
  // TransformationResultStateType.METADATA_UNRETRIEVABLE.
  repeated TransformationDescription transformation = 3;

  // Status of the transformation, if transformation was not successful, this
  // will specify what caused it to fail, otherwise it will show that the
  // transformation was successful.
  TransformationResultStatus status_details = 4;

  // The number of bytes that were transformed. If transformation was
  // unsuccessful or did not take place because there was no content to
  // transform, this will be zero.
  int64 transformed_bytes = 5;

  // The precise location of the transformed content in the original container.
  TransformationLocation transformation_location = 6;
}

// Specifies the location of a transformation.
message TransformationLocation {
  // Location type.
  oneof location_type {
    // For infotype transformations, link to the corresponding findings ID so
    // that location information does not need to be duplicated. Each findings
    // ID correlates to an entry in the findings output table, this table only
    // gets created when users specify to save findings (add the save findings
    // action to the request).
    string finding_id = 1;

    // For record transformations, provide a field and container information.
    RecordTransformation record_transformation = 2;
  }

  // Information about the functionality of the container where this finding
  // occurred, if available.
  TransformationContainerType container_type = 3;
}

// The field in a record to transform.
message RecordTransformation {
  // For record transformations, provide a field.
  FieldId field_id = 1;

  // Findings container modification timestamp, if applicable.
  google.protobuf.Timestamp container_timestamp = 2;

  // Container version, if available ("generation" for Cloud Storage).
  string container_version = 3;
}

// The outcome of a transformation.
message TransformationResultStatus {
  // Transformation result status type, this will be either SUCCESS, or it will
  // be the reason for why the transformation was not completely successful.
  TransformationResultStatusType result_status_type = 1;

  // Detailed error codes and messages
  google.rpc.Status details = 2;
}

// Enum of possible outcomes of transformations. SUCCESS if transformation and
// storing of transformation was successful, otherwise, reason for not
// transforming.
enum TransformationResultStatusType {
  // Unused.
  STATE_TYPE_UNSPECIFIED = 0;

  // This will be set when a finding could not be transformed (i.e. outside user
  // set bucket range).
  INVALID_TRANSFORM = 1;

  // This will be set when a BigQuery transformation was successful but could
  // not be stored back in BigQuery because the transformed row exceeds
  // BigQuery's max row size.
  BIGQUERY_MAX_ROW_SIZE_EXCEEDED = 2;

  // This will be set when there is a finding in the custom metadata of a file,
  // but at the write time of the transformed file, this key / value pair is
  // unretrievable.
  METADATA_UNRETRIEVABLE = 3;

  // This will be set when the transformation and storing of it is successful.
  SUCCESS = 4;
}

// Describes functionality of a given container in its original format.
enum TransformationContainerType {
  // Unused.
  TRANSFORM_UNKNOWN_CONTAINER = 0;

  // Body of a file.
  TRANSFORM_BODY = 1;

  // Metadata for a file.
  TRANSFORM_METADATA = 2;

  // A table.
  TRANSFORM_TABLE = 3;
}

// An enum of rules that can be used to transform a value. Can be a
// record suppression, or one of the transformation rules specified under
// `PrimitiveTransformation`.
enum TransformationType {
  // Unused
  TRANSFORMATION_TYPE_UNSPECIFIED = 0;

  // Record suppression
  RECORD_SUPPRESSION = 1;

  // Replace value
  REPLACE_VALUE = 2;

  // Replace value using a dictionary.
  REPLACE_DICTIONARY = 15;

  // Redact
  REDACT = 3;

  // Character mask
  CHARACTER_MASK = 4;

  // FFX-FPE
  CRYPTO_REPLACE_FFX_FPE = 5;

  // Fixed size bucketing
  FIXED_SIZE_BUCKETING = 6;

  // Bucketing
  BUCKETING = 7;

  // Replace with info type
  REPLACE_WITH_INFO_TYPE = 8;

  // Time part
  TIME_PART = 9;

  // Crypto hash
  CRYPTO_HASH = 10;

  // Date shift
  DATE_SHIFT = 12;

  // Deterministic crypto
  CRYPTO_DETERMINISTIC_CONFIG = 13;

  // Redact image
  REDACT_IMAGE = 14;
}

// Config for storing transformation details.
message TransformationDetailsStorageConfig {
  // Location to store the transformation summary.
  oneof type {
    // The BigQuery table in which to store the output. This may be an existing
    // table or in a new table in an existing dataset.
    // If table_id is not set a new one will be generated for you with the
    // following format:
    // dlp_googleapis_transformation_details_yyyy_mm_dd_[dlp_job_id]. Pacific
    // time zone will be used for generating the date details.
    BigQueryTable table = 1;
  }
}

// Schedule for inspect job triggers.
message Schedule {
  // Type of schedule.
  oneof option {
    // With this option a job is started on a regular periodic basis. For
    // example: every day (86400 seconds).
    //
    // A scheduled start time will be skipped if the previous
    // execution has not ended when its scheduled time occurs.
    //
    // This value must be set to a time duration greater than or equal
    // to 1 day and can be no longer than 60 days.
    google.protobuf.Duration recurrence_period_duration = 1;
  }
}

// Job trigger option for hybrid jobs. Jobs must be manually created
// and finished.
message Manual {}

// The inspectTemplate contains a configuration (set of types of sensitive data
// to be detected) to be used anywhere you otherwise would normally specify
// InspectConfig. See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-templates to
// learn more.
message InspectTemplate {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/InspectTemplate"
    pattern: "organizations/{organization}/inspectTemplates/{inspect_template}"
    pattern: "projects/{project}/inspectTemplates/{inspect_template}"
    pattern: "organizations/{organization}/locations/{location}/inspectTemplates/{inspect_template}"
    pattern: "projects/{project}/locations/{location}/inspectTemplates/{inspect_template}"
  };

  // Output only. The template name.
  //
  // The template will have one of the following formats:
  // `projects/PROJECT_ID/inspectTemplates/TEMPLATE_ID` OR
  // `organizations/ORGANIZATION_ID/inspectTemplates/TEMPLATE_ID`;
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Display name (max 256 chars).
  string display_name = 2;

  // Short description (max 256 chars).
  string description = 3;

  // Output only. The creation timestamp of an inspectTemplate.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last update timestamp of an inspectTemplate.
  google.protobuf.Timestamp update_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The core content of the template. Configuration of the scanning process.
  InspectConfig inspect_config = 6;
}

// DeidentifyTemplates contains instructions on how to de-identify content.
// See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-templates to
// learn more.
message DeidentifyTemplate {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/DeidentifyTemplate"
    pattern: "organizations/{organization}/deidentifyTemplates/{deidentify_template}"
    pattern: "projects/{project}/deidentifyTemplates/{deidentify_template}"
    pattern: "organizations/{organization}/locations/{location}/deidentifyTemplates/{deidentify_template}"
    pattern: "projects/{project}/locations/{location}/deidentifyTemplates/{deidentify_template}"
  };

  // Output only. The template name.
  //
  // The template will have one of the following formats:
  // `projects/PROJECT_ID/deidentifyTemplates/TEMPLATE_ID` OR
  // `organizations/ORGANIZATION_ID/deidentifyTemplates/TEMPLATE_ID`
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Display name (max 256 chars).
  string display_name = 2;

  // Short description (max 256 chars).
  string description = 3;

  // Output only. The creation timestamp of an inspectTemplate.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last update timestamp of an inspectTemplate.
  google.protobuf.Timestamp update_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The core content of the template.
  DeidentifyConfig deidentify_config = 6;
}

// Details information about an error encountered during job execution or
// the results of an unsuccessful activation of the JobTrigger.
message Error {
  // Additional information about the error.
  enum ErrorExtraInfo {
    // Unused.
    ERROR_INFO_UNSPECIFIED = 0;

    // Image scan is not available in the region.
    IMAGE_SCAN_UNAVAILABLE_IN_REGION = 1;

    // File store cluster is not supported for profile generation.
    FILE_STORE_CLUSTER_UNSUPPORTED = 2;
  }

  // Detailed error codes and messages.
  google.rpc.Status details = 1;

  // The times the error occurred. List includes the oldest timestamp and the
  // last 9 timestamps.
  repeated google.protobuf.Timestamp timestamps = 2;

  // Additional information about the error.
  ErrorExtraInfo extra_info = 4;
}

// Contains a configuration to make API calls on a repeating basis.
// See
// https://cloud.google.com/sensitive-data-protection/docs/concepts-job-triggers
// to learn more.
message JobTrigger {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/JobTrigger"
    pattern: "projects/{project}/jobTriggers/{job_trigger}"
    pattern: "projects/{project}/locations/{location}/jobTriggers/{job_trigger}"
  };

  // What event needs to occur for a new job to be started.
  message Trigger {
    // What event needs to occur for a new job to be started.
    oneof trigger {
      // Create a job on a repeating basis based on the elapse of time.
      Schedule schedule = 1;

      // For use with hybrid jobs. Jobs must be manually created and finished.
      Manual manual = 2;
    }
  }

  // Whether the trigger is currently active. If PAUSED or CANCELLED, no jobs
  // will be created with this configuration. The service may automatically
  // pause triggers experiencing frequent errors. To restart a job, set the
  // status to HEALTHY after correcting user errors.
  enum Status {
    // Unused.
    STATUS_UNSPECIFIED = 0;

    // Trigger is healthy.
    HEALTHY = 1;

    // Trigger is temporarily paused.
    PAUSED = 2;

    // Trigger is cancelled and can not be resumed.
    CANCELLED = 3;
  }

  // Unique resource name for the triggeredJob, assigned by the service when the
  // triggeredJob is created, for example
  // `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1;

  // Display name (max 100 chars)
  string display_name = 2;

  // User provided description (max 256 chars)
  string description = 3;

  // The configuration details for the specific type of job to run.
  oneof job {
    // For inspect jobs, a snapshot of the configuration.
    InspectJobConfig inspect_job = 4;
  }

  // A list of triggers which will be OR'ed together. Only one in the list
  // needs to trigger for a job to be started. The list may contain only
  // a single Schedule trigger and must have at least one object.
  repeated Trigger triggers = 5;

  // Output only. A stream of errors encountered when the trigger was activated.
  // Repeated errors may result in the JobTrigger automatically being paused.
  // Will return the last 100 errors. Whenever the JobTrigger is modified
  // this list will be cleared.
  repeated Error errors = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The creation timestamp of a triggeredJob.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last update timestamp of a triggeredJob.
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp of the last time this trigger executed.
  google.protobuf.Timestamp last_run_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. A status for this trigger.
  Status status = 10 [(google.api.field_behavior) = REQUIRED];
}

// A task to execute on the completion of a job.
// See https://cloud.google.com/sensitive-data-protection/docs/concepts-actions
// to learn more.
message Action {
  // If set, the detailed findings will be persisted to the specified
  // OutputStorageConfig. Only a single instance of this action can be
  // specified.
  // Compatible with: Inspect, Risk
  message SaveFindings {
    // Location to store findings outside of DLP.
    OutputStorageConfig output_config = 1;
  }

  // Publish a message into a given Pub/Sub topic when DlpJob has completed. The
  // message contains a single field, `DlpJobName`, which is equal to the
  // finished job's
  // [`DlpJob.name`](https://cloud.google.com/sensitive-data-protection/docs/reference/rest/v2/projects.dlpJobs#DlpJob).
  // Compatible with: Inspect, Risk
  message PublishToPubSub {
    // Cloud Pub/Sub topic to send notifications to. The topic must have given
    // publishing access rights to the DLP API service account executing
    // the long running DlpJob sending the notifications.
    // Format is projects/{project}/topics/{topic}.
    string topic = 1;
  }

  // Publish the result summary of a DlpJob to [Security Command
  // Center](https://cloud.google.com/security-command-center). This action is
  // available for only projects that belong to an organization. This action
  // publishes the count of finding instances and their infoTypes. The summary
  // of findings are persisted in Security Command Center and are governed by
  // [service-specific policies for Security Command
  // Center](https://cloud.google.com/terms/service-terms). Only a single
  // instance of this action can be specified. Compatible with: Inspect
  message PublishSummaryToCscc {}

  // Publish findings of a DlpJob to Data Catalog. In Data Catalog, tag
  // templates are applied to the resource that Cloud DLP scanned. Data
  // Catalog tag templates are stored in the same project and region where the
  // BigQuery table exists. For Cloud DLP to create and apply the tag template,
  // the Cloud DLP service agent must have the
  // `roles/datacatalog.tagTemplateOwner` permission on the project. The tag
  // template contains fields summarizing the results of the DlpJob. Any field
  // values previously written by another DlpJob are deleted. [InfoType naming
  // patterns][google.privacy.dlp.v2.InfoType] are strictly enforced when using
  // this feature.
  //
  // Findings are persisted in Data Catalog storage and are governed by
  // service-specific policies for Data Catalog. For more information, see
  // [Service Specific Terms](https://cloud.google.com/terms/service-terms).
  //
  // Only a single instance of this action can be specified. This action is
  // allowed only if all resources being scanned are BigQuery tables.
  // Compatible with: Inspect
  message PublishFindingsToCloudDataCatalog {}

  // Create a de-identified copy of the requested table or files.
  //
  // A TransformationDetail will be created for each transformation.
  //
  // If any rows in BigQuery are skipped during de-identification
  // (transformation errors or row size exceeds BigQuery insert API limits) they
  // are placed in the failure output table. If the original row exceeds
  // the BigQuery insert API limit it will be truncated when written to the
  // failure output table. The failure output table can be set in the
  // action.deidentify.output.big_query_output.deidentified_failure_output_table
  // field, if no table is set, a table will be automatically created in the
  // same project and dataset as the original table.
  //
  // Compatible with: Inspect
  message Deidentify {
    // User specified deidentify templates and configs for structured,
    // unstructured, and image files.
    TransformationConfig transformation_config = 7;

    // Config for storing transformation details. This is separate from the
    // de-identified content, and contains metadata about the successful
    // transformations and/or failures that occurred while de-identifying. This
    // needs to be set in order for users to access information about the status
    // of each transformation (see
    // [TransformationDetails][google.privacy.dlp.v2.TransformationDetails]
    // message for more information about what is noted).
    TransformationDetailsStorageConfig transformation_details_storage_config =
        3;

    // Where to store the output.
    oneof output {
      // Required. User settable Cloud Storage bucket and folders to store
      // de-identified files. This field must be set for Cloud Storage
      // deidentification. The output Cloud Storage bucket must be different
      // from the input bucket. De-identified files will overwrite files in the
      // output path.
      //
      // Form of: gs://bucket/folder/ or gs://bucket
      string cloud_storage_output = 9 [(google.api.field_behavior) = REQUIRED];
    }

    // List of user-specified file type groups to transform. If specified, only
    // the files with these file types will be transformed. If empty, all
    // supported files will be transformed. Supported types may be automatically
    // added over time. If a file type is set in this field that isn't supported
    // by the Deidentify action then the job will fail and will not be
    // successfully created/started. Currently the only file types supported
    // are: IMAGES, TEXT_FILES, CSV, TSV.
    repeated FileType file_types_to_transform = 8;
  }

  // Sends an email when the job completes. The email goes to IAM project owners
  // and technical [Essential
  // Contacts](https://cloud.google.com/resource-manager/docs/managing-notification-contacts).
  message JobNotificationEmails {}

  // Enable Stackdriver metric dlp.googleapis.com/finding_count. This
  // will publish a metric to stack driver on each infotype requested and
  // how many findings were found for it. CustomDetectors will be bucketed
  // as 'Custom' under the Stackdriver label 'info_type'.
  message PublishToStackdriver {}

  // Extra events to execute after the job has finished.
  oneof action {
    // Save resulting findings in a provided location.
    SaveFindings save_findings = 1;

    // Publish a notification to a Pub/Sub topic.
    PublishToPubSub pub_sub = 2;

    // Publish summary to Cloud Security Command Center (Alpha).
    PublishSummaryToCscc publish_summary_to_cscc = 3;

    // Publish findings to Cloud Datahub.
    PublishFindingsToCloudDataCatalog publish_findings_to_cloud_data_catalog =
        5;

    // Create a de-identified copy of the input data.
    Deidentify deidentify = 7;

    // Sends an email when the job completes. The email goes to IAM project
    // owners and technical [Essential
    // Contacts](https://cloud.google.com/resource-manager/docs/managing-notification-contacts).
    JobNotificationEmails job_notification_emails = 8;

    // Enable Stackdriver metric dlp.googleapis.com/finding_count.
    PublishToStackdriver publish_to_stackdriver = 9;
  }
}

// User specified templates and configs for how to deidentify structured,
// unstructures, and image files. User must provide either a unstructured
// deidentify template or at least one redact image config.
message TransformationConfig {
  // De-identify template.
  // If this template is specified, it will serve as the default de-identify
  // template. This template cannot contain `record_transformations` since it
  // can be used for unstructured content such as free-form text files. If this
  // template is not set, a default `ReplaceWithInfoTypeConfig` will be used to
  // de-identify unstructured content.
  string deidentify_template = 1;

  // Structured de-identify template.
  // If this template is specified, it will serve as the de-identify template
  // for structured content such as delimited files and tables. If this template
  // is not set but the `deidentify_template` is set, then `deidentify_template`
  // will also apply to the structured content. If neither template is set, a
  // default `ReplaceWithInfoTypeConfig` will be used to de-identify structured
  // content.
  string structured_deidentify_template = 2;

  // Image redact template.
  // If this template is specified, it will serve as the de-identify template
  // for images. If this template is not set, all findings in the image will be
  // redacted with a black box.
  string image_redact_template = 4;
}

// Request message for CreateInspectTemplate.
message CreateInspectTemplateRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  // + Organizations scope, location specified:
  //   `organizations/{org_id}/locations/{location_id}`
  // + Organizations scope, no location specified (defaults to global):
  //   `organizations/{org_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/InspectTemplate"
    }
  ];

  // Required. The InspectTemplate to create.
  InspectTemplate inspect_template = 2 [(google.api.field_behavior) = REQUIRED];

  // The template id can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string template_id = 3;

  // Deprecated. This field has no effect.
  string location_id = 4;
}

// Request message for UpdateInspectTemplate.
message UpdateInspectTemplateRequest {
  // Required. Resource name of organization and inspectTemplate to be updated,
  // for example `organizations/433245324/inspectTemplates/432452342` or
  // projects/project-id/inspectTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/InspectTemplate"
    }
  ];

  // New InspectTemplate value.
  InspectTemplate inspect_template = 2;

  // Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for GetInspectTemplate.
message GetInspectTemplateRequest {
  // Required. Resource name of the organization and inspectTemplate to be read,
  // for example `organizations/433245324/inspectTemplates/432452342` or
  // projects/project-id/inspectTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/InspectTemplate"
    }
  ];
}

// Request message for ListInspectTemplates.
message ListInspectTemplatesRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  // + Organizations scope, location specified:
  //   `organizations/{org_id}/locations/{location_id}`
  // + Organizations scope, no location specified (defaults to global):
  //   `organizations/{org_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/InspectTemplate"
    }
  ];

  // Page token to continue retrieval. Comes from the previous call
  // to `ListInspectTemplates`.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc,update_time, create_time desc`
  //
  // Supported fields are:
  //
  // - `create_time`: corresponds to the time the template was created.
  // - `update_time`: corresponds to the time the template was last updated.
  // - `name`: corresponds to the template's name.
  // - `display_name`: corresponds to the template's display name.
  string order_by = 4;

  // Deprecated. This field has no effect.
  string location_id = 5;
}

// Response message for ListInspectTemplates.
message ListInspectTemplatesResponse {
  // List of inspectTemplates, up to page_size in ListInspectTemplatesRequest.
  repeated InspectTemplate inspect_templates = 1;

  // If the next page is available then the next page token to be used in the
  // following ListInspectTemplates request.
  string next_page_token = 2;
}

// Request message for DeleteInspectTemplate.
message DeleteInspectTemplateRequest {
  // Required. Resource name of the organization and inspectTemplate to be
  // deleted, for example `organizations/433245324/inspectTemplates/432452342`
  // or projects/project-id/inspectTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/InspectTemplate"
    }
  ];
}

// Request message for CreateJobTrigger.
message CreateJobTriggerRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/JobTrigger"
    }
  ];

  // Required. The JobTrigger to create.
  JobTrigger job_trigger = 2 [(google.api.field_behavior) = REQUIRED];

  // The trigger id can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string trigger_id = 3;

  // Deprecated. This field has no effect.
  string location_id = 4;
}

// Request message for ActivateJobTrigger.
message ActivateJobTriggerRequest {
  // Required. Resource name of the trigger to activate, for example
  // `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];
}

// Request message for UpdateJobTrigger.
message UpdateJobTriggerRequest {
  // Required. Resource name of the project and the triggeredJob, for example
  // `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];

  // New JobTrigger value.
  JobTrigger job_trigger = 2;

  // Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for GetJobTrigger.
message GetJobTriggerRequest {
  // Required. Resource name of the project and the triggeredJob, for example
  // `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];
}

// Request message for CreateDiscoveryConfig.
message CreateDiscoveryConfigRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization):
  //
  // + Projects scope:
  //   `projects/{project_id}/locations/{location_id}`
  // + Organizations scope:
  //   `organizations/{org_id}/locations/{location_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DiscoveryConfig"
    }
  ];

  // Required. The DiscoveryConfig to create.
  DiscoveryConfig discovery_config = 2 [(google.api.field_behavior) = REQUIRED];

  // The config ID can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string config_id = 3;
}

// Request message for UpdateDiscoveryConfig.
message UpdateDiscoveryConfigRequest {
  // Required. Resource name of the project and the configuration, for example
  // `projects/dlp-test-project/discoveryConfigs/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DiscoveryConfig"
    }
  ];

  // Required. New DiscoveryConfig value.
  DiscoveryConfig discovery_config = 2 [(google.api.field_behavior) = REQUIRED];

  // Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for GetDiscoveryConfig.
message GetDiscoveryConfigRequest {
  // Required. Resource name of the project and the configuration, for example
  // `projects/dlp-test-project/discoveryConfigs/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DiscoveryConfig"
    }
  ];
}

// Request message for ListDiscoveryConfigs.
message ListDiscoveryConfigsRequest {
  // Required. Parent resource name.
  //
  // The format of this value is as follows:
  // `projects/{project_id}/locations/{location_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DiscoveryConfig"
    }
  ];

  // Page token to continue retrieval. Comes from the previous call
  // to ListDiscoveryConfigs. `order_by` field must not
  // change for subsequent calls.
  string page_token = 2;

  // Size of the page. This value can be limited by a server.
  int32 page_size = 3;

  // Comma-separated list of config fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc,update_time, create_time desc`
  //
  // Supported fields are:
  //
  // - `last_run_time`: corresponds to the last time the DiscoveryConfig ran.
  // - `name`: corresponds to the DiscoveryConfig's name.
  // - `status`: corresponds to DiscoveryConfig's status.
  string order_by = 4;
}

// Response message for ListDiscoveryConfigs.
message ListDiscoveryConfigsResponse {
  // List of configs, up to page_size in ListDiscoveryConfigsRequest.
  repeated DiscoveryConfig discovery_configs = 1;

  // If the next page is available then this value is the next page token to be
  // used in the following ListDiscoveryConfigs request.
  string next_page_token = 2;
}

// Request message for DeleteDiscoveryConfig.
message DeleteDiscoveryConfigRequest {
  // Required. Resource name of the project and the config, for example
  // `projects/dlp-test-project/discoveryConfigs/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DiscoveryConfig"
    }
  ];
}

// Request message for CreateDlpJobRequest. Used to initiate long running
// jobs such as calculating risk metrics or inspecting Google Cloud
// Storage.
message CreateDlpJobRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DlpJob"
    }
  ];

  // The configuration details for the specific type of job to run.
  oneof job {
    // An inspection job scans a storage repository for InfoTypes.
    InspectJobConfig inspect_job = 2;

    // A risk analysis job calculates re-identification risk metrics for a
    // BigQuery table.
    RiskAnalysisJobConfig risk_job = 3;
  }

  // The job id can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string job_id = 4;

  // Deprecated. This field has no effect.
  string location_id = 5;
}

// Request message for ListJobTriggers.
message ListJobTriggersRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/JobTrigger"
    }
  ];

  // Page token to continue retrieval. Comes from the previous call
  // to ListJobTriggers. `order_by` field must not
  // change for subsequent calls.
  string page_token = 2;

  // Size of the page. This value can be limited by a server.
  int32 page_size = 3;

  // Comma-separated list of triggeredJob fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc,update_time, create_time desc`
  //
  // Supported fields are:
  //
  // - `create_time`: corresponds to the time the JobTrigger was created.
  // - `update_time`: corresponds to the time the JobTrigger was last updated.
  // - `last_run_time`: corresponds to the last time the JobTrigger ran.
  // - `name`: corresponds to the JobTrigger's name.
  // - `display_name`: corresponds to the JobTrigger's display name.
  // - `status`: corresponds to JobTrigger's status.
  string order_by = 4;

  // Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values for inspect triggers:
  //     - `status` - HEALTHY|PAUSED|CANCELLED
  //     - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY
  //     - 'last_run_time` - RFC 3339 formatted timestamp, surrounded by
  //     quotation marks. Nanoseconds are ignored.
  //     - 'error_count' - Number of errors that have occurred while running.
  // * The operator must be `=` or `!=` for status and inspected_storage.
  //
  // Examples:
  //
  // * inspected_storage = cloud_storage AND status = HEALTHY
  // * inspected_storage = cloud_storage OR inspected_storage = bigquery
  // * inspected_storage = cloud_storage AND (state = PAUSED OR state = HEALTHY)
  // * last_run_time > \"2017-12-12T00:00:00+00:00\"
  //
  // The length of this field should be no more than 500 characters.
  string filter = 5;

  // The type of jobs. Will use `DlpJobType.INSPECT` if not set.
  DlpJobType type = 6;

  // Deprecated. This field has no effect.
  string location_id = 7;
}

// Response message for ListJobTriggers.
message ListJobTriggersResponse {
  // List of triggeredJobs, up to page_size in ListJobTriggersRequest.
  repeated JobTrigger job_triggers = 1;

  // If the next page is available then this value is the next page token to be
  // used in the following ListJobTriggers request.
  string next_page_token = 2;
}

// Request message for DeleteJobTrigger.
message DeleteJobTriggerRequest {
  // Required. Resource name of the project and the triggeredJob, for example
  // `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];
}

// Controls what and how to inspect for findings.
message InspectJobConfig {
  // The data to scan.
  StorageConfig storage_config = 1;

  // How and what to scan for.
  InspectConfig inspect_config = 2;

  // If provided, will be used as the default for all values in InspectConfig.
  // `inspect_config` will be merged into the values persisted as part of the
  // template.
  string inspect_template_name = 3;

  // Actions to execute at the completion of the job.
  repeated Action actions = 4;
}

// Whether a profile being created is the first generation or an update.
enum ProfileGeneration {
  // Unused.
  PROFILE_GENERATION_UNSPECIFIED = 0;

  // The profile is the first profile for the resource.
  PROFILE_GENERATION_NEW = 1;

  // The profile is an update to a previous profile.
  PROFILE_GENERATION_UPDATE = 2;
}

// A task to execute when a data profile has been generated.
message DataProfileAction {
  // If set, the detailed data profiles will be persisted to the location
  // of your choice whenever updated.
  message Export {
    // Store all profiles to BigQuery.
    //
    // * The system will create a new dataset and table for you if none are
    //   are provided. The dataset will be named
    //   `sensitive_data_protection_discovery` and table will be named
    //   `discovery_profiles`. This table will be placed in the same project as
    //   the container project running the scan. After the first profile is
    //   generated and the dataset and table are created, the discovery scan
    //   configuration will be updated with the dataset and table names.
    // * See [Analyze data profiles stored in
    // BigQuery](https://cloud.google.com/sensitive-data-protection/docs/analyze-data-profiles).
    // * See [Sample queries for your BigQuery
    // table](https://cloud.google.com/sensitive-data-protection/docs/analyze-data-profiles#sample_sql_queries).
    // *  Data is inserted using [streaming
    //    insert](https://cloud.google.com/blog/products/bigquery/life-of-a-bigquery-streaming-insert)
    //    and so data may be in the buffer for a period of time after the
    //    profile has finished.
    //  * The Pub/Sub notification is sent before the streaming buffer is
    //    guaranteed to be written, so data may not be instantly
    //    visible to queries by the time your topic receives the Pub/Sub
    //    notification.
    //  * The best practice is to use the same table for an entire organization
    //    so that you can take advantage of the [provided Looker
    //    reports](https://cloud.google.com/sensitive-data-protection/docs/analyze-data-profiles#use_a_premade_report).
    //    If you use VPC Service Controls to define security perimeters, then
    //    you must use a separate table for each boundary.
    BigQueryTable profile_table = 1;

    // Store sample [data profile
    // findings][google.privacy.dlp.v2.DataProfileFinding] in an existing table
    // or a new table in an existing dataset. Each regeneration will result in
    // new rows in BigQuery. Data is inserted using [streaming
    // insert](https://cloud.google.com/blog/products/bigquery/life-of-a-bigquery-streaming-insert)
    // and so data may be in the buffer for a period of time after the profile
    // has finished.
    BigQueryTable sample_findings_table = 2;
  }

  // Send a Pub/Sub message into the given Pub/Sub topic to connect other
  // systems to data profile generation. The message payload data will
  // be the byte serialization of `DataProfilePubSubMessage`.
  message PubSubNotification {
    // The levels of detail that can be included in the Pub/Sub message.
    enum DetailLevel {
      // Unused.
      DETAIL_LEVEL_UNSPECIFIED = 0;

      // The full table data profile.
      TABLE_PROFILE = 1;

      // The name of the profiled resource.
      RESOURCE_NAME = 2;

      // The full file store data profile.
      FILE_STORE_PROFILE = 3;
    }

    // Cloud Pub/Sub topic to send notifications to.
    // Format is projects/{project}/topics/{topic}.
    string topic = 1;

    // The type of event that triggers a Pub/Sub. At most one
    // `PubSubNotification` per EventType is permitted.
    EventType event = 2;

    // Conditions (e.g., data risk or sensitivity level) for triggering a
    // Pub/Sub.
    DataProfilePubSubCondition pubsub_condition = 3;

    // How much data to include in the Pub/Sub message. If the user wishes to
    // limit the size of the message, they can use resource_name and fetch the
    // profile fields they wish to. Per table profile (not per column).
    DetailLevel detail_of_message = 4;
  }

  // Types of event that can trigger an action.
  enum EventType {
    // Unused.
    EVENT_TYPE_UNSPECIFIED = 0;

    // New profile (not a re-profile).
    NEW_PROFILE = 1;

    // One of the following profile metrics changed: Data risk score,
    // Sensitivity score, Resource visibility, Encryption type, Predicted
    // infoTypes, Other infoTypes
    CHANGED_PROFILE = 2;

    // Table data risk score or sensitivity score increased.
    SCORE_INCREASED = 3;

    // A user (non-internal) error occurred.
    ERROR_CHANGED = 4;
  }

  // Message expressing intention to publish to Google Security Operations.
  message PublishToChronicle {}

  // If set, a summary finding will be created or updated in Security Command
  // Center for each profile.
  message PublishToSecurityCommandCenter {}

  // If set, attaches the [tags]
  // (https://cloud.google.com/resource-manager/docs/tags/tags-overview)
  // provided to profiled resources. Tags support [access
  // control](https://cloud.google.com/iam/docs/tags-access-control). You can
  // conditionally grant or deny access to a resource based on whether the
  // resource has a specific tag.
  message TagResources {
    // The tag to attach to profiles matching the condition. At most one
    // `TagCondition` can be specified per sensitivity level.
    message TagCondition {
      // The tag value to attach to resources.
      TagValue tag = 1;

      // The type of condition on which attaching the tag will be predicated.
      oneof type {
        // Conditions attaching the tag to a resource on its profile having this
        // sensitivity score.
        SensitivityScore sensitivity_score = 2;
      }
    }

    // A value of a tag.
    message TagValue {
      // The format of the tag value.
      oneof format {
        // The namespaced name for the tag value to attach to resources. Must be
        // in the format `{parent_id}/{tag_key_short_name}/{short_name}`, for
        // example, "123456/environment/prod".
        string namespaced_value = 1;
      }
    }

    // The tags to associate with different conditions.
    repeated TagCondition tag_conditions = 1;

    // The profile generations for which the tag should be attached to
    // resources. If you attach a tag to only new profiles, then if the
    // sensitivity score of a profile subsequently changes, its tag doesn't
    // change. By default, this field includes only new profiles. To include
    // both new and updated profiles for tagging, this field should explicitly
    // include both `PROFILE_GENERATION_NEW` and `PROFILE_GENERATION_UPDATE`.
    repeated ProfileGeneration profile_generations_to_tag = 2;

    // Whether applying a tag to a resource should lower the risk of the profile
    // for that resource. For example, in conjunction with an [IAM deny
    // policy](https://cloud.google.com/iam/docs/deny-overview), you can deny
    // all principals a permission if a tag value is present, mitigating the
    // risk of the resource. This also lowers the data risk of resources at the
    // lower levels of the resource hierarchy. For example, reducing the data
    // risk of a table data profile also reduces the data risk of the
    // constituent column data profiles.
    bool lower_data_risk_to_low = 3;
  }

  // Type of action to execute when a profile is generated.
  oneof action {
    // Export data profiles into a provided location.
    Export export_data = 1;

    // Publish a message into the Pub/Sub topic.
    PubSubNotification pub_sub_notification = 2;

    // Publishes generated data profiles to Google Security Operations.
    // For more information, see [Use Sensitive Data Protection data in
    // context-aware
    // analytics](https://cloud.google.com/chronicle/docs/detection/usecase-dlp-high-risk-user-download).
    PublishToChronicle publish_to_chronicle = 3;

    // Publishes findings to Security Command Center for each data profile.
    PublishToSecurityCommandCenter publish_to_scc = 4;

    // Tags the profiled resources with the specified tag values.
    TagResources tag_resources = 8;
  }
}

// Details about a piece of potentially sensitive information that was detected
// when the data resource was profiled.
message DataProfileFinding {
  // The content that was found. Even if the content is not textual, it
  // may be converted to a textual representation here. If the finding exceeds
  // 4096 bytes in length, the quote may be omitted.
  string quote = 1;

  // The [type of
  // content](https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference)
  // that might have been found.
  InfoType infotype = 2;

  // Contains data parsed from quotes. Currently supported infoTypes: DATE,
  // DATE_OF_BIRTH, and TIME.
  QuoteInfo quote_info = 3;

  // Resource name of the data profile associated with the finding.
  string data_profile_resource_name = 4;

  // A unique identifier for the finding.
  string finding_id = 5;

  // Timestamp when the finding was detected.
  google.protobuf.Timestamp timestamp = 6;

  // Where the content was found.
  DataProfileFindingLocation location = 7;

  // How broadly a resource has been shared.
  ResourceVisibility resource_visibility = 8;
}

// Location of a data profile finding within a resource.
message DataProfileFindingLocation {
  // Name of the container where the finding is located.
  // The top-level name is the source file name or table name. Names of some
  // common storage containers are formatted as follows:
  //
  // * BigQuery tables:  `{project_id}:{dataset_id}.{table_id}`
  // * Cloud Storage files: `gs://{bucket}/{path}`
  string container_name = 1;

  // Additional location details that may be provided for some types of
  // profiles. At this time, only findings for table data profiles include such
  // details.
  oneof location_extra_details {
    // Location of a finding within a resource that produces a table data
    // profile.
    DataProfileFindingRecordLocation data_profile_finding_record_location = 2;
  }
}

// Location of a finding within a resource that produces a table data profile.
message DataProfileFindingRecordLocation {
  // Field ID of the column containing the finding.
  FieldId field = 1;
}

// Configuration for setting up a job to scan resources for profile generation.
// Only one data profile configuration may exist per organization, folder,
// or project.
//
// The generated data profiles are retained according to the
// [data retention policy]
// (https://cloud.google.com/sensitive-data-protection/docs/data-profiles#retention).
message DataProfileJobConfig {
  // The data to scan.
  DataProfileLocation location = 1;

  // The project that will run the scan. The DLP service
  // account that exists within this project must have access to all resources
  // that are profiled, and the DLP API must be enabled.
  string project_id = 5;

  // Must be set only when scanning other clouds.
  OtherCloudDiscoveryStartingLocation other_cloud_starting_location = 8;

  // Detection logic for profile generation.
  //
  // Not all template features are used by profiles. FindingLimits,
  // include_quote and exclude_info_types have no impact on
  // data profiling.
  //
  // Multiple templates may be provided if there is data in multiple regions.
  // At most one template must be specified per-region (including "global").
  // Each region is scanned using the applicable template. If no region-specific
  // template is specified, but a "global" template is specified, it will be
  // copied to that region and used instead. If no global or region-specific
  // template is provided for a region with data, that region's data will not be
  // scanned.
  //
  // For more information, see
  // https://cloud.google.com/sensitive-data-protection/docs/data-profiles#data-residency.
  repeated string inspect_templates = 7;

  // Actions to execute at the completion of the job.
  repeated DataProfileAction data_profile_actions = 6;
}

// A pattern to match against one or more tables, datasets, or projects that
// contain BigQuery tables. At least one pattern must be specified.
// Regular expressions use RE2
// [syntax](https://github.com/google/re2/wiki/Syntax); a guide can be found
// under the google/re2 repository on GitHub.
message BigQueryRegex {
  // For organizations, if unset, will match all projects. Has no effect
  // for data profile configurations created within a project.
  string project_id_regex = 1;

  // If unset, this property matches all datasets.
  string dataset_id_regex = 2;

  // If unset, this property matches all tables.
  string table_id_regex = 3;
}

// A collection of regular expressions to determine what tables to match
// against.
message BigQueryRegexes {
  // A single BigQuery regular expression pattern to match against one or more
  // tables, datasets, or projects that contain BigQuery tables.
  repeated BigQueryRegex patterns = 1;
}

// The types of BigQuery tables supported by Cloud DLP.
message BigQueryTableTypes {
  // A set of BigQuery table types.
  repeated BigQueryTableType types = 1;
}

// Over time new types may be added. Currently VIEW, MATERIALIZED_VIEW, and
// non-BigLake external tables are not supported.
enum BigQueryTableTypeCollection {
  // Unused.
  BIG_QUERY_COLLECTION_UNSPECIFIED = 0;

  // Automatically generate profiles for all tables, even if the table type is
  // not yet fully supported for analysis. Profiles for unsupported tables will
  // be generated with errors to indicate their partial support. When full
  // support is added, the tables will automatically be profiled during the next
  // scheduled run.
  BIG_QUERY_COLLECTION_ALL_TYPES = 1;

  // Only those types fully supported will be profiled. Will expand
  // automatically as Cloud DLP adds support for new table types. Unsupported
  // table types will not have partial profiles generated.
  BIG_QUERY_COLLECTION_ONLY_SUPPORTED_TYPES = 2;
}

// Over time new types may be added. Currently VIEW, MATERIALIZED_VIEW, and
// non-BigLake external tables are not supported.
enum BigQueryTableType {
  // Unused.
  BIG_QUERY_TABLE_TYPE_UNSPECIFIED = 0;

  // A normal BigQuery table.
  BIG_QUERY_TABLE_TYPE_TABLE = 1;

  // A table that references data stored in Cloud Storage.
  BIG_QUERY_TABLE_TYPE_EXTERNAL_BIG_LAKE = 2;

  // A snapshot of a BigQuery table.
  BIG_QUERY_TABLE_TYPE_SNAPSHOT = 3;
}

// How frequently data profiles can be updated. New options can be added at a
// later time.
enum DataProfileUpdateFrequency {
  // Unspecified.
  UPDATE_FREQUENCY_UNSPECIFIED = 0;

  // After the data profile is created, it will never be updated.
  UPDATE_FREQUENCY_NEVER = 1;

  // The data profile can be updated up to once every 24 hours.
  UPDATE_FREQUENCY_DAILY = 2;

  // The data profile can be updated up to once every 30 days. Default.
  UPDATE_FREQUENCY_MONTHLY = 4;
}

// Do not profile the tables.
message Disabled {}

// The data that will be profiled.
message DataProfileLocation {
  // The location to be scanned.
  oneof location {
    // The ID of an organization to scan.
    int64 organization_id = 1;

    // The ID of the folder within an organization to scan.
    int64 folder_id = 2;
  }
}

// Configuration for discovery to scan resources for profile generation.
// Only one discovery configuration may exist per organization, folder,
// or project.
//
// The generated data profiles are retained according to the
// [data retention policy]
// (https://cloud.google.com/sensitive-data-protection/docs/data-profiles#retention).
message DiscoveryConfig {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/DiscoveryConfig"
    pattern: "projects/{project}/locations/{location}/discoveryConfigs/{discovery_config}"
  };

  // Project and scan location information. Only set when the parent is an org.
  message OrgConfig {
    // The data to scan: folder, org, or project
    DiscoveryStartingLocation location = 1;

    // The project that will run the scan. The DLP service
    // account that exists within this project must have access to all resources
    // that are profiled, and the DLP API must be enabled.
    string project_id = 2;
  }

  // Whether the discovery config is currently active. New options may be added
  // at a later time.
  enum Status {
    // Unused
    STATUS_UNSPECIFIED = 0;

    // The discovery config is currently active.
    RUNNING = 1;

    // The discovery config is paused temporarily.
    PAUSED = 2;
  }

  // Unique resource name for the DiscoveryConfig, assigned by the service when
  // the DiscoveryConfig is created, for example
  // `projects/dlp-test-project/locations/global/discoveryConfigs/53234423`.
  string name = 1;

  // Display name (max 100 chars)
  string display_name = 11;

  // Only set when the parent is an org.
  OrgConfig org_config = 2;

  // Must be set only when scanning other clouds.
  OtherCloudDiscoveryStartingLocation other_cloud_starting_location = 12;

  // Detection logic for profile generation.
  //
  // Not all template features are used by Discovery. FindingLimits,
  // include_quote and exclude_info_types have no impact on
  // Discovery.
  //
  // Multiple templates may be provided if there is data in multiple regions.
  // At most one template must be specified per-region (including "global").
  // Each region is scanned using the applicable template. If no region-specific
  // template is specified, but a "global" template is specified, it will be
  // copied to that region and used instead. If no global or region-specific
  // template is provided for a region with data, that region's data will not be
  // scanned.
  //
  // For more information, see
  // https://cloud.google.com/sensitive-data-protection/docs/data-profiles#data-residency.
  repeated string inspect_templates = 3;

  // Actions to execute at the completion of scanning.
  repeated DataProfileAction actions = 4;

  // Target to match against for determining what to scan and how frequently.
  repeated DiscoveryTarget targets = 5;

  // Output only. A stream of errors encountered when the config was activated.
  // Repeated errors may result in the config automatically being paused. Output
  // only field. Will return the last 100 errors. Whenever the config is
  // modified this list will be cleared.
  repeated Error errors = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The creation timestamp of a DiscoveryConfig.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last update timestamp of a DiscoveryConfig.
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp of the last time this config was executed.
  google.protobuf.Timestamp last_run_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. A status for this configuration.
  Status status = 10 [(google.api.field_behavior) = REQUIRED];

  // Optional. Processing location configuration. Vertex AI dataset scanning
  // will set processing_location.image_fallback_type to MultiRegionProcessing
  // by default.
  ProcessingLocation processing_location = 13
      [(google.api.field_behavior) = OPTIONAL];
}

// Target used to match against for Discovery.
message DiscoveryTarget {
  // A target to match against for Discovery.
  oneof target {
    // BigQuery target for Discovery. The first target to match a table will be
    // the one applied.
    BigQueryDiscoveryTarget big_query_target = 1;

    // Cloud SQL target for Discovery. The first target to match a table will be
    // the one applied.
    CloudSqlDiscoveryTarget cloud_sql_target = 2;

    // Discovery target that looks for credentials and secrets stored in cloud
    // resource metadata and reports them as vulnerabilities to Security Command
    // Center. Only one target of this type is allowed.
    SecretsDiscoveryTarget secrets_target = 3;

    // Cloud Storage target for Discovery. The first target to match a table
    // will be the one applied.
    CloudStorageDiscoveryTarget cloud_storage_target = 4;

    // Other clouds target for discovery. The first target to match a resource
    // will be the one applied.
    OtherCloudDiscoveryTarget other_cloud_target = 5;

    // Vertex AI dataset target for Discovery. The first target to match a
    // dataset will be the one applied. Note that discovery for Vertex AI can
    // incur Cloud Storage Class B operation charges for storage.objects.get
    // operations and retrieval fees. For more information, see [Cloud Storage
    // pricing](https://cloud.google.com/storage/pricing#price-tables).
    // Note that discovery for Vertex AI dataset will not be able to scan images
    // unless DiscoveryConfig.processing_location.image_fallback_location has
    // multi_region_processing or global_processing configured.
    VertexDatasetDiscoveryTarget vertex_dataset_target = 7;
  }
}

// Target used to match against for discovery with BigQuery tables
message BigQueryDiscoveryTarget {
  // Required. The tables the discovery cadence applies to. The first target
  // with a matching filter will be the one to apply to a table.
  DiscoveryBigQueryFilter filter = 1 [(google.api.field_behavior) = REQUIRED];

  // In addition to matching the filter, these conditions must be true
  // before a profile is generated.
  DiscoveryBigQueryConditions conditions = 2;

  // The generation rule includes the logic on how frequently
  // to update the data profiles. If not specified, discovery will re-run and
  // update no more than once a month if new columns appear in the table.
  oneof frequency {
    // How often and when to update profiles. New tables that match both the
    // filter and conditions are scanned as quickly as possible depending on
    // system capacity.
    DiscoveryGenerationCadence cadence = 3;

    // Tables that match this filter will not have profiles created.
    Disabled disabled = 4;
  }
}

// Determines what tables will have profiles generated within an organization
// or project. Includes the ability to filter by regular expression patterns
// on project ID, dataset ID, and table ID.
message DiscoveryBigQueryFilter {
  // Catch-all for all other tables not specified by other filters. Should
  // always be last, except for single-table configurations, which will only
  // have a TableReference target.
  message AllOtherBigQueryTables {}

  // Whether the filter applies to a specific set of tables or all other tables
  // within the location being profiled. The first filter to match will be
  // applied, regardless of the condition. If none is set, will default to
  // `other_tables`.
  oneof filter {
    // A specific set of tables for this filter to apply to. A table collection
    // must be specified in only one filter per config.
    // If a table id or dataset is empty, Cloud DLP assumes all tables in that
    // collection must be profiled. Must specify a project ID.
    BigQueryTableCollection tables = 1;

    // Catch-all. This should always be the last filter in the list because
    // anything above it will apply first. Should only appear once in a
    // configuration. If none is specified, a default one will be added
    // automatically.
    AllOtherBigQueryTables other_tables = 2;

    // The table to scan. Discovery configurations including this can only
    // include one DiscoveryTarget (the DiscoveryTarget with this
    // TableReference).
    TableReference table_reference = 3;
  }
}

// Specifies a collection of BigQuery tables. Used for Discovery.
message BigQueryTableCollection {
  // Maximum of 100 entries.
  // The first filter containing a pattern that matches a table will be used.
  oneof pattern {
    // A collection of regular expressions to match a BigQuery table against.
    BigQueryRegexes include_regexes = 1;
  }
}

// Requirements that must be true before a table is scanned in discovery for the
// first time. There is an AND relationship between the top-level attributes.
// Additionally, minimum conditions with an OR relationship that must be met
// before Cloud DLP scans a table can be set (like a minimum row count or a
// minimum table age).
message DiscoveryBigQueryConditions {
  // There is an OR relationship between these attributes. They are used to
  // determine if a table should be scanned or not in Discovery.
  message OrConditions {
    // Minimum number of rows that should be present before Cloud DLP
    // profiles a table
    int32 min_row_count = 1;

    // Minimum age a table must have before Cloud DLP can profile it. Value must
    // be 1 hour or greater.
    google.protobuf.Duration min_age = 2;
  }

  // BigQuery table must have been created after this date. Used to avoid
  // backfilling.
  google.protobuf.Timestamp created_after = 1;

  // The type of BigQuery tables to scan. If nothing is set the default
  // behavior is to scan only tables of type TABLE and to give errors
  // for all unsupported tables.
  oneof included_types {
    // Restrict discovery to specific table types.
    BigQueryTableTypes types = 2;

    // Restrict discovery to categories of table types.
    BigQueryTableTypeCollection type_collection = 3;
  }

  // At least one of the conditions must be true for a table to be scanned.
  OrConditions or_conditions = 4;
}

// What must take place for a profile to be updated and how
// frequently it should occur.
// New tables are scanned as quickly as possible depending on system
// capacity.
message DiscoveryGenerationCadence {
  // Governs when to update data profiles when a schema is modified.
  DiscoverySchemaModifiedCadence schema_modified_cadence = 1;

  // Governs when to update data profiles when a table is modified.
  DiscoveryTableModifiedCadence table_modified_cadence = 2;

  // Governs when to update data profiles when the inspection rules
  // defined by the `InspectTemplate` change.
  // If not set, changing the template will not cause a data profile to update.
  DiscoveryInspectTemplateModifiedCadence inspect_template_modified_cadence = 3;

  // Frequency at which profiles should be updated, regardless of whether the
  // underlying resource has changed. Defaults to never.
  DataProfileUpdateFrequency refresh_frequency = 4;
}

// The cadence at which to update data profiles when a table is modified.
message DiscoveryTableModifiedCadence {
  // The type of events to consider when deciding if the table has been
  // modified and should have the profile updated. Defaults to
  // MODIFIED_TIMESTAMP.
  repeated BigQueryTableModification types = 1;

  // How frequently data profiles can be updated when tables are modified.
  // Defaults to never.
  DataProfileUpdateFrequency frequency = 2;
}

// Attributes evaluated to determine if a table has been modified. New values
// may be added at a later time.
enum BigQueryTableModification {
  // Unused.
  TABLE_MODIFICATION_UNSPECIFIED = 0;

  // A table will be considered modified when the last_modified_time from
  // BigQuery has been updated.
  TABLE_MODIFIED_TIMESTAMP = 1;
}

// The cadence at which to update data profiles when a schema is modified.
message DiscoverySchemaModifiedCadence {
  // The type of events to consider when deciding if the table's schema
  // has been modified and should have the profile updated. Defaults to
  // NEW_COLUMNS.
  repeated BigQuerySchemaModification types = 1;

  // How frequently profiles may be updated when schemas are
  // modified. Defaults to monthly.
  DataProfileUpdateFrequency frequency = 2;
}

// Attributes evaluated to determine if a schema has been modified. New values
// may be added at a later time.
enum BigQuerySchemaModification {
  // Unused
  SCHEMA_MODIFICATION_UNSPECIFIED = 0;

  // Profiles should be regenerated when new columns are added to the table.
  // Default.
  SCHEMA_NEW_COLUMNS = 1;

  // Profiles should be regenerated when columns are removed from the table.
  SCHEMA_REMOVED_COLUMNS = 2;
}

// The cadence at which to update data profiles when the inspection rules
// defined by the `InspectTemplate` change.
message DiscoveryInspectTemplateModifiedCadence {
  // How frequently data profiles can be updated when the template is modified.
  // Defaults to never.
  DataProfileUpdateFrequency frequency = 1;
}

// Target used to match against for discovery with Cloud SQL tables.
message CloudSqlDiscoveryTarget {
  // Required. The tables the discovery cadence applies to. The first target
  // with a matching filter will be the one to apply to a table.
  DiscoveryCloudSqlFilter filter = 1 [(google.api.field_behavior) = REQUIRED];

  // In addition to matching the filter, these conditions must be true
  // before a profile is generated.
  DiscoveryCloudSqlConditions conditions = 2;

  // Type of schedule.
  oneof cadence {
    // How often and when to update profiles. New tables that match both the
    // filter and conditions are scanned as quickly as possible depending on
    // system capacity.
    DiscoveryCloudSqlGenerationCadence generation_cadence = 3;

    // Disable profiling for database resources that match this filter.
    Disabled disabled = 4;
  }
}

// Determines what tables will have profiles generated within an organization
// or project. Includes the ability to filter by regular expression patterns
// on project ID, location, instance, database, and database resource name.
message DiscoveryCloudSqlFilter {
  // Whether the filter applies to a specific set of database resources or all
  // other database resources within the location being profiled. The first
  // filter to match will be applied, regardless of the condition. If none is
  // set, will default to `others`.
  oneof filter {
    // A specific set of database resources for this filter to apply to.
    DatabaseResourceCollection collection = 1;

    // Catch-all. This should always be the last target in the list because
    // anything above it will apply first. Should only appear once in a
    // configuration. If none is specified, a default one will be added
    // automatically.
    AllOtherDatabaseResources others = 2;

    // The database resource to scan. Targets including this can only include
    // one target (the target with this database resource reference).
    DatabaseResourceReference database_resource_reference = 3;
  }
}

// Match database resources using regex filters. Examples of database
// resources are tables, views, and stored procedures.
message DatabaseResourceCollection {
  // The first filter containing a pattern that matches a database resource will
  // be used.
  oneof pattern {
    // A collection of regular expressions to match a database resource against.
    DatabaseResourceRegexes include_regexes = 1;
  }
}

// A collection of regular expressions to determine what database resources to
// match against.
message DatabaseResourceRegexes {
  // A group of regular expression patterns to match against one or more
  // database resources.
  // Maximum of 100 entries. The sum of all regular expression's length can't
  // exceed 10 KiB.
  repeated DatabaseResourceRegex patterns = 1;
}

// A pattern to match against one or more database resources. At least one
// pattern must be specified. Regular expressions use RE2
// [syntax](https://github.com/google/re2/wiki/Syntax); a guide can be found
// under the google/re2 repository on GitHub.
message DatabaseResourceRegex {
  // For organizations, if unset, will match all projects. Has no effect
  // for configurations created within a project.
  string project_id_regex = 1;

  // Regex to test the instance name against. If empty, all instances match.
  string instance_regex = 2;

  // Regex to test the database name against. If empty, all databases match.
  string database_regex = 3;

  // Regex to test the database resource's name against. An example of a
  // database resource name is a table's name. Other database resource names
  // like view names could be included in the future. If empty, all database
  // resources match.
  string database_resource_name_regex = 4;
}

// Match database resources not covered by any other filter.
message AllOtherDatabaseResources {}

// Identifies a single database resource, like a table within a database.
message DatabaseResourceReference {
  // Required. If within a project-level config, then this must match the
  // config's project ID.
  string project_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The instance where this resource is located. For example: Cloud
  // SQL instance ID.
  string instance = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Name of a database within the instance.
  string database = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Name of a database resource, for example, a table within the
  // database.
  string database_resource = 4 [(google.api.field_behavior) = REQUIRED];
}

// Requirements that must be true before a table is profiled for the
// first time.
message DiscoveryCloudSqlConditions {
  // The database engines that should be profiled.
  enum DatabaseEngine {
    // Unused.
    DATABASE_ENGINE_UNSPECIFIED = 0;

    // Include all supported database engines.
    ALL_SUPPORTED_DATABASE_ENGINES = 1;

    // MySQL database.
    MYSQL = 2;

    // PostgreSQL database.
    POSTGRES = 3;
  }

  // Cloud SQL database resource types. New values can be added at a later time.
  enum DatabaseResourceType {
    // Unused.
    DATABASE_RESOURCE_TYPE_UNSPECIFIED = 0;

    // Includes database resource types that become supported at a later time.
    DATABASE_RESOURCE_TYPE_ALL_SUPPORTED_TYPES = 1;

    // Tables.
    DATABASE_RESOURCE_TYPE_TABLE = 2;
  }

  // Optional. Database engines that should be profiled.
  // Optional. Defaults to ALL_SUPPORTED_DATABASE_ENGINES if unspecified.
  repeated DatabaseEngine database_engines = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Data profiles will only be generated for the database resource types
  // specified in this field.
  // If not specified, defaults to [DATABASE_RESOURCE_TYPE_ALL_SUPPORTED_TYPES].
  repeated DatabaseResourceType types = 3;
}

// How often existing tables should have their profiles refreshed.
// New tables are scanned as quickly as possible depending on system
// capacity.
message DiscoveryCloudSqlGenerationCadence {
  // How frequently to modify the profile when the table's schema is modified.
  message SchemaModifiedCadence {
    // The type of modification that causes a profile update.
    enum CloudSqlSchemaModification {
      // Unused.
      SQL_SCHEMA_MODIFICATION_UNSPECIFIED = 0;

      // New columns have appeared.
      NEW_COLUMNS = 1;

      // Columns have been removed from the table.
      REMOVED_COLUMNS = 2;
    }

    // The types of schema modifications to consider.
    // Defaults to NEW_COLUMNS.
    repeated CloudSqlSchemaModification types = 1;

    // Frequency to regenerate data profiles when the schema is modified.
    // Defaults to monthly.
    DataProfileUpdateFrequency frequency = 2;
  }

  // When to reprofile if the schema has changed.
  SchemaModifiedCadence schema_modified_cadence = 1;

  // Data changes (non-schema changes) in Cloud SQL tables can't trigger
  // reprofiling. If you set this field, profiles are refreshed at this
  // frequency regardless of whether the underlying tables have changed.
  // Defaults to never.
  DataProfileUpdateFrequency refresh_frequency = 2;

  // Governs when to update data profiles when the inspection rules
  // defined by the `InspectTemplate` change.
  // If not set, changing the template will not cause a data profile to update.
  DiscoveryInspectTemplateModifiedCadence inspect_template_modified_cadence = 3;
}

// Discovery target for credentials and secrets in cloud resource metadata.
//
// This target does not include any filtering or frequency controls. Cloud
// DLP will scan cloud resource metadata for secrets daily.
//
// No inspect template should be included in the discovery config for a
// security benchmarks scan. Instead, the built-in list of secrets and
// credentials infoTypes will be used (see
// https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference#credentials_and_secrets).
//
// Credentials and secrets discovered will be reported as vulnerabilities to
// Security Command Center.
message SecretsDiscoveryTarget {}

// Target used to match against for discovery with Cloud Storage buckets.
message CloudStorageDiscoveryTarget {
  // Required. The buckets the generation_cadence applies to. The first target
  // with a matching filter will be the one to apply to a bucket.
  DiscoveryCloudStorageFilter filter = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. In addition to matching the filter, these conditions must be true
  // before a profile is generated.
  DiscoveryFileStoreConditions conditions = 4
      [(google.api.field_behavior) = OPTIONAL];

  // How often and when to update profiles.
  oneof cadence {
    // Optional. How often and when to update profiles. New buckets that match
    // both the filter and conditions are scanned as quickly as possible
    // depending on system capacity.
    DiscoveryCloudStorageGenerationCadence generation_cadence = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Disable profiling for buckets that match this filter.
    Disabled disabled = 3 [(google.api.field_behavior) = OPTIONAL];
  }
}

// Determines which buckets will have profiles generated within an organization
// or project. Includes the ability to filter by regular expression patterns
// on project ID and bucket name.
message DiscoveryCloudStorageFilter {
  // Whether the filter applies to a specific set of buckets or all
  // other buckets within the location being profiled. The first
  // filter to match will be applied, regardless of the condition. If none is
  // set, will default to `others`.
  oneof filter {
    // Optional. A specific set of buckets for this filter to apply to.
    FileStoreCollection collection = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The bucket to scan. Targets including this can only include one
    // target (the target with this bucket). This enables profiling the contents
    // of a single bucket, while the other options allow for easy profiling of
    // many bucets within a project or an organization.
    CloudStorageResourceReference cloud_storage_resource_reference = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Catch-all. This should always be the last target in the list
    // because anything above it will apply first. Should only appear once in a
    // configuration. If none is specified, a default one will be added
    // automatically.
    AllOtherResources others = 100 [(google.api.field_behavior) = OPTIONAL];
  }
}

// Match file stores (e.g. buckets) using regex filters.
message FileStoreCollection {
  // The first filter containing a pattern that matches a file store will
  // be used.
  oneof pattern {
    // Optional. A collection of regular expressions to match a file store
    // against.
    FileStoreRegexes include_regexes = 1
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// A collection of regular expressions to determine what file store to match
// against.
message FileStoreRegexes {
  // Required. The group of regular expression patterns to match against one or
  // more file stores. Maximum of 100 entries. The sum of all regular
  // expression's length can't exceed 10 KiB.
  repeated FileStoreRegex patterns = 1 [(google.api.field_behavior) = REQUIRED];
}

// A pattern to match against one or more file stores.
message FileStoreRegex {
  // The type of resource regex to use.
  oneof resource_regex {
    // Optional. Regex for Cloud Storage.
    CloudStorageRegex cloud_storage_regex = 1
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// A pattern to match against one or more file stores. At least one
// pattern must be specified. Regular expressions use RE2
// [syntax](https://github.com/google/re2/wiki/Syntax); a guide can be found
// under the google/re2 repository on GitHub.
message CloudStorageRegex {
  // Optional. For organizations, if unset, will match all projects.
  string project_id_regex = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Regex to test the bucket name against. If empty, all buckets
  // match. Example: "marketing2021" or "(marketing)\d{4}" will both match the
  // bucket gs://marketing2021
  string bucket_name_regex = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Identifies a single Cloud Storage bucket.
message CloudStorageResourceReference {
  // Required. The bucket to scan.
  string bucket_name = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. If within a project-level config, then this must match the
  // config's project id.
  string project_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// How often existing buckets should have their profiles refreshed.
// New buckets are scanned as quickly as possible depending on system
// capacity.
message DiscoveryCloudStorageGenerationCadence {
  // Optional. Data changes in Cloud Storage can't trigger reprofiling. If you
  // set this field, profiles are refreshed at this frequency regardless of
  // whether the underlying buckets have changed. Defaults to never.
  DataProfileUpdateFrequency refresh_frequency = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Governs when to update data profiles when the inspection rules
  // defined by the `InspectTemplate` change.
  // If not set, changing the template will not cause a data profile to update.
  DiscoveryInspectTemplateModifiedCadence inspect_template_modified_cadence = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Requirements that must be true before a Cloud Storage bucket or object is
// scanned in discovery for the first time. There is an AND relationship between
// the top-level attributes.
message DiscoveryCloudStorageConditions {
  // The attribute of an object. See
  // https://cloud.google.com/storage/docs/storage-classes for more information
  // on storage classes.
  enum CloudStorageObjectAttribute {
    // Unused.
    CLOUD_STORAGE_OBJECT_ATTRIBUTE_UNSPECIFIED = 0;

    // Scan objects regardless of the attribute.
    ALL_SUPPORTED_OBJECTS = 1;

    // Scan objects with the standard storage class.
    STANDARD = 2;

    // Scan objects with the nearline storage class. This will incur retrieval
    // fees.
    NEARLINE = 3;

    // Scan objects with the coldline storage class. This will incur retrieval
    // fees.
    COLDLINE = 4;

    // Scan objects with the archive storage class. This will incur retrieval
    // fees.
    ARCHIVE = 5;

    // Scan objects with the regional storage class.
    REGIONAL = 6;

    // Scan objects with the multi-regional storage class.
    MULTI_REGIONAL = 7;

    // Scan objects with the dual-regional storage class. This will incur
    // retrieval fees.
    DURABLE_REDUCED_AVAILABILITY = 8;
  }

  // The attribute of a bucket.
  enum CloudStorageBucketAttribute {
    // Unused.
    CLOUD_STORAGE_BUCKET_ATTRIBUTE_UNSPECIFIED = 0;

    // Scan buckets regardless of the attribute.
    ALL_SUPPORTED_BUCKETS = 1;

    // Buckets with [Autoclass](https://cloud.google.com/storage/docs/autoclass)
    // disabled. Only one of
    // AUTOCLASS_DISABLED or AUTOCLASS_ENABLED should be set.
    AUTOCLASS_DISABLED = 2;

    // Buckets with [Autoclass](https://cloud.google.com/storage/docs/autoclass)
    // enabled. Only one of
    // AUTOCLASS_DISABLED or AUTOCLASS_ENABLED should be set. Scanning
    // Autoclass-enabled buckets can affect object storage classes.
    AUTOCLASS_ENABLED = 3;
  }

  // Required. Only objects with the specified attributes will be scanned. If an
  // object has one of the specified attributes but is inside an excluded
  // bucket, it will not be scanned. Defaults to [ALL_SUPPORTED_OBJECTS]. A
  // profile will be created even if no objects match the
  // included_object_attributes.
  repeated CloudStorageObjectAttribute included_object_attributes = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Only objects with the specified attributes will be scanned.
  // Defaults to [ALL_SUPPORTED_BUCKETS] if unset.
  repeated CloudStorageBucketAttribute included_bucket_attributes = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Requirements that must be true before a file store is scanned in discovery
// for the first time. There is an AND relationship between the top-level
// attributes.
message DiscoveryFileStoreConditions {
  // Optional. File store must have been created after this date. Used to avoid
  // backfilling.
  google.protobuf.Timestamp created_after = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Minimum age a file store must have. If set, the value must be 1
  // hour or greater.
  google.protobuf.Duration min_age = 2 [(google.api.field_behavior) = OPTIONAL];

  // File store specific conditions.
  oneof conditions {
    // Optional. Cloud Storage conditions.
    DiscoveryCloudStorageConditions cloud_storage_conditions = 3
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// Target used to match against for discovery of resources from other clouds.
// An [AWS connector in Security Command Center
// (Enterprise](https://cloud.google.com/security-command-center/docs/connect-scc-to-aws)
// is required to use this feature.
message OtherCloudDiscoveryTarget {
  // Required. The type of data profiles generated by this discovery target.
  // Supported values are:
  // * aws/s3/bucket
  DataSourceType data_source_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The resources that the discovery cadence applies to. The
  // first target with a matching filter will be the one to apply to a resource.
  DiscoveryOtherCloudFilter filter = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. In addition to matching the filter, these conditions must be true
  // before a profile is generated.
  DiscoveryOtherCloudConditions conditions = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Type of cadence.
  oneof cadence {
    // How often and when to update data profiles. New resources that match both
    // the filter and conditions are scanned as quickly as possible depending on
    // system capacity.
    DiscoveryOtherCloudGenerationCadence generation_cadence = 4;

    // Disable profiling for resources that match this filter.
    Disabled disabled = 5;
  }
}

// Determines which resources from the other cloud will have profiles generated.
// Includes the ability to filter by resource names.
message DiscoveryOtherCloudFilter {
  // Whether the filter applies to a specific set of resources or all
  // other resources. The first filter to match will be applied, regardless of
  // the condition. Defaults to `others` if none is set.
  oneof filter {
    // A collection of resources for this filter to apply to.
    OtherCloudResourceCollection collection = 1;

    // The resource to scan. Configs using this filter can only have one target
    // (the target with this single resource reference).
    OtherCloudSingleResourceReference single_resource = 2;

    // Optional. Catch-all. This should always be the last target in the list
    // because anything above it will apply first. Should only appear once in a
    // configuration. If none is specified, a default one will be added
    // automatically.
    AllOtherResources others = 100 [(google.api.field_behavior) = OPTIONAL];
  }
}

// Match resources using regex filters.
message OtherCloudResourceCollection {
  // The first filter containing a pattern that matches a resource will be used.
  oneof pattern {
    // A collection of regular expressions to match a resource against.
    OtherCloudResourceRegexes include_regexes = 1;
  }
}

// A collection of regular expressions to determine what resources to match
// against.
message OtherCloudResourceRegexes {
  // A group of regular expression patterns to match against one or more
  // resources.
  // Maximum of 100 entries. The sum of all regular expression's length can't
  // exceed 10 KiB.
  repeated OtherCloudResourceRegex patterns = 1;
}

// A pattern to match against one or more resources. At least one pattern must
// be specified. Regular expressions use RE2
// [syntax](https://github.com/google/re2/wiki/Syntax); a guide can be found
// under the google/re2 repository on GitHub.
message OtherCloudResourceRegex {
  // The type of resource regex to use.
  oneof resource_regex {
    // Regex for Amazon S3 buckets.
    AmazonS3BucketRegex amazon_s3_bucket_regex = 1;
  }
}

// AWS account regex.
message AwsAccountRegex {
  // Optional. Regex to test the AWS account ID against.
  // If empty, all accounts match.
  string account_id_regex = 1 [(google.api.field_behavior) = OPTIONAL];
}

// Amazon S3 bucket regex.
message AmazonS3BucketRegex {
  // The AWS account regex.
  AwsAccountRegex aws_account_regex = 1;

  // Optional. Regex to test the bucket name against.
  // If empty, all buckets match.
  string bucket_name_regex = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Identifies a single resource, like a single Amazon S3 bucket.
message OtherCloudSingleResourceReference {
  // The resource to scan.
  oneof resource {
    // Amazon S3 bucket.
    AmazonS3Bucket amazon_s3_bucket = 1;
  }
}

// AWS account.
message AwsAccount {
  // Required. AWS account ID.
  string account_id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Amazon S3 bucket.
message AmazonS3Bucket {
  // The AWS account.
  AwsAccount aws_account = 1;

  // Required. The bucket name.
  string bucket_name = 2 [(google.api.field_behavior) = REQUIRED];
}

// Requirements that must be true before a resource is profiled for the first
// time.
message DiscoveryOtherCloudConditions {
  // Minimum age a resource must be before Cloud DLP can profile it. Value must
  // be 1 hour or greater.
  google.protobuf.Duration min_age = 1;

  // The conditions to apply.
  oneof conditions {
    // Amazon S3 bucket conditions.
    AmazonS3BucketConditions amazon_s3_bucket_conditions = 2;
  }
}

// Amazon S3 bucket conditions.
message AmazonS3BucketConditions {
  // Supported Amazon S3 bucket types.
  // Defaults to TYPE_ALL_SUPPORTED.
  enum BucketType {
    // Unused.
    TYPE_UNSPECIFIED = 0;

    // All supported classes.
    TYPE_ALL_SUPPORTED = 1;

    // A general purpose Amazon S3 bucket.
    TYPE_GENERAL_PURPOSE = 2;
  }

  // Supported Amazon S3 object storage classes.
  // Defaults to ALL_SUPPORTED_CLASSES.
  enum ObjectStorageClass {
    // Unused.
    UNSPECIFIED = 0;

    // All supported classes.
    ALL_SUPPORTED_CLASSES = 1;

    // Standard object class.
    STANDARD = 2;

    // Standard - infrequent access object class.
    STANDARD_INFREQUENT_ACCESS = 4;

    // Glacier - instant retrieval object class.
    GLACIER_INSTANT_RETRIEVAL = 6;

    // Objects in the S3 Intelligent-Tiering access tiers.
    INTELLIGENT_TIERING = 7;
  }

  // Optional. Bucket types that should be profiled.
  // Optional. Defaults to TYPE_ALL_SUPPORTED if unspecified.
  repeated BucketType bucket_types = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Object classes that should be profiled.
  // Optional. Defaults to ALL_SUPPORTED_CLASSES if unspecified.
  repeated ObjectStorageClass object_storage_classes = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// How often existing resources should have their profiles refreshed.
// New resources are scanned as quickly as possible depending on system
// capacity.
message DiscoveryOtherCloudGenerationCadence {
  // Optional. Frequency to update profiles regardless of whether the underlying
  // resource has changes. Defaults to never.
  DataProfileUpdateFrequency refresh_frequency = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Governs when to update data profiles when the inspection rules
  // defined by the `InspectTemplate` change.
  // If not set, changing the template will not cause a data profile to update.
  DiscoveryInspectTemplateModifiedCadence inspect_template_modified_cadence = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// The location to begin a discovery scan. Denotes an organization ID or folder
// ID within an organization.
message DiscoveryStartingLocation {
  // The location to be scanned.
  oneof location {
    // The ID of an organization to scan.
    int64 organization_id = 1;

    // The ID of the folder within an organization to be scanned.
    int64 folder_id = 2;
  }
}

// The other cloud starting location for discovery.
message OtherCloudDiscoveryStartingLocation {
  // The AWS starting location for discovery.
  message AwsDiscoveryStartingLocation {
    // The scope of this starting location.
    oneof scope {
      // The AWS account ID that this discovery config applies to.
      // Within an AWS organization, you can find the AWS account ID inside an
      // AWS account ARN. Example:
      // arn:{partition}:organizations::{management_account_id}:account/{org_id}/{account_id}
      string account_id = 2;

      // All AWS assets stored in Asset Inventory that didn't match other AWS
      // discovery configs.
      bool all_asset_inventory_assets = 3;
    }
  }

  // The other cloud starting location for discovery.
  oneof location {
    // The AWS starting location for discovery.
    AwsDiscoveryStartingLocation aws_location = 1;
  }
}

// Match discovery resources not covered by any other filter.
message AllOtherResources {}

// Target used to match against for discovery with Vertex AI datasets.
message VertexDatasetDiscoveryTarget {
  // Required. The datasets the discovery cadence applies to. The first target
  // with a matching filter will be the one to apply to a dataset.
  DiscoveryVertexDatasetFilter filter = 1
      [(google.api.field_behavior) = REQUIRED];

  // In addition to matching the filter, these conditions must be true
  // before a profile is generated.
  DiscoveryVertexDatasetConditions conditions = 2;

  // Type of schedule.
  oneof cadence {
    // How often and when to update profiles. New datasets that match both the
    // filter and conditions are scanned as quickly as possible depending on
    // system capacity.
    DiscoveryVertexDatasetGenerationCadence generation_cadence = 3;

    // Disable profiling for datasets that match this filter.
    Disabled disabled = 4;
  }
}

// Determines what datasets will have profiles generated within an organization
// or project. Includes the ability to filter by regular expression patterns
// on project ID or dataset regex.
message DiscoveryVertexDatasetFilter {
  // Whether the filter applies to a specific set of datasets or all
  // other datasets within the location being profiled. The first
  // filter to match will be applied, regardless of the condition. If none is
  // set, this field defaults to `others`.
  oneof filter {
    // A specific set of Vertex AI datasets for this filter to apply to.
    VertexDatasetCollection collection = 1;

    // The dataset resource to scan. Targets including this can only include
    // one target (the target with this dataset resource reference).
    VertexDatasetResourceReference vertex_dataset_resource_reference = 2;

    // Catch-all. This should always be the last target in the list because
    // anything above it will apply first. Should only appear once in a
    // configuration. If none is specified, a default one will be added
    // automatically.
    AllOtherResources others = 100;
  }
}

// Match dataset resources using regex filters.
message VertexDatasetCollection {
  // The pattern used to filter dataset resources.
  oneof pattern {
    // The regex used to filter dataset resources.
    VertexDatasetRegexes vertex_dataset_regexes = 1;
  }
}

// A collection of regular expressions to determine what datasets to match
// against.
message VertexDatasetRegexes {
  // Required. The group of regular expression patterns to match against one or
  // more datasets. Maximum of 100 entries. The sum of the lengths of all
  // regular expressions can't exceed 10 KiB.
  repeated VertexDatasetRegex patterns = 1
      [(google.api.field_behavior) = REQUIRED];
}

// A pattern to match against one or more dataset resources.
message VertexDatasetRegex {
  // For organizations, if unset, will match all projects. Has no effect
  // for configurations created within a project.
  string project_id_regex = 1;
}

// Identifies a single Vertex AI dataset.
message VertexDatasetResourceReference {
  // Required. The name of the dataset resource. If set within a project-level
  // configuration, the specified resource must be within the project.
  string dataset_resource_name = 1 [(google.api.field_behavior) = REQUIRED];
}

// Requirements that must be true before a dataset is profiled for the
// first time.
message DiscoveryVertexDatasetConditions {
  // Vertex AI dataset must have been created after this date. Used to avoid
  // backfilling.
  google.protobuf.Timestamp created_after = 1;

  // Minimum age a Vertex AI dataset must have. If set, the value must be 1 hour
  // or greater.
  google.protobuf.Duration min_age = 2;
}

// How often existing datasets should have their profiles refreshed.
// New datasets are scanned as quickly as possible depending on system
// capacity.
message DiscoveryVertexDatasetGenerationCadence {
  // If you set this field, profiles are refreshed at this
  // frequency regardless of whether the underlying datasets have changed.
  // Defaults to never.
  DataProfileUpdateFrequency refresh_frequency = 1;

  // Governs when to update data profiles when the inspection rules
  // defined by the `InspectTemplate` change.
  // If not set, changing the template will not cause a data profile to be
  // updated.
  DiscoveryInspectTemplateModifiedCadence inspect_template_modified_cadence = 2;
}

// Combines all of the information about a DLP job.
message DlpJob {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/DlpJob"
    pattern: "projects/{project}/dlpJobs/{dlp_job}"
    pattern: "projects/{project}/locations/{location}/dlpJobs/{dlp_job}"
  };

  // Possible states of a job. New items may be added.
  enum JobState {
    // Unused.
    JOB_STATE_UNSPECIFIED = 0;

    // The job has not yet started.
    PENDING = 1;

    // The job is currently running. Once a job has finished it will transition
    // to FAILED or DONE.
    RUNNING = 2;

    // The job is no longer running.
    DONE = 3;

    // The job was canceled before it could be completed.
    CANCELED = 4;

    // The job had an error and did not complete.
    FAILED = 5;

    // The job is currently accepting findings via hybridInspect.
    // A hybrid job in ACTIVE state may continue to have findings added to it
    // through the calling of hybridInspect. After the job has finished no more
    // calls to hybridInspect may be made. ACTIVE jobs can transition to DONE.
    ACTIVE = 6;
  }

  // The server-assigned name.
  string name = 1;

  // The type of job.
  DlpJobType type = 2;

  // State of a job.
  JobState state = 3;

  // Job details.
  oneof details {
    // Results from analyzing risk of a data source.
    AnalyzeDataSourceRiskDetails risk_details = 4;

    // Results from inspecting a data source.
    InspectDataSourceDetails inspect_details = 5;
  }

  // Time when the job was created.
  google.protobuf.Timestamp create_time = 6;

  // Time when the job started.
  google.protobuf.Timestamp start_time = 7;

  // Time when the job finished.
  google.protobuf.Timestamp end_time = 8;

  // Time when the job was last modified by the system.
  google.protobuf.Timestamp last_modified = 15;

  // If created by a job trigger, the resource name of the trigger that
  // instantiated the job.
  string job_trigger_name = 10;

  // A stream of errors encountered running the job.
  repeated Error errors = 11;

  // Events that should occur after the job has completed.
  repeated ActionDetails action_details = 12;
}

// The request message for
// [GetDlpJob][google.privacy.dlp.v2.DlpService.GetDlpJob].
message GetDlpJobRequest {
  // Required. The name of the DlpJob resource.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }
  ];
}

// The request message for listing DLP jobs.
message ListDlpJobsRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on whether you have [specified a
  // processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 4 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DlpJob"
    }
  ];

  // Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values for inspect jobs:
  //     - `state` - PENDING|RUNNING|CANCELED|FINISHED|FAILED
  //     - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY
  //     - `trigger_name` - The name of the trigger that created the job.
  //     - 'end_time` - Corresponds to the time the job finished.
  //     - 'start_time` - Corresponds to the time the job finished.
  // * Supported fields for risk analysis jobs:
  //     - `state` - RUNNING|CANCELED|FINISHED|FAILED
  //     - 'end_time` - Corresponds to the time the job finished.
  //     - 'start_time` - Corresponds to the time the job finished.
  // * The operator must be `=` or `!=`.
  //
  // Examples:
  //
  // * inspected_storage = cloud_storage AND state = done
  // * inspected_storage = cloud_storage OR inspected_storage = bigquery
  // * inspected_storage = cloud_storage AND (state = done OR state = canceled)
  // * end_time > \"2017-12-12T00:00:00+00:00\"
  //
  // The length of this field should be no more than 500 characters.
  string filter = 1;

  // The standard list page size.
  int32 page_size = 2;

  // The standard list page token.
  string page_token = 3;

  // The type of job. Defaults to `DlpJobType.INSPECT`
  DlpJobType type = 5;

  // Comma-separated list of fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc, end_time asc, create_time desc`
  //
  // Supported fields are:
  //
  // - `create_time`: corresponds to the time the job was created.
  // - `end_time`: corresponds to the time the job ended.
  // - `name`: corresponds to the job's name.
  // - `state`: corresponds to `state`
  string order_by = 6;

  // Deprecated. This field has no effect.
  string location_id = 7;
}

// The response message for listing DLP jobs.
message ListDlpJobsResponse {
  // A list of DlpJobs that matches the specified filter in the request.
  repeated DlpJob jobs = 1;

  // The standard List next-page token.
  string next_page_token = 2;
}

// The request message for canceling a DLP job.
message CancelDlpJobRequest {
  // Required. The name of the DlpJob resource to be cancelled.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }
  ];
}

// The request message for finishing a DLP hybrid job.
message FinishDlpJobRequest {
  // Required. The name of the DlpJob resource to be finished.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }
  ];
}

// The request message for deleting a DLP job.
message DeleteDlpJobRequest {
  // Required. The name of the DlpJob resource to be deleted.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }
  ];
}

// Request message for CreateDeidentifyTemplate.
message CreateDeidentifyTemplateRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  // + Organizations scope, location specified:
  //   `organizations/{org_id}/locations/{location_id}`
  // + Organizations scope, no location specified (defaults to global):
  //   `organizations/{org_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DeidentifyTemplate"
    }
  ];

  // Required. The DeidentifyTemplate to create.
  DeidentifyTemplate deidentify_template = 2
      [(google.api.field_behavior) = REQUIRED];

  // The template id can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string template_id = 3;

  // Deprecated. This field has no effect.
  string location_id = 4;
}

// Request message for UpdateDeidentifyTemplate.
message UpdateDeidentifyTemplateRequest {
  // Required. Resource name of organization and deidentify template to be
  // updated, for example
  // `organizations/433245324/deidentifyTemplates/432452342` or
  // projects/project-id/deidentifyTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DeidentifyTemplate"
    }
  ];

  // New DeidentifyTemplate value.
  DeidentifyTemplate deidentify_template = 2;

  // Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for GetDeidentifyTemplate.
message GetDeidentifyTemplateRequest {
  // Required. Resource name of the organization and deidentify template to be
  // read, for example `organizations/433245324/deidentifyTemplates/432452342`
  // or projects/project-id/deidentifyTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DeidentifyTemplate"
    }
  ];
}

// Request message for ListDeidentifyTemplates.
message ListDeidentifyTemplatesRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  // + Organizations scope, location specified:
  //   `organizations/{org_id}/locations/{location_id}`
  // + Organizations scope, no location specified (defaults to global):
  //   `organizations/{org_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/DeidentifyTemplate"
    }
  ];

  // Page token to continue retrieval. Comes from the previous call
  // to `ListDeidentifyTemplates`.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc,update_time, create_time desc`
  //
  // Supported fields are:
  //
  // - `create_time`: corresponds to the time the template was created.
  // - `update_time`: corresponds to the time the template was last updated.
  // - `name`: corresponds to the template's name.
  // - `display_name`: corresponds to the template's display name.
  string order_by = 4;

  // Deprecated. This field has no effect.
  string location_id = 5;
}

// Response message for ListDeidentifyTemplates.
message ListDeidentifyTemplatesResponse {
  // List of deidentify templates, up to page_size in
  // ListDeidentifyTemplatesRequest.
  repeated DeidentifyTemplate deidentify_templates = 1;

  // If the next page is available then the next page token to be used in the
  // following ListDeidentifyTemplates request.
  string next_page_token = 2;
}

// Request message for DeleteDeidentifyTemplate.
message DeleteDeidentifyTemplateRequest {
  // Required. Resource name of the organization and deidentify template to be
  // deleted, for example
  // `organizations/433245324/deidentifyTemplates/432452342` or
  // projects/project-id/deidentifyTemplates/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/DeidentifyTemplate"
    }
  ];
}

// Configuration for a custom dictionary created from a data source of any size
// up to the maximum size defined in the
// [limits](https://cloud.google.com/sensitive-data-protection/limits) page. The
// artifacts of dictionary creation are stored in the specified Cloud Storage
// location. Consider using `CustomInfoType.Dictionary` for smaller dictionaries
// that satisfy the size requirements.
message LargeCustomDictionaryConfig {
  // Location to store dictionary artifacts in Cloud Storage. These files
  // will only be accessible by project owners and the DLP API. If any of these
  // artifacts are modified, the dictionary is considered invalid and can no
  // longer be used.
  CloudStoragePath output_path = 1;

  // Source of the dictionary.
  oneof source {
    // Set of files containing newline-delimited lists of dictionary phrases.
    CloudStorageFileSet cloud_storage_file_set = 2;

    // Field in a BigQuery table where each cell represents a dictionary phrase.
    BigQueryField big_query_field = 3;
  }
}

// Summary statistics of a custom dictionary.
message LargeCustomDictionaryStats {
  // Approximate number of distinct phrases in the dictionary.
  int64 approx_num_phrases = 1;
}

// Configuration for stored infoTypes. All fields and subfield are provided
// by the user. For more information, see
// https://cloud.google.com/sensitive-data-protection/docs/creating-custom-infotypes.
message StoredInfoTypeConfig {
  // Display name of the StoredInfoType (max 256 characters).
  string display_name = 1;

  // Description of the StoredInfoType (max 256 characters).
  string description = 2;

  // Stored infotype types.
  oneof type {
    // StoredInfoType where findings are defined by a dictionary of phrases.
    LargeCustomDictionaryConfig large_custom_dictionary = 3;

    // Store dictionary-based CustomInfoType.
    CustomInfoType.Dictionary dictionary = 4;

    // Store regular expression-based StoredInfoType.
    CustomInfoType.Regex regex = 5;
  }
}

// Statistics for a StoredInfoType.
message StoredInfoTypeStats {
  // Stat types
  oneof type {
    // StoredInfoType where findings are defined by a dictionary of phrases.
    LargeCustomDictionaryStats large_custom_dictionary = 1;
  }
}

// Version of a StoredInfoType, including the configuration used to build it,
// create timestamp, and current state.
message StoredInfoTypeVersion {
  // StoredInfoType configuration.
  StoredInfoTypeConfig config = 1;

  // Create timestamp of the version. Read-only, determined by the system
  // when the version is created.
  google.protobuf.Timestamp create_time = 2;

  // Stored info type version state. Read-only, updated by the system
  // during dictionary creation.
  StoredInfoTypeState state = 3;

  // Errors that occurred when creating this storedInfoType version, or
  // anomalies detected in the storedInfoType data that render it unusable. Only
  // the five most recent errors will be displayed, with the most recent error
  // appearing first.
  //
  // For example, some of the data for stored custom dictionaries is put in
  // the user's Cloud Storage bucket, and if this data is modified or
  // deleted by the user or another system, the dictionary becomes invalid.
  //
  // If any errors occur, fix the problem indicated by the error message and
  // use the UpdateStoredInfoType API method to create another version of the
  // storedInfoType to continue using it, reusing the same `config` if it was
  // not the source of the error.
  repeated Error errors = 4;

  // Statistics about this storedInfoType version.
  StoredInfoTypeStats stats = 5;
}

// StoredInfoType resource message that contains information about the current
// version and any pending updates.
message StoredInfoType {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/StoredInfoType"
    pattern: "organizations/{organization}/storedInfoTypes/{stored_info_type}"
    pattern: "projects/{project}/storedInfoTypes/{stored_info_type}"
    pattern: "organizations/{organization}/locations/{location}/storedInfoTypes/{stored_info_type}"
    pattern: "projects/{project}/locations/{location}/storedInfoTypes/{stored_info_type}"
  };

  // Resource name.
  string name = 1;

  // Current version of the stored info type.
  StoredInfoTypeVersion current_version = 2;

  // Pending versions of the stored info type. Empty if no versions are
  // pending.
  repeated StoredInfoTypeVersion pending_versions = 3;
}

// Request message for CreateStoredInfoType.
message CreateStoredInfoTypeRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  // + Organizations scope, location specified:
  //   `organizations/{org_id}/locations/{location_id}`
  // + Organizations scope, no location specified (defaults to global):
  //   `organizations/{org_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/StoredInfoType"
    }
  ];

  // Required. Configuration of the storedInfoType to create.
  StoredInfoTypeConfig config = 2 [(google.api.field_behavior) = REQUIRED];

  // The storedInfoType ID can contain uppercase and lowercase letters,
  // numbers, and hyphens; that is, it must match the regular
  // expression: `[a-zA-Z\d-_]+`. The maximum length is 100
  // characters. Can be empty to allow the system to generate one.
  string stored_info_type_id = 3;

  // Deprecated. This field has no effect.
  string location_id = 4;
}

// Request message for UpdateStoredInfoType.
message UpdateStoredInfoTypeRequest {
  // Required. Resource name of organization and storedInfoType to be updated,
  // for example `organizations/433245324/storedInfoTypes/432452342` or
  // projects/project-id/storedInfoTypes/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/StoredInfoType"
    }
  ];

  // Updated configuration for the storedInfoType. If not provided, a new
  // version of the storedInfoType will be created with the existing
  // configuration.
  StoredInfoTypeConfig config = 2;

  // Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3;
}

// Request message for GetStoredInfoType.
message GetStoredInfoTypeRequest {
  // Required. Resource name of the organization and storedInfoType to be read,
  // for example `organizations/433245324/storedInfoTypes/432452342` or
  // projects/project-id/storedInfoTypes/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/StoredInfoType"
    }
  ];
}

// Request message for ListStoredInfoTypes.
message ListStoredInfoTypesRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization) and whether you have [specified a processing
  // location](https://cloud.google.com/sensitive-data-protection/docs/specifying-location):
  //
  // + Projects scope, location specified:
  //   `projects/{project_id}/locations/{location_id}`
  // + Projects scope, no location specified (defaults to global):
  //   `projects/{project_id}`
  //
  // The following example `parent` string specifies a parent project with the
  // identifier `example-project`, and specifies the `europe-west3` location
  // for processing data:
  //
  //     parent=projects/example-project/locations/europe-west3
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/StoredInfoType"
    }
  ];

  // Page token to continue retrieval. Comes from the previous call
  // to `ListStoredInfoTypes`.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by,
  // followed by `asc` or `desc` postfix. This list is case insensitive. The
  // default sorting order is ascending. Redundant space characters are
  // insignificant.
  //
  // Example: `name asc, display_name, create_time desc`
  //
  // Supported fields are:
  //
  // - `create_time`: corresponds to the time the most recent version of the
  // resource was created.
  // - `state`: corresponds to the state of the resource.
  // - `name`: corresponds to resource name.
  // - `display_name`: corresponds to info type's display name.
  string order_by = 4;

  // Deprecated. This field has no effect.
  string location_id = 5;
}

// Response message for ListStoredInfoTypes.
message ListStoredInfoTypesResponse {
  // List of storedInfoTypes, up to page_size in ListStoredInfoTypesRequest.
  repeated StoredInfoType stored_info_types = 1;

  // If the next page is available then the next page token to be used
  // in the following ListStoredInfoTypes request.
  string next_page_token = 2;
}

// Request message for DeleteStoredInfoType.
message DeleteStoredInfoTypeRequest {
  // Required. Resource name of the organization and storedInfoType to be
  // deleted, for example `organizations/433245324/storedInfoTypes/432452342` or
  // projects/project-id/storedInfoTypes/432452342.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/StoredInfoType"
    }
  ];
}

// Request to search for potentially sensitive info in a custom location.
message HybridInspectJobTriggerRequest {
  // Required. Resource name of the trigger to execute a hybrid inspect on, for
  // example `projects/dlp-test-project/jobTriggers/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/JobTrigger" }
  ];

  // The item to inspect.
  HybridContentItem hybrid_item = 3;
}

// Request to search for potentially sensitive info in a custom location.
message HybridInspectDlpJobRequest {
  // Required. Resource name of the job to execute a hybrid inspect on, for
  // example `projects/dlp-test-project/dlpJob/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/DlpJob" }
  ];

  // The item to inspect.
  HybridContentItem hybrid_item = 3;
}

// An individual hybrid item to inspect. Will be stored temporarily during
// processing.
message HybridContentItem {
  // The item to inspect.
  ContentItem item = 1;

  // Supplementary information that will be added to each finding.
  HybridFindingDetails finding_details = 2;
}

// Populate to associate additional data with each finding.
message HybridFindingDetails {
  // Details about the container where the content being inspected is from.
  Container container_details = 1;

  // Offset in bytes of the line, from the beginning of the file, where the
  // finding  is located. Populate if the item being scanned is only part of a
  // bigger item, such as a shard of a file and you want to track the absolute
  // position of the finding.
  int64 file_offset = 2;

  // Offset of the row for tables. Populate if the row(s) being scanned are
  // part of a bigger dataset and you want to keep track of their absolute
  // position.
  int64 row_offset = 3;

  // If the container is a table, additional information to make findings
  // meaningful such as the columns that are primary keys. If not known ahead
  // of time, can also be set within each inspect hybrid call and the two
  // will be merged. Note that identifying_fields will only be stored to
  // BigQuery, and only if the BigQuery action has been included.
  TableOptions table_options = 4;

  // Labels to represent user provided metadata about the data being inspected.
  // If configured by the job, some key values may be required.
  // The labels associated with `Finding`'s produced by hybrid
  // inspection.
  //
  // Label keys must be between 1 and 63 characters long and must conform
  // to the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`.
  //
  // Label values must be between 0 and 63 characters long and must conform
  // to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`.
  //
  // No more than 10 labels can be associated with a given finding.
  //
  // Examples:
  //
  // * `"environment" : "production"`
  // * `"pipeline" : "etl"`
  map<string, string> labels = 5;
}

// Quota exceeded errors will be thrown once quota has been met.
message HybridInspectResponse {}

// Operators available for comparing the value of fields.
enum RelationalOperator {
  // Unused
  RELATIONAL_OPERATOR_UNSPECIFIED = 0;

  // Equal. Attempts to match even with incompatible types.
  EQUAL_TO = 1;

  // Not equal to. Attempts to match even with incompatible types.
  NOT_EQUAL_TO = 2;

  // Greater than.
  GREATER_THAN = 3;

  // Less than.
  LESS_THAN = 4;

  // Greater than or equals.
  GREATER_THAN_OR_EQUALS = 5;

  // Less than or equals.
  LESS_THAN_OR_EQUALS = 6;

  // Exists
  EXISTS = 7;
}

// Type of the match which can be applied to different ways of matching, like
// Dictionary, regular expression and intersecting with findings of another
// info type.
enum MatchingType {
  // Invalid.
  MATCHING_TYPE_UNSPECIFIED = 0;

  // Full match.
  //
  // - Dictionary: join of Dictionary results matched complete finding quote
  // - Regex: all regex matches fill a finding quote start to end
  // - Exclude info type: completely inside affecting info types findings
  MATCHING_TYPE_FULL_MATCH = 1;

  // Partial match.
  //
  // - Dictionary: at least one of the tokens in the finding matches
  // - Regex: substring of the finding matches
  // - Exclude info type: intersects with affecting info types findings
  MATCHING_TYPE_PARTIAL_MATCH = 2;

  // Inverse match.
  //
  // - Dictionary: no tokens in the finding match the dictionary
  // - Regex: finding doesn't match the regex
  // - Exclude info type: no intersection with affecting info types findings
  MATCHING_TYPE_INVERSE_MATCH = 3;
}

// Deprecated and unused.
enum ContentOption {
  // Includes entire content of a file or a data stream.
  CONTENT_UNSPECIFIED = 0;

  // Text content within the data, excluding any metadata.
  CONTENT_TEXT = 1;

  // Images found in the data.
  CONTENT_IMAGE = 2;
}

// Type of metadata containing the finding.
enum MetadataType {
  // Unused
  METADATATYPE_UNSPECIFIED = 0;

  // General file metadata provided by Cloud Storage.
  STORAGE_METADATA = 2;
}

// Parts of the APIs which use certain infoTypes.
enum InfoTypeSupportedBy {
  // Unused.
  ENUM_TYPE_UNSPECIFIED = 0;

  // Supported by the inspect operations.
  INSPECT = 1;

  // Supported by the risk analysis operations.
  RISK_ANALYSIS = 2;
}

// An enum to represent the various types of DLP jobs.
enum DlpJobType {
  // Defaults to INSPECT_JOB.
  DLP_JOB_TYPE_UNSPECIFIED = 0;

  // The job inspected Google Cloud for sensitive data.
  INSPECT_JOB = 1;

  // The job executed a Risk Analysis computation.
  RISK_ANALYSIS_JOB = 2;
}

// State of a StoredInfoType version.
enum StoredInfoTypeState {
  // Unused
  STORED_INFO_TYPE_STATE_UNSPECIFIED = 0;

  // StoredInfoType version is being created.
  PENDING = 1;

  // StoredInfoType version is ready for use.
  READY = 2;

  // StoredInfoType creation failed. All relevant error messages are returned in
  // the `StoredInfoTypeVersion` message.
  FAILED = 3;

  // StoredInfoType is no longer valid because artifacts stored in
  // user-controlled storage were modified. To fix an invalid StoredInfoType,
  // use the `UpdateStoredInfoType` method to create a new version.
  INVALID = 4;
}

// Request to list the profiles generated for a given organization or project.
message ListProjectDataProfilesRequest {
  // Required. organizations/{org_id}/locations/{loc_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/ProjectDataProfile"
    }
  ];

  // Page token to continue retrieval.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero, server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by, followed by `asc` or `desc`
  // postfix. This list is case insensitive. The default sorting order is
  // ascending. Redundant space characters are insignificant. Only one order
  // field at a time is allowed.
  //
  // Examples:
  // * `project_id`
  // * `sensitivity_level desc`
  //
  // Supported fields are:
  //
  // - `project_id`: Google Cloud project ID
  // - `sensitivity_level`: How sensitive the data in a project is, at most.
  // - `data_risk_level`: How much risk is associated with this data.
  // - `profile_last_generated`: When the profile was last updated in epoch
  // seconds.
  string order_by = 4;

  // Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values:
  //     - `sensitivity_level` - HIGH|MODERATE|LOW
  //     - `data_risk_level` - HIGH|MODERATE|LOW
  //     - `status_code` - an RPC status code as defined in
  //     https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
  // * The operator must be `=` or `!=`.
  //
  // Examples:
  //
  // * `project_id = 12345 AND status_code = 1`
  // * `project_id = 12345 AND sensitivity_level = HIGH`
  //
  // The length of this field should be no more than 500 characters.
  string filter = 5;
}

// List of profiles generated for a given organization or project.
message ListProjectDataProfilesResponse {
  // List of data profiles.
  repeated ProjectDataProfile project_data_profiles = 1;

  // The next page token.
  string next_page_token = 2;
}

// Request to list the profiles generated for a given organization or project.
message ListTableDataProfilesRequest {
  // Required. Resource name of the organization or project, for
  // example `organizations/433245324/locations/europe` or
  // `projects/project-id/locations/asia`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/TableDataProfile"
    }
  ];

  // Page token to continue retrieval.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero, server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by, followed by `asc` or `desc`
  // postfix. This list is case insensitive. The default sorting order is
  // ascending. Redundant space characters are insignificant. Only one order
  // field at a time is allowed.
  //
  // Examples:
  // * `project_id asc`
  // * `table_id`
  // * `sensitivity_level desc`
  //
  // Supported fields are:
  //
  // - `project_id`: The Google Cloud project ID.
  // - `dataset_id`: The ID of a BigQuery dataset.
  // - `table_id`: The ID of a BigQuery table.
  // - `sensitivity_level`: How sensitive the data in a table is, at most.
  // - `data_risk_level`: How much risk is associated with this data.
  // - `profile_last_generated`: When the profile was last updated in epoch
  // seconds.
  // - `last_modified`: The last time the resource was modified.
  // - `resource_visibility`: Visibility restriction for this resource.
  // - `row_count`: Number of rows in this resource.
  string order_by = 4;

  // Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values:
  //     - `project_id` - The Google Cloud project ID.
  //     - `dataset_id` - The BigQuery dataset ID.
  //     - `table_id` - The ID of the BigQuery table.
  //     - `sensitivity_level` - HIGH|MODERATE|LOW
  //     - `data_risk_level` - HIGH|MODERATE|LOW
  //     - `resource_visibility`: PUBLIC|RESTRICTED
  //     - `status_code` - an RPC status code as defined in
  //     https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
  // * The operator must be `=` or `!=`.
  //
  // Examples:
  //
  // * `project_id = 12345 AND status_code = 1`
  // * `project_id = 12345 AND sensitivity_level = HIGH`
  // * `project_id = 12345 AND resource_visibility = PUBLIC`
  //
  // The length of this field should be no more than 500 characters.
  string filter = 5;
}

// List of profiles generated for a given organization or project.
message ListTableDataProfilesResponse {
  // List of data profiles.
  repeated TableDataProfile table_data_profiles = 1;

  // The next page token.
  string next_page_token = 2;
}

// Request to list the profiles generated for a given organization or project.
message ListColumnDataProfilesRequest {
  // Required. Resource name of the organization or project, for
  // example `organizations/433245324/locations/europe` or
  // `projects/project-id/locations/asia`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/ColumnDataProfile"
    }
  ];

  // Page token to continue retrieval.
  string page_token = 2;

  // Size of the page. This value can be limited by the server. If zero, server
  // returns a page of max size 100.
  int32 page_size = 3;

  // Comma-separated list of fields to order by, followed by `asc` or `desc`
  // postfix. This list is case insensitive. The default sorting order is
  // ascending. Redundant space characters are insignificant. Only one order
  // field at a time is allowed.
  //
  // Examples:
  //
  // * `project_id asc`
  // * `table_id`
  // * `sensitivity_level desc`
  //
  // Supported fields are:
  //
  // - `project_id`: The Google Cloud project ID.
  // - `dataset_id`: The ID of a BigQuery dataset.
  // - `table_id`: The ID of a BigQuery table.
  // - `sensitivity_level`: How sensitive the data in a column is, at most.
  // - `data_risk_level`: How much risk is associated with this data.
  // - `profile_last_generated`: When the profile was last updated in epoch
  // seconds.
  string order_by = 4;

  // Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values:
  //     - `table_data_profile_name` - The name of the related table data
  //     profile.
  //     - `project_id` - The Google Cloud project ID. (REQUIRED)
  //     - `dataset_id` - The BigQuery dataset ID. (REQUIRED)
  //     - `table_id` - The BigQuery table ID. (REQUIRED)
  //     - `field_id` - The ID of the BigQuery field.
  //     - `info_type` - The infotype detected in the resource.
  //     - `sensitivity_level` - HIGH|MEDIUM|LOW
  //     - `data_risk_level`: How much risk is associated with this data.
  //     - `status_code` - an RPC status code as defined in
  //     https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
  // * The operator must be `=` for project_id, dataset_id, and table_id. Other
  //   filters also support `!=`.
  //
  // Examples:
  //
  // * project_id = 12345 AND status_code = 1
  // * project_id = 12345 AND sensitivity_level = HIGH
  // * project_id = 12345 AND info_type = STREET_ADDRESS
  //
  // The length of this field should be no more than 500 characters.
  string filter = 5;
}

// List of profiles generated for a given organization or project.
message ListColumnDataProfilesResponse {
  // List of data profiles.
  repeated ColumnDataProfile column_data_profiles = 1;

  // The next page token.
  string next_page_token = 2;
}

// Score is a summary of all elements in the data profile.
// A higher number means more risk.
message DataRiskLevel {
  // Various score levels for resources.
  enum DataRiskLevelScore {
    // Unused.
    RISK_SCORE_UNSPECIFIED = 0;

    // Low risk - Lower indication of sensitive data that appears to have
    // additional access restrictions in place or no indication of sensitive
    // data found.
    RISK_LOW = 10;

    // Unable to determine risk.
    RISK_UNKNOWN = 12;

    // Medium risk - Sensitive data may be present but additional access or fine
    // grain access restrictions appear to be present.  Consider limiting
    // access even further or transform data to mask.
    RISK_MODERATE = 20;

    // High risk – SPII may be present. Access controls may include public
    // ACLs. Exfiltration of data may lead to user data loss. Re-identification
    // of users may be possible. Consider limiting usage and or removing SPII.
    RISK_HIGH = 30;
  }

  // The score applied to the resource.
  DataRiskLevelScore score = 1;
}

// An aggregated profile for this project, based on the resources profiled
// within it.
message ProjectDataProfile {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/ProjectDataProfile"
    pattern: "organizations/{organization}/locations/{location}/projectDataProfiles/{project_data_profile}"
    pattern: "projects/{project}/locations/{location}/projectDataProfiles/{project_data_profile}"
  };

  // The resource name of the profile.
  string name = 1;

  // Project ID or account that was profiled.
  string project_id = 2;

  // The last time the profile was generated.
  google.protobuf.Timestamp profile_last_generated = 3;

  // The sensitivity score of this project.
  SensitivityScore sensitivity_score = 4;

  // The data risk level of this project.
  DataRiskLevel data_risk_level = 5;

  // Success or error status of the last attempt to profile the project.
  ProfileStatus profile_status = 7;

  // The number of table data profiles generated for this project.
  int64 table_data_profile_count = 9;

  // The number of file store data profiles generated for this project.
  int64 file_store_data_profile_count = 10;
}

// How broadly the data in the resource has been shared. New items may be added
// over time. A higher number means more restricted.
enum ResourceVisibility {
  // Unused.
  RESOURCE_VISIBILITY_UNSPECIFIED = 0;

  // Visible to any user.
  RESOURCE_VISIBILITY_PUBLIC = 10;

  // May contain public items.
  // For example, if a Cloud Storage bucket has uniform bucket level access
  // disabled, some objects inside it may be public, but none are known yet.
  RESOURCE_VISIBILITY_INCONCLUSIVE = 15;

  // Visible only to specific users.
  RESOURCE_VISIBILITY_RESTRICTED = 20;
}

// Snapshot of the configurations used to generate the profile.
message DataProfileConfigSnapshot {
  // A copy of the inspection config used to generate this profile. This
  // is a copy of the inspect_template specified in `DataProfileJobConfig`.
  InspectConfig inspect_config = 2;

  // A copy of the configuration used to generate this profile. This is
  // deprecated, and the DiscoveryConfig field is preferred moving forward.
  // DataProfileJobConfig will still be written here for Discovery in BigQuery
  // for backwards compatibility, but will not be updated with new fields, while
  // DiscoveryConfig will.
  DataProfileJobConfig data_profile_job = 3 [deprecated = true];

  // A copy of the configuration used to generate this profile.
  DiscoveryConfig discovery_config = 4;

  // Name of the inspection template used to generate this profile
  string inspect_template_name = 5;

  // Timestamp when the template was modified
  google.protobuf.Timestamp inspect_template_modified_time = 6;
}

// The profile for a scanned table.
message TableDataProfile {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/TableDataProfile"
    pattern: "organizations/{organization}/locations/{location}/tableDataProfiles/{table_data_profile}"
    pattern: "projects/{project}/locations/{location}/tableDataProfiles/{table_data_profile}"
  };

  // Possible states of a profile. New items may be added.
  enum State {
    // Unused.
    STATE_UNSPECIFIED = 0;

    // The profile is currently running. Once a profile has finished it will
    // transition to DONE.
    RUNNING = 1;

    // The profile is no longer generating.
    // If profile_status.status.code is 0, the profile succeeded, otherwise, it
    // failed.
    DONE = 2;
  }

  // The name of the profile.
  string name = 1;

  // The resource type that was profiled.
  DataSourceType data_source_type = 36;

  // The resource name of the project data profile for this table.
  string project_data_profile = 2;

  // The Google Cloud project ID that owns the resource.
  string dataset_project_id = 24;

  // If supported, the location where the dataset's data is stored.
  // See https://cloud.google.com/bigquery/docs/locations for supported
  // locations.
  string dataset_location = 29;

  // If the resource is BigQuery, the dataset ID.
  string dataset_id = 25;

  // The table ID.
  string table_id = 26;

  // The Cloud Asset Inventory resource that was profiled in order to generate
  // this TableDataProfile.
  // https://cloud.google.com/apis/design/resource_names#full_resource_name
  string full_resource = 3;

  // Success or error status from the most recent profile generation attempt.
  // May be empty if the profile is still being generated.
  ProfileStatus profile_status = 21;

  // State of a profile.
  State state = 22;

  // The sensitivity score of this table.
  SensitivityScore sensitivity_score = 5;

  // The data risk level of this table.
  DataRiskLevel data_risk_level = 6;

  // The infoTypes predicted from this table's data.
  repeated InfoTypeSummary predicted_info_types = 27;

  // Other infoTypes found in this table's data.
  repeated OtherInfoTypeSummary other_info_types = 28;

  // The snapshot of the configurations used to generate the profile.
  DataProfileConfigSnapshot config_snapshot = 7;

  // The time when this table was last modified
  google.protobuf.Timestamp last_modified_time = 8;

  // Optional. The time when this table expires.
  google.protobuf.Timestamp expiration_time = 9;

  // The number of columns profiled in the table.
  int64 scanned_column_count = 10;

  // The number of columns skipped in the table because of an error.
  int64 failed_column_count = 11;

  // The size of the table when the profile was generated.
  int64 table_size_bytes = 12;

  // Number of rows in the table when the profile was generated.
  // This will not be populated for BigLake tables.
  int64 row_count = 13;

  // How the table is encrypted.
  EncryptionStatus encryption_status = 14;

  // How broadly a resource has been shared.
  ResourceVisibility resource_visibility = 15;

  // The last time the profile was generated.
  google.protobuf.Timestamp profile_last_generated = 16;

  // The labels applied to the resource at the time the profile was generated.
  map<string, string> resource_labels = 17;

  // The time at which the table was created.
  google.protobuf.Timestamp create_time = 23;

  // The BigQuery table to which the sample findings are written.
  BigQueryTable sample_findings_table = 37;

  // The tags attached to the table, including any tags attached during
  // profiling. Because tags are attached to Cloud SQL instances rather than
  // Cloud SQL tables, this field is empty for Cloud SQL table profiles.
  repeated Tag tags = 39;

  // Resources related to this profile.
  repeated RelatedResource related_resources = 41;
}

// Success or errors for the profile generation.
message ProfileStatus {
  // Profiling status code and optional message. The `status.code` value is 0
  // (default value) for OK.
  google.rpc.Status status = 1;

  // Time when the profile generation status was updated
  google.protobuf.Timestamp timestamp = 3;
}

// How a resource is encrypted.
enum EncryptionStatus {
  // Unused.
  ENCRYPTION_STATUS_UNSPECIFIED = 0;

  // Google manages server-side encryption keys on your behalf.
  ENCRYPTION_GOOGLE_MANAGED = 1;

  // Customer provides the key.
  ENCRYPTION_CUSTOMER_MANAGED = 2;
}

// The infoType details for this column.
message InfoTypeSummary {
  // The infoType.
  InfoType info_type = 1;

  // Not populated for predicted infotypes.
  int32 estimated_prevalence = 2 [deprecated = true];
}

// Infotype details for other infoTypes found within a column.
message OtherInfoTypeSummary {
  // The other infoType.
  InfoType info_type = 1;

  // Approximate percentage of non-null rows that contained data detected by
  // this infotype.
  int32 estimated_prevalence = 2;

  // Whether this infoType was excluded from sensitivity and risk analysis due
  // to factors such as low prevalence (subject to change).
  bool excluded_from_analysis = 3;
}

// Bucketized nullness percentage levels. A higher level means a higher
// percentage of the column is null.
enum NullPercentageLevel {
  // Unused.
  NULL_PERCENTAGE_LEVEL_UNSPECIFIED = 0;

  // Very few null entries.
  NULL_PERCENTAGE_VERY_LOW = 1;

  // Some null entries.
  NULL_PERCENTAGE_LOW = 2;

  // A few null entries.
  NULL_PERCENTAGE_MEDIUM = 3;

  // A lot of null entries.
  NULL_PERCENTAGE_HIGH = 4;
}

// Bucketized uniqueness score levels. A higher uniqueness score is a strong
// signal that the column may contain a unique identifier like user id. A low
// value indicates that the column contains few unique values like booleans or
// other classifiers.
enum UniquenessScoreLevel {
  // Some columns do not have estimated uniqueness. Possible reasons include
  // having too few values.
  UNIQUENESS_SCORE_LEVEL_UNSPECIFIED = 0;

  // Low uniqueness, possibly a boolean, enum or similiarly typed column.
  UNIQUENESS_SCORE_LOW = 1;

  // Medium uniqueness.
  UNIQUENESS_SCORE_MEDIUM = 2;

  // High uniqueness, possibly a column of free text or unique identifiers.
  UNIQUENESS_SCORE_HIGH = 3;
}

// The profile for a scanned column within a table.
message ColumnDataProfile {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/ColumnDataProfile"
    pattern: "organizations/{organization}/locations/{location}/columnDataProfiles/{column_data_profile}"
    pattern: "projects/{project}/locations/{location}/columnDataProfiles/{column_data_profile}"
  };

  // Possible states of a profile. New items may be added.
  enum State {
    // Unused.
    STATE_UNSPECIFIED = 0;

    // The profile is currently running. Once a profile has finished it will
    // transition to DONE.
    RUNNING = 1;

    // The profile is no longer generating.
    // If profile_status.status.code is 0, the profile succeeded, otherwise, it
    // failed.
    DONE = 2;
  }

  // Data types of the data in a column. Types may be added over time.
  enum ColumnDataType {
    // Invalid type.
    COLUMN_DATA_TYPE_UNSPECIFIED = 0;

    // Encoded as a string in decimal format.
    TYPE_INT64 = 1;

    // Encoded as a boolean "false" or "true".
    TYPE_BOOL = 2;

    // Encoded as a number, or string "NaN", "Infinity" or "-Infinity".
    TYPE_FLOAT64 = 3;

    // Encoded as a string value.
    TYPE_STRING = 4;

    // Encoded as a base64 string per RFC 4648, section 4.
    TYPE_BYTES = 5;

    // Encoded as an RFC 3339 timestamp with mandatory "Z" time zone string:
    // 1985-04-12T23:20:50.52Z
    TYPE_TIMESTAMP = 6;

    // Encoded as RFC 3339 full-date format string: 1985-04-12
    TYPE_DATE = 7;

    // Encoded as RFC 3339 partial-time format string: 23:20:50.52
    TYPE_TIME = 8;

    // Encoded as RFC 3339 full-date "T" partial-time: 1985-04-12T23:20:50.52
    TYPE_DATETIME = 9;

    // Encoded as WKT
    TYPE_GEOGRAPHY = 10;

    // Encoded as a decimal string.
    TYPE_NUMERIC = 11;

    // Container of ordered fields, each with a type and field name.
    TYPE_RECORD = 12;

    // Decimal type.
    TYPE_BIGNUMERIC = 13;

    // Json type.
    TYPE_JSON = 14;

    // Interval type.
    TYPE_INTERVAL = 15;

    // `Range<Date>` type.
    TYPE_RANGE_DATE = 16;

    // `Range<Datetime>` type.
    TYPE_RANGE_DATETIME = 17;

    // `Range<Timestamp>` type.
    TYPE_RANGE_TIMESTAMP = 18;
  }

  // The possible policy states for a column.
  enum ColumnPolicyState {
    // No policy tags.
    COLUMN_POLICY_STATE_UNSPECIFIED = 0;

    // Column has policy tag applied.
    COLUMN_POLICY_TAGGED = 1;
  }

  // The name of the profile.
  string name = 1;

  // Success or error status from the most recent profile generation attempt.
  // May be empty if the profile is still being generated.
  ProfileStatus profile_status = 17;

  // State of a profile.
  State state = 18;

  // The last time the profile was generated.
  google.protobuf.Timestamp profile_last_generated = 3;

  // The resource name of the table data profile.
  string table_data_profile = 4;

  // The resource name of the resource this column is within.
  string table_full_resource = 5;

  // The Google Cloud project ID that owns the profiled resource.
  string dataset_project_id = 19;

  // If supported, the location where the dataset's data is stored.
  // See https://cloud.google.com/bigquery/docs/locations for supported
  // BigQuery locations.
  string dataset_location = 20;

  // The BigQuery dataset ID, if the resource profiled is a BigQuery table.
  string dataset_id = 21;

  // The table ID.
  string table_id = 22;

  // The name of the column.
  string column = 6;

  // The sensitivity of this column.
  SensitivityScore sensitivity_score = 7;

  // The data risk level for this column.
  DataRiskLevel data_risk_level = 8;

  // If it's been determined this column can be identified as a single type,
  // this will be set. Otherwise the column either has unidentifiable content
  // or mixed types.
  InfoTypeSummary column_info_type = 9;

  // Other types found within this column. List will be unordered.
  repeated OtherInfoTypeSummary other_matches = 10;

  // Approximate percentage of entries being null in the column.
  NullPercentageLevel estimated_null_percentage = 23;

  // Approximate uniqueness of the column.
  UniquenessScoreLevel estimated_uniqueness_score = 24;

  // The likelihood that this column contains free-form text.
  // A value close to 1 may indicate the column is likely to contain
  // free-form or natural language text.
  // Range in 0-1.
  double free_text_score = 13;

  // The data type of a given column.
  ColumnDataType column_type = 14;

  // Indicates if a policy tag has been applied to the column.
  ColumnPolicyState policy_state = 15;
}

// The profile for a file store.
//
// * Cloud Storage: maps 1:1 with a bucket.
// * Amazon S3: maps 1:1 with a bucket.
message FileStoreDataProfile {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/FileStoreDataProfile"
    pattern: "organizations/{organization}/locations/{location}/fileStoreDataProfiles/{file_store_data_profile}"
    pattern: "projects/{project}/locations/{location}/fileStoreDataProfiles/{file_store_data_profile}"
  };

  // Possible states of a profile. New items may be added.
  enum State {
    // Unused.
    STATE_UNSPECIFIED = 0;

    // The profile is currently running. Once a profile has finished it will
    // transition to DONE.
    RUNNING = 1;

    // The profile is no longer generating.
    // If profile_status.status.code is 0, the profile succeeded, otherwise, it
    // failed.
    DONE = 2;
  }

  // The name of the profile.
  string name = 1;

  // The resource type that was profiled.
  DataSourceType data_source_type = 2;

  // The resource name of the project data profile for this file store.
  string project_data_profile = 3;

  // The Google Cloud project ID that owns the resource.
  // For Amazon S3 buckets, this is the AWS Account Id.
  string project_id = 4;

  // The location of the file store.
  //
  // * Cloud Storage:
  // https://cloud.google.com/storage/docs/locations#available-locations
  // * Amazon S3:
  // https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints
  string file_store_location = 5;

  // For resources that have multiple storage locations, these are those
  // regions. For Cloud Storage this is the list of regions chosen for
  // dual-region storage. `file_store_location` will normally be the
  // corresponding multi-region for the list of individual locations. The first
  // region is always picked as the processing and storage location for the data
  // profile.
  repeated string data_storage_locations = 19;

  // The location type of the file store (region, dual-region, multi-region,
  // etc). If dual-region, expect data_storage_locations to be populated.
  string location_type = 20;

  // The file store path.
  //
  // * Cloud Storage: `gs://{bucket}`
  // * Amazon S3: `s3://{bucket}`
  // * Vertex AI dataset:
  // `projects/{project_number}/locations/{location}/datasets/{dataset_id}`
  string file_store_path = 6;

  // The resource name of the resource profiled.
  // https://cloud.google.com/apis/design/resource_names#full_resource_name
  //
  // Example format of an S3 bucket full resource name:
  // `//cloudasset.googleapis.com/organizations/{org_id}/otherCloudConnections/aws/arn:aws:s3:::{bucket_name}`
  string full_resource = 24;

  // The snapshot of the configurations used to generate the profile.
  DataProfileConfigSnapshot config_snapshot = 7;

  // Success or error status from the most recent profile generation attempt.
  // May be empty if the profile is still being generated.
  ProfileStatus profile_status = 8;

  // State of a profile.
  State state = 9;

  // The last time the profile was generated.
  google.protobuf.Timestamp profile_last_generated = 10;

  // How broadly a resource has been shared.
  ResourceVisibility resource_visibility = 11;

  // The sensitivity score of this resource.
  SensitivityScore sensitivity_score = 12;

  // The data risk level of this resource.
  DataRiskLevel data_risk_level = 13;

  // The time the file store was first created.
  google.protobuf.Timestamp create_time = 14;

  // The time the file store was last modified.
  google.protobuf.Timestamp last_modified_time = 15;

  // FileClusterSummary per each cluster.
  repeated FileClusterSummary file_cluster_summaries = 16;

  // Attributes of the resource being profiled.
  // Currently used attributes:
  //
  // * customer_managed_encryption: boolean
  //     - true: the resource is encrypted with a customer-managed key.
  //     - false: the resource is encrypted with a provider-managed key.
  map<string, Value> resource_attributes = 17;

  // The labels applied to the resource at the time the profile was generated.
  map<string, string> resource_labels = 18;

  // InfoTypes detected in this file store.
  repeated FileStoreInfoTypeSummary file_store_info_type_summaries = 21;

  // The BigQuery table to which the sample findings are written.
  BigQueryTable sample_findings_table = 22;

  // The file store does not have any files.
  bool file_store_is_empty = 23;

  // The tags attached to the resource, including any tags attached during
  // profiling.
  repeated Tag tags = 25;

  // Resources related to this profile.
  repeated RelatedResource related_resources = 26;
}

// A tag associated with a resource.
message Tag {
  // The namespaced name for the tag value to attach to Google Cloud resources.
  // Must be in the format `{parent_id}/{tag_key_short_name}/{short_name}`, for
  // example, "123456/environment/prod". This is only set for Google Cloud
  // resources.
  string namespaced_tag_value = 1;

  // The key of a tag key-value pair. For Google Cloud resources, this is the
  // resource name of the key, for example, "tagKeys/123456".
  string key = 2;

  // The value of a tag key-value pair. For Google Cloud resources, this is the
  // resource name of the value, for example, "tagValues/123456".
  string value = 3;
}

// A related resource.
// Examples:
//
// * The source BigQuery table for a Vertex AI dataset.
// * The source Cloud Storage bucket for a Vertex AI dataset.
message RelatedResource {
  // The full resource name of the related resource.
  string full_resource = 1;
}

// Information regarding the discovered InfoType.
message FileStoreInfoTypeSummary {
  // The InfoType seen.
  InfoType info_type = 1;
}

// Information regarding the discovered file extension.
message FileExtensionInfo {
  // The file extension if set. (aka .pdf, .jpg, .txt)
  string file_extension = 1;
}

// The file cluster summary.
message FileClusterSummary {
  // The file cluster type.
  FileClusterType file_cluster_type = 1;

  // InfoTypes detected in this cluster.
  repeated FileStoreInfoTypeSummary file_store_info_type_summaries = 2;

  // The sensitivity score of this cluster. The score will be SENSITIVITY_LOW
  // if nothing has been scanned.
  SensitivityScore sensitivity_score = 3;

  // The data risk level of this cluster. RISK_LOW if nothing has been
  // scanned.
  DataRiskLevel data_risk_level = 4;

  // A list of errors detected while scanning this cluster. The list is
  // truncated to 10 per cluster.
  repeated Error errors = 6;

  // A sample of file types scanned in this cluster. Empty if no files were
  // scanned. File extensions can be derived from the file name or the file
  // content.
  repeated FileExtensionInfo file_extensions_scanned = 7;

  // A sample of file types seen in this cluster. Empty if no files were seen.
  // File extensions can be derived from the file name or the file content.
  repeated FileExtensionInfo file_extensions_seen = 8;

  // True if no files exist in this cluster. If the file store had more files
  // than could be listed, this will be false even if no files for this cluster
  // were seen and file_extensions_seen is empty.
  bool no_files_exist = 9;
}

// Request to get a project data profile.
message GetProjectDataProfileRequest {
  // Required. Resource name, for example
  // `organizations/12345/locations/us/projectDataProfiles/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/ProjectDataProfile"
    }
  ];
}

// Request to get a file store data profile.
message GetFileStoreDataProfileRequest {
  // Required. Resource name, for example
  // `organizations/12345/locations/us/fileStoreDataProfiles/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/ProjectDataProfile"
    }
  ];
}

// Request to list the file store profiles generated for a given organization or
// project.
message ListFileStoreDataProfilesRequest {
  // Required. Resource name of the organization or project, for
  // example `organizations/433245324/locations/europe` or
  // `projects/project-id/locations/asia`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/FileStoreDataProfile"
    }
  ];

  // Optional. Page token to continue retrieval.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Size of the page. This value can be limited by the server. If
  // zero, server returns a page of max size 100.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Comma-separated list of fields to order by, followed by `asc` or
  // `desc` postfix. This list is case insensitive. The default sorting order is
  // ascending. Redundant space characters are insignificant. Only one order
  // field at a time is allowed.
  //
  // Examples:
  //
  // * `project_id asc`
  // * `name`
  // * `sensitivity_level desc`
  //
  // Supported fields are:
  //
  // - `project_id`: The Google Cloud project ID.
  // - `sensitivity_level`: How sensitive the data in a table is, at most.
  // - `data_risk_level`: How much risk is associated with this data.
  // - `profile_last_generated`: When the profile was last updated in epoch
  // seconds.
  // - `last_modified`: The last time the resource was modified.
  // - `resource_visibility`: Visibility restriction for this resource.
  // - `name`: The name of the profile.
  // - `create_time`: The time the file store was first created.
  string order_by = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Allows filtering.
  //
  // Supported syntax:
  //
  // * Filter expressions are made up of one or more restrictions.
  // * Restrictions can be combined by `AND` or `OR` logical operators. A
  // sequence of restrictions implicitly uses `AND`.
  // * A restriction has the form of `{field} {operator} {value}`.
  // * Supported fields/values:
  //     - `project_id` - The Google Cloud project ID.
  //     - `account_id` - The AWS account ID.
  //     - `file_store_path` - The path like "gs://bucket".
  //     - `data_source_type` - The profile's data source type, like
  //     "google/storage/bucket".
  //     - `data_storage_location` - The location where the file store's data is
  //     stored, like "us-central1".
  //     - `sensitivity_level` - HIGH|MODERATE|LOW
  //     - `data_risk_level` - HIGH|MODERATE|LOW
  //     - `resource_visibility`: PUBLIC|RESTRICTED
  //     - `status_code` - an RPC status code as defined in
  //     https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
  // * The operator must be `=` or `!=`.
  //
  // Examples:
  //
  // * `project_id = 12345 AND status_code = 1`
  // * `project_id = 12345 AND sensitivity_level = HIGH`
  // * `project_id = 12345 AND resource_visibility = PUBLIC`
  // * `file_store_path = "gs://mybucket"`
  //
  // The length of this field should be no more than 500 characters.
  string filter = 5 [(google.api.field_behavior) = OPTIONAL];
}

// List of file store data profiles generated for a given organization or
// project.
message ListFileStoreDataProfilesResponse {
  // List of data profiles.
  repeated FileStoreDataProfile file_store_data_profiles = 1;

  // The next page token.
  string next_page_token = 2;
}

// Request message for DeleteFileStoreProfile.
message DeleteFileStoreDataProfileRequest {
  // Required. Resource name of the file store data profile.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/FileStoreDataProfile"
    }
  ];
}

// Request to get a table data profile.
message GetTableDataProfileRequest {
  // Required. Resource name, for example
  // `organizations/12345/locations/us/tableDataProfiles/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/TableDataProfile"
    }
  ];
}

// Request to get a column data profile.
message GetColumnDataProfileRequest {
  // Required. Resource name, for example
  // `organizations/12345/locations/us/columnDataProfiles/53234423`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/ColumnDataProfile"
    }
  ];
}

// A condition for determining whether a Pub/Sub should be triggered.
message DataProfilePubSubCondition {
  // Various score levels for resources.
  enum ProfileScoreBucket {
    // Unused.
    PROFILE_SCORE_BUCKET_UNSPECIFIED = 0;

    // High risk/sensitivity detected.
    HIGH = 1;

    // Medium or high risk/sensitivity detected.
    MEDIUM_OR_HIGH = 2;
  }

  // A condition consisting of a value.
  message PubSubCondition {
    // The value for the condition to trigger.
    oneof value {
      // The minimum data risk score that triggers the condition.
      ProfileScoreBucket minimum_risk_score = 1;

      // The minimum sensitivity level that triggers the condition.
      ProfileScoreBucket minimum_sensitivity_score = 2;
    }
  }

  // An expression, consisting of an operator and conditions.
  message PubSubExpressions {
    // Logical operators for conditional checks.
    enum PubSubLogicalOperator {
      // Unused.
      LOGICAL_OPERATOR_UNSPECIFIED = 0;

      // Conditional OR.
      OR = 1;

      // Conditional AND.
      AND = 2;
    }

    // The operator to apply to the collection of conditions.
    PubSubLogicalOperator logical_operator = 1;

    // Conditions to apply to the expression.
    repeated PubSubCondition conditions = 2;
  }

  // An expression.
  PubSubExpressions expressions = 1;
}

// Pub/Sub topic message for a DataProfileAction.PubSubNotification event.
// To receive a message of protocol buffer schema type, convert the message data
// to an object of this proto class.
message DataProfilePubSubMessage {
  // If `DetailLevel` is `TABLE_PROFILE` this will be fully populated.
  // Otherwise, if `DetailLevel` is `RESOURCE_NAME`, then only `name` and
  // `full_resource` will be populated.
  TableDataProfile profile = 1;

  // If `DetailLevel` is `FILE_STORE_PROFILE` this will be fully populated.
  // Otherwise, if `DetailLevel` is `RESOURCE_NAME`, then only `name` and
  // `file_store_path` will be populated.
  FileStoreDataProfile file_store_profile = 3;

  // The event that caused the Pub/Sub message to be sent.
  DataProfileAction.EventType event = 2;
}

// Request message for CreateConnection.
message CreateConnectionRequest {
  // Required. Parent resource name.
  //
  // The format of this value varies depending on the scope of the request
  // (project or organization):
  //
  // + Projects scope:
  //   `projects/{project_id}/locations/{location_id}`
  // + Organizations scope:
  //   `organizations/{org_id}/locations/{location_id}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/Connection"
    }
  ];

  // Required. The connection resource.
  Connection connection = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request message for GetConnection.
message GetConnectionRequest {
  // Required. Resource name in the format:
  // `projects/{project}/locations/{location}/connections/{connection}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/Connection" }
  ];
}

// Request message for ListConnections.
message ListConnectionsRequest {
  // Required. Resource name of the organization or project, for
  // example, `organizations/433245324/locations/europe` or
  // `projects/project-id/locations/asia`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/Connection"
    }
  ];

  // Optional. Number of results per page, max 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Page token from a previous page to return the next set of
  // results. If set, all other request fields must match the original request.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Supported field/value: `state` - MISSING|AVAILABLE|ERROR
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for SearchConnections.
message SearchConnectionsRequest {
  // Required. Resource name of the organization or project with a wildcard
  // location, for example, `organizations/433245324/locations/-` or
  // `projects/project-id/locations/-`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dlp.googleapis.com/Connection"
    }
  ];

  // Optional. Number of results per page, max 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Page token from a previous page to return the next set of
  // results. If set, all other request fields must match the original request.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Supported field/value: - `state` - MISSING|AVAILABLE|ERROR
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for ListConnections.
message ListConnectionsResponse {
  // List of connections.
  repeated Connection connections = 1;

  // Token to retrieve the next page of results. An empty value means there are
  // no more results.
  string next_page_token = 2;
}

// Response message for SearchConnections.
message SearchConnectionsResponse {
  // List of connections that match the search query. Note that only a subset
  // of the fields will be populated, and only "name" is guaranteed to be set.
  // For full details of a Connection, call GetConnection with the name.
  repeated Connection connections = 1;

  // Token to retrieve the next page of results. An empty value means there are
  // no more results.
  string next_page_token = 2;
}

// Request message for UpdateConnection.
message UpdateConnectionRequest {
  // Required. Resource name in the format:
  // `projects/{project}/locations/{location}/connections/{connection}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/Connection" }
  ];

  // Required. The connection with new values for the relevant fields.
  Connection connection = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Mask to control which fields get updated.
  google.protobuf.FieldMask update_mask = 3
      [(google.api.field_behavior) = OPTIONAL];
}

// Request message for DeleteConnection.
message DeleteConnectionRequest {
  // Required. Resource name of the Connection to be deleted, in the format:
  // `projects/{project}/locations/{location}/connections/{connection}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "dlp.googleapis.com/Connection" }
  ];
}

// A data connection to allow the DLP API to profile data in locations that
// require additional configuration.
message Connection {
  option (google.api.resource) = {
    type: "dlp.googleapis.com/Connection"
    pattern: "projects/{project}/locations/{location}/connections/{connection}"
    pattern: "organizations/{organization}/locations/{location}/connections/{connection}"
  };

  // Output only. Name of the connection:
  // `projects/{project}/locations/{location}/connections/{name}`.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The connection's state in its lifecycle.
  ConnectionState state = 2 [(google.api.field_behavior) = REQUIRED];

  // Output only. Set if status == ERROR, to provide additional details. Will
  // store the last 10 errors sorted with the most recent first.
  repeated Error errors = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Type of connection.
  oneof properties {
    // Connect to a Cloud SQL instance.
    CloudSqlProperties cloud_sql = 4;
  }
}

// State of the connection.
// New values may be added over time.
enum ConnectionState {
  // Unused
  CONNECTION_STATE_UNSPECIFIED = 0;

  // The DLP API automatically created this connection during an initial scan,
  // and it is awaiting full configuration by a user.
  MISSING_CREDENTIALS = 1;

  // A configured connection that has not encountered any errors.
  AVAILABLE = 2;

  // A configured connection that encountered errors during its last use. It
  // will not be used again until it is set to AVAILABLE.
  //
  // If the resolution requires external action, then the client must send a
  // request to set the status to AVAILABLE when the connection is ready for
  // use. If the resolution doesn't require external action, then any changes to
  // the connection properties will automatically mark it as AVAILABLE.
  ERROR = 3;
}

// A credential consisting of a username and password, where the password is
// stored in a Secret Manager resource.
// Note: Secret Manager [charges
// apply](https://cloud.google.com/secret-manager/pricing).
message SecretManagerCredential {
  // Required. The username.
  string username = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The name of the Secret Manager resource that stores the password,
  // in the form `projects/project-id/secrets/secret-name/versions/version`.
  string password_secret_version_name = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Use IAM authentication to connect. This requires the Cloud SQL IAM feature
// to be enabled on the instance, which is not the default for Cloud SQL.
// See https://cloud.google.com/sql/docs/postgres/authentication and
// https://cloud.google.com/sql/docs/mysql/authentication.
message CloudSqlIamCredential {}

// Cloud SQL connection properties.
message CloudSqlProperties {
  // Database engine of a Cloud SQL instance.
  // New values may be added over time.
  enum DatabaseEngine {
    // An engine that is not currently supported by Sensitive Data Protection.
    DATABASE_ENGINE_UNKNOWN = 0;

    // Cloud SQL for MySQL instance.
    DATABASE_ENGINE_MYSQL = 1;

    // Cloud SQL for PostgreSQL instance.
    DATABASE_ENGINE_POSTGRES = 2;
  }

  // Optional. Immutable. The Cloud SQL instance for which the connection is
  // defined. Only one connection per instance is allowed. This can only be set
  // at creation time, and cannot be updated.
  //
  // It is an error to use a connection_name from different project or region
  // than the one that holds the connection.
  // For example, a Connection resource for Cloud SQL connection_name
  // `project-id:us-central1:sql-instance`
  // must be created under the parent
  // `projects/project-id/locations/us-central1`
  string connection_name = 1 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.field_behavior) = OPTIONAL
  ];

  // How to authenticate to the instance.
  oneof credential {
    // A username and password stored in Secret Manager.
    SecretManagerCredential username_password = 2;

    // Built-in IAM authentication (must be configured in Cloud SQL).
    CloudSqlIamCredential cloud_sql_iam = 3;
  }

  // Required. The DLP API will limit its connections to max_connections.
  // Must be 2 or greater.
  int32 max_connections = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The database engine used by the Cloud SQL instance that this
  // connection configures.
  DatabaseEngine database_engine = 7 [(google.api.field_behavior) = REQUIRED];
}

// Request message for DeleteTableProfile.
message DeleteTableDataProfileRequest {
  // Required. Resource name of the table data profile.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dlp.googleapis.com/TableDataProfile"
    }
  ];
}

// Message used to identify the type of resource being profiled.
message DataSourceType {
  // Output only. An identifying string to the type of resource being profiled.
  // Current values:
  //
  // * google/bigquery/table
  // * google/project
  // * google/sql/table
  // * google/gcs/bucket
  string data_source = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Message used to identify file cluster type being profiled.
message FileClusterType {
  // Cluster type. Each cluster corresponds to a set of file types.
  // Over time, new types may be added and files may move between clusters.
  enum Cluster {
    // Unused.
    CLUSTER_UNSPECIFIED = 0;

    // Unsupported files.
    CLUSTER_UNKNOWN = 1;

    // Plain text.
    CLUSTER_TEXT = 2;

    // Structured data like CSV, TSV etc.
    CLUSTER_STRUCTURED_DATA = 3;

    // Source code.
    CLUSTER_SOURCE_CODE = 4;

    // Rich document like docx, xlsx etc.
    CLUSTER_RICH_DOCUMENT = 5;

    // Images like jpeg, bmp.
    CLUSTER_IMAGE = 6;

    // Archives and containers like .zip, .tar etc.
    CLUSTER_ARCHIVE = 7;

    // Multimedia like .mp4, .avi etc.
    CLUSTER_MULTIMEDIA = 8;

    // Executable files like .exe, .class, .apk etc.
    CLUSTER_EXECUTABLE = 9;

    // AI models like .tflite etc.
    CLUSTER_AI_MODEL = 10;
  }

  // File cluster type.
  oneof file_cluster_type {
    // Cluster type.
    Cluster cluster = 1;
  }
}

// Configure processing location for discovery and inspection. For example,
// image OCR is only provided in limited regions but configuring
// ProcessingLocation will redirect OCR to a location where OCR is provided.
message ProcessingLocation {
  // Processing will happen in a multi-region that contains the current region
  // if available.
  message MultiRegionProcessing {}

  // Processing will happen in the global region.
  message GlobalProcessing {}

  // Configure image processing to fall back to the configured processing option
  // below if unavailable in the request location.
  message ImageFallbackLocation {
    // Processing will happen in a multi-region that contains the current region
    // if available.
    MultiRegionProcessing multi_region_processing = 100;

    // Processing will happen in the global region.
    GlobalProcessing global_processing = 200;
  }

  // Image processing will fall back using this configuration.
  ImageFallbackLocation image_fallback_location = 1;
}
