// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.datacatalog.lineage.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/type/interval.proto";

option csharp_namespace = "Google.Cloud.DataCatalog.Lineage.V1";
option go_package = "cloud.google.com/go/datacatalog/lineage/apiv1/lineagepb;lineagepb";
option java_multiple_files = true;
option java_outer_classname = "LineageProto";
option java_package = "com.google.cloud.datacatalog.lineage.v1";
option php_namespace = "Google\\Cloud\\DataCatalog\\Lineage\\V1";
option ruby_package = "Google::Cloud::DataCatalog::Lineage::V1";

// Lineage is used to track data flows between assets over time. You can
// create [LineageEvents][google.cloud.datacatalog.lineage.v1.LineageEvent]
// to record lineage between multiple sources and a single target, for
// example, when table data is based on data from multiple tables.
service Lineage {
  option (google.api.default_host) = "datalineage.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Creates new lineage events together with their parents: process and run.
  // Updates the process and run if they already exist.
  // Mapped from Open Lineage specification:
  // https://github.com/OpenLineage/OpenLineage/blob/main/spec/OpenLineage.json.
  rpc ProcessOpenLineageRunEvent(ProcessOpenLineageRunEventRequest)
      returns (ProcessOpenLineageRunEventResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}:processOpenLineageRunEvent"
      body: "open_lineage"
    };
    option (google.api.method_signature) = "parent,open_lineage";
  }

  // Creates a new process.
  rpc CreateProcess(CreateProcessRequest) returns (Process) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/processes"
      body: "process"
    };
    option (google.api.method_signature) = "parent,process";
  }

  // Updates a process.
  rpc UpdateProcess(UpdateProcessRequest) returns (Process) {
    option (google.api.http) = {
      patch: "/v1/{process.name=projects/*/locations/*/processes/*}"
      body: "process"
    };
    option (google.api.method_signature) = "process,update_mask";
  }

  // Gets the details of the specified process.
  rpc GetProcess(GetProcessRequest) returns (Process) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/processes/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // List processes in the given project and location. List order is descending
  // by insertion time.
  rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/processes"
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes the process with the specified name.
  rpc DeleteProcess(DeleteProcessRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/processes/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "google.cloud.datacatalog.lineage.v1.OperationMetadata"
    };
  }

  // Creates a new run.
  rpc CreateRun(CreateRunRequest) returns (Run) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/processes/*}/runs"
      body: "run"
    };
    option (google.api.method_signature) = "parent,run";
  }

  // Updates a run.
  rpc UpdateRun(UpdateRunRequest) returns (Run) {
    option (google.api.http) = {
      patch: "/v1/{run.name=projects/*/locations/*/processes/*/runs/*}"
      body: "run"
    };
    option (google.api.method_signature) = "run,update_mask";
  }

  // Gets the details of the specified run.
  rpc GetRun(GetRunRequest) returns (Run) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/processes/*/runs/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists runs in the given project and location. List order is descending by
  // `start_time`.
  rpc ListRuns(ListRunsRequest) returns (ListRunsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/processes/*}/runs"
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes the run with the specified name.
  rpc DeleteRun(DeleteRunRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/processes/*/runs/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "google.cloud.datacatalog.lineage.v1.OperationMetadata"
    };
  }

  // Creates a new lineage event.
  rpc CreateLineageEvent(CreateLineageEventRequest) returns (LineageEvent) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/processes/*/runs/*}/lineageEvents"
      body: "lineage_event"
    };
    option (google.api.method_signature) = "parent,lineage_event";
  }

  // Gets details of a specified lineage event.
  rpc GetLineageEvent(GetLineageEventRequest) returns (LineageEvent) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/processes/*/runs/*/lineageEvents/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists lineage events in the given project and location. The list order is
  // not defined.
  rpc ListLineageEvents(ListLineageEventsRequest)
      returns (ListLineageEventsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/processes/*/runs/*}/lineageEvents"
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes the lineage event with the specified name.
  rpc DeleteLineageEvent(DeleteLineageEventRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/processes/*/runs/*/lineageEvents/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Retrieve a list of links connected to a specific asset.
  // Links represent the data flow between **source** (upstream)
  // and **target** (downstream) assets in transformation pipelines.
  // Links are stored in the same project as the Lineage Events that create
  // them.
  //
  // You can retrieve links in every project where you have the
  // `datalineage.events.get` permission. The project provided in the URL
  // is used for Billing and Quota.
  rpc SearchLinks(SearchLinksRequest) returns (SearchLinksResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}:searchLinks"
      body: "*"
    };
  }

  // Retrieve information about LineageProcesses associated with specific
  // links. LineageProcesses are transformation pipelines that result in data
  // flowing from **source** to **target** assets. Links between assets
  // represent this operation.
  //
  // If you have specific link names, you can use this method to
  // verify which LineageProcesses contribute to creating those links.
  // See the
  // [SearchLinks][google.cloud.datacatalog.lineage.v1.Lineage.SearchLinks]
  // method for more information on how to retrieve link name.
  //
  // You can retrieve the LineageProcess information in every project where you
  // have the `datalineage.events.get` permission. The project provided in the
  // URL is used for Billing and Quota.
  rpc BatchSearchLinkProcesses(BatchSearchLinkProcessesRequest)
      returns (BatchSearchLinkProcessesResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}:batchSearchLinkProcesses"
      body: "*"
    };
  }

  // Retrieves a streaming response of lineage links connected to the requested
  // assets by performing a breadth-first search in the given direction. Links
  // represent the data flow between **source** (upstream) and **target**
  // (downstream) assets in transformation pipelines. Links are stored in the
  // same project as the Lineage Events that create them. This method retrieves
  // links from all valid locations provided in the request. This method
  // supports Column-Level Lineage (CLL) along with wildcard support to retrieve
  // all CLL for an Entity FQN.
  //
  // Following permissions are required to retrieve links:
  // * `datalineage.events.get` permission for the project where the link is
  // stored for entity-level lineage.
  // * `datalineage.events.getFields` permission for the project where the link
  // is stored for column-level lineage.
  //
  // This method also returns processes that created the links if explicitly
  // requested by setting
  // [max_process_per_link](google.cloud.datacatalog.lineage.v1.SearchLineageStreamingRequest.limits.max_process_per_link)
  // is non-zero and full process details are requested via
  // `links.processes.process` in the
  // [FieldMask](https://developers.google.com/workspace/docs/api/how-tos/field-masks#read_with_a_field_mask).
  //
  // Permission required to retrieve processes:
  // * `datalineage.processes.get` permission for the project where the process
  // is stored.
  rpc SearchLineageStreaming(SearchLineageStreamingRequest)
      returns (stream SearchLineageStreamingResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}:searchLineageStreaming"
      body: "*"
    };
  }
}

// A process is the definition of a data transformation operation.
message Process {
  option (google.api.resource) = {
    type: "datalineage.googleapis.com/Process"
    pattern: "projects/{project}/locations/{location}/processes/{process}"
    plural: "processes"
    singular: "process"
  };

  // Immutable. The resource name of the lineage process. Format:
  // `projects/{project}/locations/{location}/processes/{process}`.
  // Can be specified or auto-assigned.
  // {process} must be not longer than 200 characters and only
  // contain characters in a set: `a-zA-Z0-9_-:.`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Optional. A human-readable name you can set to display in a user interface.
  // Must be not longer than 200 characters and only contain UTF-8 letters
  // or numbers, spaces or characters like `_-:&.`
  string display_name = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The attributes of the process. Should only be used for the
  // purpose of non-semantic management (classifying, describing or labeling the
  // process).
  //
  // Up to 100 attributes are allowed.
  map<string, google.protobuf.Value> attributes = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The origin of this process and its runs and lineage events.
  Origin origin = 4 [(google.api.field_behavior) = OPTIONAL];
}

// A lineage run represents an execution of a process that creates
// lineage events.
message Run {
  option (google.api.resource) = {
    type: "datalineage.googleapis.com/Run"
    pattern: "projects/{project}/locations/{location}/processes/{process}/runs/{run}"
    plural: "runs"
    singular: "run"
  };

  // The current state of the run.
  enum State {
    // The state is unknown. The true state may be any of the below or a
    // different state that is not supported here explicitly.
    UNKNOWN = 0;

    // The run is still executing.
    STARTED = 1;

    // The run completed.
    COMPLETED = 2;

    // The run failed.
    FAILED = 3;

    // The run aborted.
    ABORTED = 4;
  }

  // Immutable. The resource name of the run. Format:
  // `projects/{project}/locations/{location}/processes/{process}/runs/{run}`.
  // Can be specified or auto-assigned.
  // {run} must be not longer than 200 characters and only
  // contain characters in a set: `a-zA-Z0-9_-:.`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Optional. A human-readable name you can set to display in a user interface.
  // Must be not longer than 200 characters and only contain UTF-8 letters
  // or numbers, spaces or characters like `_-:&.`
  string display_name = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The attributes of the run. Should only be used for the purpose of
  // non-semantic management (classifying, describing or labeling the run).
  //
  // Up to 100 attributes are allowed.
  map<string, google.protobuf.Value> attributes = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The timestamp of the start of the run.
  google.protobuf.Timestamp start_time = 4
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The timestamp of the end of the run.
  google.protobuf.Timestamp end_time = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The state of the run.
  State state = 6 [(google.api.field_behavior) = REQUIRED];
}

// A lineage event represents an operation on assets. Within the operation, the
// data flows from the source to the target defined in the links field.
message LineageEvent {
  option (google.api.resource) = {
    type: "datalineage.googleapis.com/LineageEvent"
    pattern: "projects/{project}/locations/{location}/processes/{process}/runs/{run}/lineageEvents/{lineage_event}"
    plural: "lineageEvents"
    singular: "lineageEvent"
  };

  // Immutable. The resource name of the lineage event.
  // Format:
  // `projects/{project}/locations/{location}/processes/{process}/runs/{run}/lineageEvents/{lineage_event}`.
  // Can be specified or auto-assigned.
  // {lineage_event} must be not longer than 200 characters and only
  // contain characters in a set: `a-zA-Z0-9_-:.`
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Optional. List of source-target pairs. Can't contain more than 100 tuples.
  repeated EventLink links = 8 [(google.api.field_behavior) = OPTIONAL];

  // Required. The beginning of the transformation which resulted in this
  // lineage event. For streaming scenarios, it should be the beginning of the
  // period from which the lineage is being reported.
  google.protobuf.Timestamp start_time = 6
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The end of the transformation which resulted in this lineage
  // event.  For streaming scenarios, it should be the end of the period from
  // which the lineage is being reported.
  google.protobuf.Timestamp end_time = 7
      [(google.api.field_behavior) = OPTIONAL];
}

// A lineage between source and target entities.
message EventLink {
  // Required. Reference to the source entity
  EntityReference source = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Reference to the target entity
  EntityReference target = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Describes how the target depends on the source.
  DependencyInfo dependency_info = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Dependency info describes how one entity depends on another.
message DependencyInfo {
  // Required. Type of dependency.
  DependencyType dependency_type = 1 [(google.api.field_behavior) = REQUIRED];
}

// The soft reference to everything you can attach a lineage event to.
message EntityReference {
  // Required. [Fully Qualified Name
  // (FQN)](https://cloud.google.com/dataplex/docs/fully-qualified-names)
  // of the entity.
  string fully_qualified_name = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Field path within the entity. Each nesting level should be a
  // separate value in the repeated field. The order matters. Must be empty for
  // asset level lineage
  //
  // For example to address "salary.net" subfield where "salary" is a column and
  // "net" is a proto field two values in the `field` should be reported,
  // the first is "salary" and the second is "net".
  //
  // Each field length is limited to 500 characters.
  // Maximum supported nesting level is 20.
  repeated string field = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Metadata describing the operation.
message OperationMetadata {
  // An enum with the state of the operation.
  enum State {
    // Unused.
    STATE_UNSPECIFIED = 0;

    // The operation has been created but is not yet started.
    PENDING = 1;

    // The operation is underway.
    RUNNING = 2;

    // The operation completed successfully.
    SUCCEEDED = 3;

    // The operation is no longer running and did not succeed.
    FAILED = 4;
  }

  // Type of the long running operation.
  enum Type {
    // Unused.
    TYPE_UNSPECIFIED = 0;

    // The resource deletion operation.
    DELETE = 1;

    // The resource creation operation.
    CREATE = 2;
  }

  // Output only. The current operation state.
  State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The type of the operation being performed.
  Type operation_type = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The [relative name]
  // (https://cloud.google.com//apis/design/resource_names#relative_resource_name)
  // of the resource being operated on.
  string resource = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The UUID of the resource being operated on.
  string resource_uuid = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp of the operation submission to the server.
  google.protobuf.Timestamp create_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp of the operation termination, regardless of its
  // success. This field is unset if the operation is still ongoing.
  google.protobuf.Timestamp end_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for
// [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent].
message ProcessOpenLineageRunEventRequest {
  // Required. The name of the project and its location that should own the
  // process, run, and lineage event.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. OpenLineage message following OpenLineage format:
  // https://github.com/OpenLineage/OpenLineage/blob/main/spec/OpenLineage.json
  google.protobuf.Struct open_lineage = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. A unique identifier for this request. Restricted to 36 ASCII
  // characters. A random UUID is recommended. This request is idempotent only
  // if a `request_id` is provided.
  string request_id = 3 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Response message for
// [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent].
message ProcessOpenLineageRunEventResponse {
  // Created process name.
  // Format: `projects/{project}/locations/{location}/processes/{process}`.
  string process = 1 [(google.api.resource_reference) = {
    type: "datalineage.googleapis.com/Process"
  }];

  // Created run name.
  // Format:
  // `projects/{project}/locations/{location}/processes/{process}/runs/{run}`.
  string run = 2 [
    (google.api.resource_reference) = { type: "datalineage.googleapis.com/Run" }
  ];

  // Created lineage event names.
  // Format:
  // `projects/{project}/locations/{location}/processes/{process}/runs/{run}/lineageEvents/{lineage_event}`.
  repeated string lineage_events = 3 [(google.api.resource_reference) = {
    type: "datalineage.googleapis.com/LineageEvent"
  }];
}

// Request message for
// [CreateProcess][google.cloud.datacatalog.lineage.v1.Lineage.CreateProcess].
message CreateProcessRequest {
  // Required. The name of the project and its location that should own the
  // process.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Process"
    }
  ];

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

  // Optional. A unique identifier for this request. Restricted to 36 ASCII
  // characters. A random UUID is recommended. This request is idempotent only
  // if a `request_id` is provided.
  string request_id = 3 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for
// [UpdateProcess][google.cloud.datacatalog.lineage.v1.Lineage.UpdateProcess].
message UpdateProcessRequest {
  // Required. The lineage process to update.
  //
  // The process's `name` field is used to identify the process to update.
  Process process = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The list of fields to update. Currently not used. The whole
  // message is updated.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set to true and the process is not found, the request inserts
  // it.
  bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A unique identifier for this request. Restricted to 36 ASCII
  // characters. A random UUID is recommended. This request is idempotent only
  // if a `request_id` is provided.
  string request_id = 4 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for
// [GetProcess][google.cloud.datacatalog.lineage.v1.Lineage.GetProcess].
message GetProcessRequest {
  // Required. The name of the process to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datalineage.googleapis.com/Process"
    }
  ];
}

// Request message for
// [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses].
message ListProcessesRequest {
  // Required. The name of the project and its location that owns this
  // collection of processes.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Process"
    }
  ];

  // Optional. The maximum number of processes to return. The service may return
  // fewer than this value. If unspecified, at most 50 processes are
  // returned. The maximum value is 100; values greater than 100 are cut to
  // 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token received from a previous `ListProcesses` call.
  // Specify it to get the next page.
  //
  // When paginating, all other parameters specified in this call must
  // match the parameters of the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses].
message ListProcessesResponse {
  // The processes from the specified project and location.
  repeated Process processes = 1;

  // The token to specify as `page_token` in the next call to get the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for
// [DeleteProcess][google.cloud.datacatalog.lineage.v1.Lineage.DeleteProcess].
message DeleteProcessRequest {
  // Required. The name of the process to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datalineage.googleapis.com/Process"
    }
  ];

  // Optional. If set to true and the process is not found, the request
  // succeeds but the server doesn't perform any actions.
  bool allow_missing = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for
// [CreateRun][google.cloud.datacatalog.lineage.v1.Lineage.CreateRun].
message CreateRunRequest {
  // Required. The name of the process that should own the run.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Run"
    }
  ];

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

  // Optional. A unique identifier for this request. Restricted to 36 ASCII
  // characters. A random UUID is recommended. This request is idempotent only
  // if a `request_id` is provided.
  string request_id = 3 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for
// [UpdateRun][google.cloud.datacatalog.lineage.v1.Lineage.UpdateRun].
message UpdateRunRequest {
  // Required. The lineage run to update.
  //
  // The run's `name` field is used to identify the run to update.
  //
  // Format:
  // `projects/{project}/locations/{location}/processes/{process}/runs/{run}`.
  Run run = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The list of fields to update. Currently not used. The whole
  // message is updated.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set to true and the run is not found, the request creates it.
  bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for
// [GetRun][google.cloud.datacatalog.lineage.v1.Lineage.GetRun].
message GetRunRequest {
  // Required. The name of the run to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "datalineage.googleapis.com/Run" }
  ];
}

// Request message for
// [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns].
message ListRunsRequest {
  // Required. The name of process that owns this collection of runs.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datalineage.googleapis.com/Process"
    }
  ];

  // Optional. The maximum number of runs to return. The service may return
  // fewer than this value. If unspecified, at most 50 runs are
  // returned. The maximum value is 100; values greater than 100 are cut to
  // 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token received from a previous `ListRuns` call. Specify
  // it to get the next page.
  //
  // When paginating, all other parameters specified in this call must
  // match the parameters of the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns].
message ListRunsResponse {
  // The runs from the specified project and location.
  repeated Run runs = 1;

  // The token to specify as `page_token` in the next call to get the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for
// [DeleteRun][google.cloud.datacatalog.lineage.v1.Lineage.DeleteRun].
message DeleteRunRequest {
  // Required. The name of the run to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "datalineage.googleapis.com/Run" }
  ];

  // Optional. If set to true and the run is not found, the request
  // succeeds but the server doesn't perform any actions.
  bool allow_missing = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for
// [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.CreateLineageEvent].
message CreateLineageEventRequest {
  // Required. The name of the run that should own the lineage event.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/LineageEvent"
    }
  ];

  // Required. The lineage event to create.
  LineageEvent lineage_event = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A unique identifier for this request. Restricted to 36 ASCII
  // characters. A random UUID is recommended. This request is idempotent only
  // if a `request_id` is provided.
  string request_id = 3 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for
// [GetLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.GetLineageEvent].
message GetLineageEventRequest {
  // Required. The name of the lineage event to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datalineage.googleapis.com/LineageEvent"
    }
  ];
}

// Request message for
// [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents].
message ListLineageEventsRequest {
  // Required. The name of the run that owns the collection of lineage events to
  // get.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "datalineage.googleapis.com/Run" }
  ];

  // Optional. The maximum number of lineage events to return.
  //
  // The service may return fewer events than this value.
  // If unspecified, at most 50 events are returned. The maximum value is 100;
  // values greater than 100 are cut to 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token received from a previous `ListLineageEvents` call.
  // Specify it to get the next page.
  //
  // When paginating, all other parameters specified in this call must
  // match the parameters of the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents].
message ListLineageEventsResponse {
  // Lineage events from the specified project and location.
  repeated LineageEvent lineage_events = 1;

  // The token to specify as `page_token` in the next call to get the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Request message for
// [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.DeleteLineageEvent].
message DeleteLineageEventRequest {
  // Required. The name of the lineage event to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "datalineage.googleapis.com/LineageEvent"
    }
  ];

  // Optional. If set to true and the lineage event is not found, the request
  // succeeds but the server doesn't perform any actions.
  bool allow_missing = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for
// [SearchLinks][google.cloud.datacatalog.lineage.v1.Lineage.SearchLinks].
message SearchLinksRequest {
  // Required. The project and location you want search in.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Process"
    }
  ];

  // The asset for which you want to retrieve links.
  oneof criteria {
    // Optional. Send asset information in the **source** field to retrieve all
    // links that lead from the specified asset to downstream assets.
    EntityReference source = 4 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Send asset information in the **target** field to retrieve all
    // links that lead from upstream assets to the specified asset.
    EntityReference target = 5 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Send a list of asset information in the **sources** field to
    // retrieve all links that lead from the specified assets to downstream
    // assets. This field is similar to the `source`
    // [source][google.cloud.datacatalog.lineage.v1.SearchLinksRequest.source]
    // field but allows providing multiple entities.
    // All entities within the `MultipleEntityReference` must have the same
    // `fully_qualified_name`.
    MultipleEntityReference sources = 6
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Send a list of asset information in the **targets** field to
    // retrieve all links that lead from upstream assets to the specified
    // assets. This field is similar to the `target`
    // [target][google.cloud.datacatalog.lineage.v1.SearchLinksRequest.target]
    // field but allows providing multiple entities.
    // All entities within the `MultipleEntityReference` must have the same
    // `fully_qualified_name`.
    MultipleEntityReference targets = 7
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Optional. The maximum number of links to return in a single page of the
  // response. A page may contain fewer links than this value. If unspecified,
  // at most 10 links are returned.
  //
  // Maximum value is 100; values greater than 100 are reduced to 100.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token received from a previous `SearchLinksRequest`
  // call. Use it to get the next page.
  //
  // When requesting subsequent pages of a response, remember that
  // all parameters must match the values you provided
  // in the original request.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Multiple entity reference for SearchLinksRequest.
message MultipleEntityReference {
  // Optional. The list of entities to search for links. The maximum number of
  // entities is 20.
  repeated EntityReference entities = 1
      [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [SearchLinks][google.cloud.datacatalog.lineage.v1.Lineage.SearchLinks].
message SearchLinksResponse {
  // The list of links for a given asset. Can be empty if the asset has no
  // relations of requested type (source or target).
  repeated Link links = 1;

  // The token to specify as `page_token` in the subsequent call to get the next
  // page. Omitted if there are no more pages in the response.
  string next_page_token = 2;
}

// Links represent the data flow between **source** (upstream)
// and **target** (downstream) assets in transformation pipelines.
//
// Links are created when LineageEvents record data transformation between
// related assets.
message Link {
  // Dependency info describes how one entity depends on another.
  message DependencyInfo {
    // The type of dependency.
    DependencyType dependency_type = 1;
  }

  // Output only. Immutable. The name of the link. Format:
  // `projects/{project}/locations/{location}/links/{link}`.
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // The pointer to the entity that is the **source** of this link.
  EntityReference source = 2;

  // The pointer to the entity that is the **target** of this link.
  EntityReference target = 3;

  // The start of the first event establishing this link.
  google.protobuf.Timestamp start_time = 4;

  // The end of the last event establishing this link.
  google.protobuf.Timestamp end_time = 5;

  // Optional. The dependency info of the link (applies only to column level
  // links).
  repeated DependencyInfo dependency_info = 6
      [(google.api.field_behavior) = OPTIONAL];
}

// Request message for
// [BatchSearchLinkProcesses][google.cloud.datacatalog.lineage.v1.Lineage.BatchSearchLinkProcesses].
message BatchSearchLinkProcessesRequest {
  // Required. The project and location where you want to search.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Process"
    }
  ];

  // Required. An array of links to check for their associated LineageProcesses.
  //
  // The maximum number of items in this array is 100.
  // If the request contains more than 100 links, it returns the
  // `INVALID_ARGUMENT` error.
  //
  // Format: `projects/{project}/locations/{location}/links/{link}`.
  repeated string links = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The maximum number of processes to return in a single page of the
  // response. A page may contain fewer results than this value.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page token received from a previous
  // `BatchSearchLinkProcesses` call. Use it to get the next page.
  //
  // When requesting subsequent pages of a response, remember that
  // all parameters must match the values you provided
  // in the original request.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [BatchSearchLinkProcesses][google.cloud.datacatalog.lineage.v1.Lineage.BatchSearchLinkProcesses].
message BatchSearchLinkProcessesResponse {
  // An array of processes associated with the specified links.
  repeated ProcessLinks process_links = 1;

  // The token to specify as `page_token` in the subsequent call to get the next
  // page. Omitted if there are no more pages in the response.
  string next_page_token = 2;
}

// Links associated with a specific process.
message ProcessLinks {
  // The process name in the format of
  // `projects/{project}/locations/{location}/processes/{process}`.
  string process = 1 [(google.api.resource_reference) = {
    type: "datalineage.googleapis.com/Process"
  }];

  // An array containing link details objects of the links provided in
  // the original request.
  //
  // A single process can result in creating multiple links.
  // If any of the links you provide in the request are created by
  // the same process, they all are included in this array.
  repeated ProcessLinkInfo links = 2;
}

// Link details.
message ProcessLinkInfo {
  // The name of the link in the format of
  // `projects/{project}/locations/{location}/links/{link}`.
  string link = 1;

  // The start of the first event establishing this link-process tuple.
  google.protobuf.Timestamp start_time = 2;

  // The end of the last event establishing this link-process tuple.
  google.protobuf.Timestamp end_time = 3;
}

// Origin of a process.
message Origin {
  // Type of the source of a process.
  enum SourceType {
    // Source is Unspecified
    SOURCE_TYPE_UNSPECIFIED = 0;

    // A custom source
    CUSTOM = 1;

    // BigQuery
    BIGQUERY = 2;

    // Data Fusion
    DATA_FUSION = 3;

    // Composer
    COMPOSER = 4;

    // Looker Studio
    LOOKER_STUDIO = 5;

    // Dataproc
    DATAPROC = 6;

    // Vertex AI
    VERTEX_AI = 7;

    // Dataflow
    DATAFLOW = 8;

    // Looker Core
    LOOKER_CORE = 9;
  }

  // Type of the source.
  //
  // Use of a source_type other than `CUSTOM` for process creation
  // or updating is highly discouraged. It might be restricted in the future
  // without notice. There will be increase in cost if you use any of the source
  // types other than `CUSTOM`.
  SourceType source_type = 1;

  // If the source_type isn't CUSTOM, the value of this field should be a Google
  // Cloud resource name of the system, which reports lineage. The project and
  // location parts of the resource name must match the project and location of
  // the lineage resource being created. Examples:
  //
  // - `{source_type: COMPOSER, name:
  //   "projects/foo/locations/us/environments/bar"}`
  // - `{source_type: BIGQUERY, name: "projects/foo/locations/eu"}`
  // - `{source_type: CUSTOM,   name: "myCustomIntegration"}`
  string name = 2;
}

// Lineage link between two entities.
message LineageLink {
  // Process metadata for the link.
  message LineageProcess {
    // Process that created the link.
    Process process = 3;
  }

  // Dependency info describes how one entity is dependent on another.
  message DependencyInfo {
    // The type of dependency.
    DependencyType dependency_type = 1;
  }

  // The entity that is the **source** of this link.
  EntityReference source = 1;

  // The entity that is the **target** of this link.
  EntityReference target = 2;

  // Processes metadata associated with the link.
  repeated LineageProcess processes = 3;

  // Describes how the target entity is dependent on the source entity.
  repeated DependencyInfo dependency_info = 4;

  // Depth of the current link in the graph starting from 1.
  int32 depth = 5;

  // The location where the LineageEvent that created the link is stored.
  string location = 7;
}

// Request message for
// [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming].
message SearchLineageStreamingRequest {
  // Direction of the search.
  enum SearchDirection {
    // Direction is unspecified.
    SEARCH_DIRECTION_UNSPECIFIED = 0;

    // Retrieve links that lead from the specified asset to downstream assets.
    DOWNSTREAM = 1;

    // Retrieve links that lead from upstream assets to the specified asset.
    UPSTREAM = 2;
  }

  // Entity set restriction.
  enum EntitySet {
    // The entity set is unspecified. Returns all the data.
    ENTITY_SET_UNSPECIFIED = 0;

    // Returns entities with only FQN specified. For example, entities with the
    // `field` field set are not returned.
    ENTITIES = 1;
  }

  // Filters for the search.
  message SearchFilters {
    // Optional. Types of dependencies between entities to retrieve.
    // If unspecified, all dependency types are returned.
    repeated DependencyType dependency_types = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Entity set restriction. If unspecified, the method returns all
    // entities.
    EntitySet entity_set = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Time interval to search for lineage. If unspecified, all
    // lineage is returned. Currently, at most one of `start_time` and
    // `end_time` can be set.
    google.type.Interval time_range = 3
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Limits for the search results.
  message SearchLimits {
    // Optional. The maximum depth of the search. The default value is 5 and
    // maximum value is 100.
    int32 max_depth = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The maximum number of links to return in the response. The
    // default value is 1_000 and the maximum value is 10_000.
    int32 max_results = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The maximum number of processes to return per link. The default
    // value is 0 and the maximum value is 100. If this value is non-zero, the
    // response will contain process names for the links. To retrieve full
    // process details in the response, include `links.processes.process` in the
    // [FieldMask](https://developers.google.com/workspace/docs/api/how-tos/field-masks#read_with_a_field_mask).
    int32 max_process_per_link = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // Criteria for the root of the search.
  message RootCriteria {
    // Criteria for the root of the search.
    oneof criteria {
      // Optional. The entities to initiate the search from. Entities can be
      // specified by FQN only, or by FQN and field. To search by FQN and all
      // available fields for that FQN, use the wildcard `*` as the field value.
      MultipleEntityReference entities = 1
          [(google.api.field_behavior) = OPTIONAL];
    }
  }

  // Required. The project and location to initiate the search from.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "datalineage.googleapis.com/Process"
    }
  ];

  // Required. The locations to search in.
  repeated string locations = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Criteria for the root of the search.
  RootCriteria root_criteria = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Direction of the search.
  SearchDirection direction = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. Filters for the search.
  SearchFilters filters = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Limits for the search.
  SearchLimits limits = 6 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming].
message SearchLineageStreamingResponse {
  // Output only. The lineage links that match the search criteria. Can be empty
  // if no links match.
  repeated LineageLink links = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Unordered list. Unreachable resources. If non-empty, the result set might
  // be incomplete.
  //
  // Currently, only locations are supported.
  //
  // Format: `projects/[PROJECT_NUMBER]/locations/[LOCATION]`
  // Example: projects/123456789/locations/us-east1
  repeated string unreachable = 2
      [(google.api.field_behavior) = UNORDERED_LIST];
}

// Type of dependency between entities.
enum DependencyType {
  // Dependency type unspecified.
  DEPENDENCY_TYPE_UNSPECIFIED = 0;

  // Exact data copy without any change.
  EXACT_COPY = 1;

  // Other types of dependencies like filtering or grouping.
  OTHER = 3;
}
