// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: MPL-2.0

// Terraform Plugin RPC protocol version 6.10
//
// This file defines version 6.10 of the RPC protocol. To implement a plugin
// against this protocol, copy this definition into your own codebase and
// use protoc to generate stubs for your target language.
//
// Any minor versions of protocol 6 to follow should modify this file while
// maintaining backwards compatibility. Breaking changes, if any are required,
// will come in a subsequent major version with its own separate proto definition.
//
// Note that only the proto files included in a release tag of Terraform are
// official protocol releases. Proto files taken from other commits may include
// incomplete changes or features that did not make it into a final release.
// In all reasonable cases, plugin developers should take the proto file from
// the tag of the most recent release of Terraform, and not from the main
// branch or any other development branch.
//
syntax = "proto3";
option go_package = "github.com/opentofu/opentofu/internal/tfplugin6";

import "google/protobuf/timestamp.proto";

package tfplugin6;

// DynamicValue is an opaque encoding of terraform data, with the field name
// indicating the encoding scheme used.
message DynamicValue {
    bytes msgpack = 1;
    bytes json = 2;
}

message Diagnostic {
    enum Severity {
        INVALID = 0;
        ERROR = 1;
        WARNING = 2;
    }
    Severity severity = 1;
    string summary = 2;
    string detail = 3;
    AttributePath attribute = 4;
}

message FunctionError {
    string text = 1;
    // The optional function_argument records the index position of the
    // argument which caused the error.
    optional int64 function_argument = 2;
}

message AttributePath {
    message Step {
        oneof selector {
            // Set "attribute_name" to represent looking up an attribute
            // in the current object value.
            string attribute_name = 1;
            // Set "element_key_*" to represent looking up an element in
            // an indexable collection type.
            string element_key_string = 2;
            int64 element_key_int = 3;
        }
    }
    repeated Step steps = 1;
}

message StopProvider {
    message Request {
    }
    message Response {
        string Error = 1;
    }
}

// RawState holds the stored state for a resource to be upgraded by the
// provider. It can be in one of two formats, the current json encoded format
// in bytes, or the legacy flatmap format as a map of strings.
message RawState {
    bytes json = 1;
    map<string, string> flatmap = 2;
}

enum StringKind {
    PLAIN = 0;
    MARKDOWN = 1;
}

// ResourceIdentitySchema represents the structure and types of data used to identify
// a managed resource type. Effectively, resource identity is a versioned object
// that can be used to compare resources, whether already managed and/or being
// discovered.
message ResourceIdentitySchema {
    // IdentityAttribute represents one value of data within resource identity. These
    // are always used in resource identity comparisons.
    message IdentityAttribute {
        // name is the identity attribute name
        string name = 1;

        // type is the identity attribute type
        bytes type = 2;

        // required_for_import when enabled signifies that this attribute must be
        // defined for ImportResourceState to complete successfully
        bool required_for_import = 3;

        // optional_for_import when enabled signifies that this attribute is not
        // required for ImportResourceState, because it can be supplied by the
        // provider. It is still possible to supply this attribute during import.
        bool optional_for_import = 4;

        // description is a human-readable description of the attribute in Markdown
        string description = 5;
    }

    // version is the identity version and separate from the Schema version.
    // Any time the structure or format of identity_attributes changes, this version
    // should be incremented. Versioning implicitly starts at 0 and by convention
    // should be incremented by 1 each change.
    //
    // When comparing identity_attributes data, differing versions should always be treated
    // as inequal.
    int64 version = 1;

    // identity_attributes are the individual value definitions which define identity data
    // for a managed resource type. This information is used to decode DynamicValue of
    // identity data.
    //
    // These attributes are intended for permanent identity data and must be wholly
    // representative of all data necessary to compare two managed resource instances
    // with no other data. This generally should include account, endpoint, location,
    // and automatically generated identifiers. For some resources, this may include
    // configuration-based data, such as a required name which must be unique.
    repeated IdentityAttribute identity_attributes = 2;
}

message ResourceIdentityData {
    // identity_data is the resource identity data for the given definition. It should
    // be decoded using the identity schema.
    //
    // This data is considered permanent for the identity version and suitable for
    // longer-term storage.
    DynamicValue identity_data = 1;
}

// ActionSchema defines the schema for an action that can be invoked by Terraform.
message ActionSchema {
    Schema schema = 1; // of the action itself
}

// Schema is the configuration schema for a Resource or Provider.
message Schema {
    message Block {
        int64 version = 1;
        repeated Attribute attributes = 2;
        repeated NestedBlock block_types = 3;
        string description = 4;
        StringKind description_kind = 5;
        bool deprecated = 6;
        string deprecation_message = 7;
    }

    message Attribute {
        string name = 1;
        bytes type = 2;
        Object nested_type = 10;
        string description = 3;
        bool required = 4;
        bool optional = 5;
        bool computed = 6;
        bool sensitive = 7;
        StringKind description_kind = 8;
        bool deprecated = 9;
        bool write_only = 11;
        string deprecation_message = 12;
    }

    message NestedBlock {
        enum NestingMode {
            INVALID = 0;
            SINGLE = 1;
            LIST = 2;
            SET = 3;
            MAP = 4;
            GROUP = 5;
        }

        string type_name = 1;
        Block block = 2;
        NestingMode nesting = 3;
        int64 min_items = 4;
        int64 max_items = 5;
    }

    message Object {
        enum NestingMode {
            INVALID = 0;
            SINGLE = 1;
            LIST = 2;
            SET = 3;
            MAP = 4;
        }

        repeated Attribute attributes = 1;
        NestingMode nesting = 3;

        // MinItems and MaxItems were never used in the protocol, and have no
        // effect on validation.
        int64 min_items = 4 [ deprecated = true ];
        int64 max_items = 5 [ deprecated = true ];
    }

    // The version of the schema.
    // Schemas are versioned, so that providers can upgrade a saved resource
    // state when the schema is changed.
    int64 version = 1;

    // Block is the top level configuration block for this schema.
    Block block = 2;
}

message Function {
    // parameters is the ordered list of positional function parameters.
    repeated Parameter parameters = 1;

    // variadic_parameter is an optional final parameter which accepts
    // zero or more argument values, in which Terraform will send an
    // ordered list of the parameter type.
    Parameter variadic_parameter = 2;

    // Return is the function return parameter.
    Return return = 3;

    // summary is the human-readable shortened documentation for the function.
    string summary = 4;

    // description is human-readable documentation for the function.
    string description = 5;

    // description_kind is the formatting of the description.
    StringKind description_kind = 6;

    // deprecation_message is human-readable documentation if the
    // function is deprecated.
    string deprecation_message = 7;

    message Parameter {
        // name is the human-readable display name for the parameter.
        string name = 1;

        // type is the type constraint for the parameter.
        bytes type = 2;

        // allow_null_value when enabled denotes that a null argument value can
        // be passed to the provider. When disabled, Terraform returns an error
        // if the argument value is null.
        bool allow_null_value = 3;

        // allow_unknown_values when enabled denotes that only wholly known
        // argument values will be passed to the provider. When disabled,
        // Terraform skips the function call entirely and assumes an unknown
        // value result from the function.
        bool allow_unknown_values = 4;

        // description is human-readable documentation for the parameter.
        string description = 5;

        // description_kind is the formatting of the description.
        StringKind description_kind = 6;
    }

    message Return {
        // type is the type constraint for the function result.
        bytes type = 1;
    }
}

// ServerCapabilities allows providers to communicate extra information
// regarding supported protocol features. This is used to indicate
// availability of certain forward-compatible changes which may be optional
// in a major protocol version, but cannot be tested for directly.
message ServerCapabilities {
    // The plan_destroy capability signals that a provider expects a call
    // to PlanResourceChange when a resource is going to be destroyed.
    bool plan_destroy = 1;

    // The get_provider_schema_optional capability indicates that this
    // provider does not require calling GetProviderSchema to operate
    // normally, and the caller can used a cached copy of the provider's
    // schema.
    bool get_provider_schema_optional = 2;

    // The move_resource_state capability signals that a provider supports the
    // MoveResourceState RPC.
    bool move_resource_state = 3;

    // The generate_resource_config capability signals that a provider supports
    // GenerateResourceConfig.
    bool generate_resource_config = 4;
}

// ClientCapabilities allows Terraform to publish information regarding
// supported protocol features. This is used to indicate availability of
// certain forward-compatible changes which may be optional in a major
// protocol version, but cannot be tested for directly.
message ClientCapabilities {
    // The deferral_allowed capability signals that the client is able to
    // handle deferred responses from the provider.
    bool deferral_allowed = 1;

    // The write_only_attributes_allowed capability signals that the client
    // is able to handle write_only attributes for managed resources.
    bool write_only_attributes_allowed = 2;
}

// Deferred is a message that indicates that change is deferred for a reason.
message Deferred {
    // Reason is the reason for deferring the change.
    enum Reason {
        // UNKNOWN is the default value, and should not be used.
        UNKNOWN = 0;
        // RESOURCE_CONFIG_UNKNOWN is used when the config is partially unknown and the real
        // values need to be known before the change can be planned.
        RESOURCE_CONFIG_UNKNOWN = 1;
        // PROVIDER_CONFIG_UNKNOWN is used when parts of the provider configuration
        // are unknown, e.g. the provider configuration is only known after the apply is done.
        PROVIDER_CONFIG_UNKNOWN = 2;
        // ABSENT_PREREQ is used when a hard dependency has not been satisfied.
        ABSENT_PREREQ = 3;
    }

    // reason is the reason for deferring the change.
    Reason reason = 1;
}

service Provider {
    //////// Information about what a provider supports/expects

    // GetMetadata returns upfront information about server capabilities and
    // supported resource types without requiring the server to instantiate all
    // schema information, which may be memory intensive.
    // This method is CURRENTLY UNUSED and it serves mostly for convenience
    // of code generation inside of terraform-plugin-mux.
    rpc GetMetadata(GetMetadata.Request) returns (GetMetadata.Response);

    // GetSchema returns schema information for the provider, data resources,
    // and managed resources.
    rpc GetProviderSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response);
    rpc ValidateProviderConfig(ValidateProviderConfig.Request) returns (ValidateProviderConfig.Response);
    rpc ValidateResourceConfig(ValidateResourceConfig.Request) returns (ValidateResourceConfig.Response);
    rpc ValidateDataResourceConfig(ValidateDataResourceConfig.Request) returns (ValidateDataResourceConfig.Response);
    rpc UpgradeResourceState(UpgradeResourceState.Request) returns (UpgradeResourceState.Response);

    // GetResourceIdentitySchemas returns the identity schemas for all managed
    // resources.
    rpc GetResourceIdentitySchemas(GetResourceIdentitySchemas.Request) returns (GetResourceIdentitySchemas.Response);
    // UpgradeResourceIdentityData should return the upgraded resource identity
    // data for a managed resource type.
    rpc UpgradeResourceIdentity(UpgradeResourceIdentity.Request) returns (UpgradeResourceIdentity.Response);

    //////// One-time initialization, called before other functions below
    rpc ConfigureProvider(ConfigureProvider.Request) returns (ConfigureProvider.Response);

    //////// Managed Resource Lifecycle
    rpc ReadResource(ReadResource.Request) returns (ReadResource.Response);
    rpc PlanResourceChange(PlanResourceChange.Request) returns (PlanResourceChange.Response);
    rpc ApplyResourceChange(ApplyResourceChange.Request) returns (ApplyResourceChange.Response);
    rpc ImportResourceState(ImportResourceState.Request) returns (ImportResourceState.Response);
    rpc MoveResourceState(MoveResourceState.Request) returns (MoveResourceState.Response);
    rpc ReadDataSource(ReadDataSource.Request) returns (ReadDataSource.Response);
    rpc GenerateResourceConfig(GenerateResourceConfig.Request) returns (GenerateResourceConfig.Response);

    //////// Ephemeral Resource Lifecycle
    rpc ValidateEphemeralResourceConfig(ValidateEphemeralResourceConfig.Request) returns (ValidateEphemeralResourceConfig.Response);
    rpc OpenEphemeralResource(OpenEphemeralResource.Request) returns (OpenEphemeralResource.Response);
    rpc RenewEphemeralResource(RenewEphemeralResource.Request) returns (RenewEphemeralResource.Response);
    rpc CloseEphemeralResource(CloseEphemeralResource.Request) returns (CloseEphemeralResource.Response);

    /////// List
    rpc ListResource(ListResource.Request) returns (stream ListResource.Event);
    rpc ValidateListResourceConfig(ValidateListResourceConfig.Request) returns (ValidateListResourceConfig.Response);

    // GetFunctions returns the definitions of all functions.
    rpc GetFunctions(GetFunctions.Request) returns (GetFunctions.Response);

    //////// Provider-contributed Functions
    rpc CallFunction(CallFunction.Request) returns (CallFunction.Response);

    // ValidateStateStoreConfig performs configuration validation
    rpc ValidateStateStoreConfig(ValidateStateStore.Request) returns (ValidateStateStore.Response);
    // ConfigureStateStore configures the state store, such as S3 connection in the context of already configured provider
    rpc ConfigureStateStore(ConfigureStateStore.Request) returns (ConfigureStateStore.Response);

    // ReadStateBytes streams byte chunks of a given state file from a state store
    rpc ReadStateBytes(ReadStateBytes.Request) returns (stream ReadStateBytes.Response);
    // WriteStateBytes streams byte chunks of a given state file into a state store
    rpc WriteStateBytes(stream WriteStateBytes.RequestChunk) returns (WriteStateBytes.Response);

    // LockState locks a given state (i.e. CE workspace)
    rpc LockState(LockState.Request) returns (LockState.Response);
    // UnlockState unlocks a given state (i.e. CE workspace)
    rpc UnlockState(UnlockState.Request) returns (UnlockState.Response);

    // GetStates returns a list of all states (i.e. CE workspaces) managed by a given state store
    rpc GetStates(GetStates.Request) returns (GetStates.Response);
    // DeleteState instructs a given state store to delete a specific state (i.e. a CE workspace)
    rpc DeleteState(DeleteState.Request) returns (DeleteState.Response);

    //////// Actions
    rpc PlanAction(PlanAction.Request) returns (PlanAction.Response);
    rpc InvokeAction(InvokeAction.Request) returns (stream InvokeAction.Event);
    rpc ValidateActionConfig(ValidateActionConfig.Request) returns (ValidateActionConfig.Response);

    //////// Graceful Shutdown
    rpc StopProvider(StopProvider.Request) returns (StopProvider.Response);
}

message GetMetadata {
    message Request {
    }

    message Response {
        ServerCapabilities server_capabilities = 1;
        repeated Diagnostic diagnostics = 2;
        repeated DataSourceMetadata data_sources = 3;
        repeated ResourceMetadata resources = 4;
        // functions returns metadata for any functions.
        repeated FunctionMetadata functions = 5;
        repeated EphemeralMetadata ephemeral_resources = 6;
        repeated ListResourceMetadata list_resources = 7;
        repeated StateStoreMetadata state_stores = 8;
        repeated ActionMetadata actions = 9;
    }

    message EphemeralMetadata {
        string type_name = 1;
    }

    message FunctionMetadata {
        // name is the function name.
        string name = 1;
    }

    message DataSourceMetadata {
        string type_name = 1;
    }

    message ResourceMetadata {
        string type_name = 1;
    }

    message ListResourceMetadata {
        string type_name = 1;
    }

    message StateStoreMetadata {
        string type_name = 1;
    }
    
    message ActionMetadata {
        string type_name = 1;
    }
}

message GetProviderSchema {
    message Request {
    }
    message Response {
        Schema provider = 1;
        map<string, Schema> resource_schemas = 2;
        map<string, Schema> data_source_schemas = 3;
        map<string, Function> functions = 7;
        map<string, Schema> ephemeral_resource_schemas = 8;
        map<string, Schema> list_resource_schemas = 9;
        map<string, Schema> state_store_schemas = 10;
        map<string, ActionSchema> action_schemas = 11;
        repeated Diagnostic diagnostics = 4;
        Schema provider_meta = 5;
        ServerCapabilities server_capabilities = 6;
    }
}

message ValidateProviderConfig {
    message Request {
        DynamicValue config = 1;
    }
    message Response {
        repeated Diagnostic diagnostics = 2;
    }
}

message UpgradeResourceState {
    // Request is the message that is sent to the provider during the
    // UpgradeResourceState RPC.
    //
    // This message intentionally does not include configuration data as any
    // configuration-based or configuration-conditional changes should occur
    // during the PlanResourceChange RPC. Additionally, the configuration is
    // not guaranteed to exist (in the case of resource destruction), be wholly
    // known, nor match the given prior state, which could lead to unexpected
    // provider behaviors for practitioners.
    message Request {
        string type_name = 1;

        // version is the schema_version number recorded in the state file
        int64 version = 2;

        // raw_state is the raw states as stored for the resource.  Core does
        // not have access to the schema of prior_version, so it's the
        // provider's responsibility to interpret this value using the
        // appropriate older schema. The raw_state will be the json encoded
        // state, or a legacy flat-mapped format.
        RawState raw_state = 3;
    }
    message Response {
        // new_state is a msgpack-encoded data structure that, when interpreted with
        // the _current_ schema for this resource type, is functionally equivalent to
        // that which was given in prior_state_raw.
        DynamicValue upgraded_state = 1;

        // diagnostics describes any errors encountered during migration that could not
        // be safely resolved, and warnings about any possibly-risky assumptions made
        // in the upgrade process.
        repeated Diagnostic diagnostics = 2;
    }
}

message GetResourceIdentitySchemas {
    message Request {
    }

    message Response {
        // identity_schemas is a mapping of resource type names to their identity schemas.
        map<string, ResourceIdentitySchema> identity_schemas = 1;

        // diagnostics is the collection of warning and error diagnostics for this request.
        repeated Diagnostic diagnostics = 2;
    }
}

message UpgradeResourceIdentity {
    message Request {
        // type_name is the managed resource type name
        string type_name = 1;

        // version is the version of the resource identity data to upgrade
        int64 version = 2;

        // raw_identity is the raw identity as stored for the resource. Core does
        // not have access to the identity schema of prior_version, so it's the
        // provider's responsibility to interpret this value using the
        // appropriate older schema. The raw_identity will be json encoded.
        RawState raw_identity = 3;
    }

    message Response {
        // upgraded_identity returns the upgraded resource identity data
        ResourceIdentityData upgraded_identity = 1;

        // diagnostics is the collection of warning and error diagnostics for this request
        repeated Diagnostic diagnostics = 2;
    }
}

message ValidateResourceConfig {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
        ClientCapabilities client_capabilities = 3;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ValidateDataResourceConfig {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ValidateEphemeralResourceConfig {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ConfigureProvider {
    message Request {
        string terraform_version = 1;
        DynamicValue config = 2;
        ClientCapabilities client_capabilities = 3;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ReadResource {
    // Request is the message that is sent to the provider during the
    // ReadResource RPC.
    //
    // This message intentionally does not include configuration data as any
    // configuration-based or configuration-conditional changes should occur
    // during the PlanResourceChange RPC. Additionally, the configuration is
    // not guaranteed to be wholly known nor match the given prior state, which
    // could lead to unexpected provider behaviors for practitioners.
    message Request {
        string type_name = 1;
        DynamicValue current_state = 2;
        bytes private = 3;
        DynamicValue provider_meta = 4;
        ClientCapabilities client_capabilities = 5;
        ResourceIdentityData current_identity = 6;
    }
    message Response {
        DynamicValue new_state = 1;
        repeated Diagnostic diagnostics = 2;
        bytes private = 3;
        // deferred is set if the provider is deferring the change. If set the caller
        // needs to handle the deferral.
        Deferred deferred = 4;
        ResourceIdentityData new_identity = 5;
    }
}

message PlanResourceChange {
    message Request {
        string type_name = 1;
        DynamicValue prior_state = 2;
        DynamicValue proposed_new_state = 3;
        DynamicValue config = 4;
        bytes prior_private = 5;
        DynamicValue provider_meta = 6;
        ClientCapabilities client_capabilities = 7;
        ResourceIdentityData prior_identity = 8;
    }

    message Response {
        DynamicValue planned_state = 1;
        repeated AttributePath requires_replace = 2;
        bytes planned_private = 3;
        repeated Diagnostic diagnostics = 4;

        // This may be set only by the helper/schema "SDK" in the main Terraform
        // repository, to request that Terraform Core >=0.12 permit additional
        // inconsistencies that can result from the legacy SDK type system
        // and its imprecise mapping to the >=0.12 type system.
        // The change in behavior implied by this flag makes sense only for the
        // specific details of the legacy SDK type system, and are not a general
        // mechanism to avoid proper type handling in providers.
        //
        //     ====              DO NOT USE THIS              ====
        //     ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ====
        //     ====              DO NOT USE THIS              ====
        bool legacy_type_system = 5;

        // deferred is set if the provider is deferring the change. If set the caller
        // needs to handle the deferral.
        Deferred deferred = 6;

        ResourceIdentityData planned_identity = 7;
    }
}

message ApplyResourceChange {
    message Request {
        string type_name = 1;
        DynamicValue prior_state = 2;
        DynamicValue planned_state = 3;
        DynamicValue config = 4;
        bytes planned_private = 5;
        DynamicValue provider_meta = 6;
        ResourceIdentityData planned_identity = 7;
    }
    message Response {
        DynamicValue new_state = 1;
        bytes private = 2;
        repeated Diagnostic diagnostics = 3;

        // This may be set only by the helper/schema "SDK" in the main Terraform
        // repository, to request that Terraform Core >=0.12 permit additional
        // inconsistencies that can result from the legacy SDK type system
        // and its imprecise mapping to the >=0.12 type system.
        // The change in behavior implied by this flag makes sense only for the
        // specific details of the legacy SDK type system, and are not a general
        // mechanism to avoid proper type handling in providers.
        //
        //     ====              DO NOT USE THIS              ====
        //     ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ====
        //     ====              DO NOT USE THIS              ====
        bool legacy_type_system = 4;

        ResourceIdentityData new_identity = 5;
    }
}

message ImportResourceState {
    message Request {
        string type_name = 1;
        string id = 2;
        ClientCapabilities client_capabilities = 3;
        ResourceIdentityData identity = 4;
    }

    message ImportedResource {
        string type_name = 1;
        DynamicValue state = 2;
        bytes private = 3;
        ResourceIdentityData identity = 4;
    }

    message Response {
        repeated ImportedResource imported_resources = 1;
        repeated Diagnostic diagnostics = 2;
        // deferred is set if the provider is deferring the change. If set the caller
        // needs to handle the deferral.
        Deferred deferred = 3;
    }
}

message GenerateResourceConfig {
    message Request {
        string type_name = 1;
        DynamicValue state = 2;
    }

    message Response {
        // config is the provided state modified such that it represents a valid resource configuration value.
        DynamicValue config = 1;
        repeated Diagnostic diagnostics = 2;
    }
}

message MoveResourceState {
    message Request {
        // The address of the provider the resource is being moved from.
        string source_provider_address = 1;

        // The resource type that the resource is being moved from.
        string source_type_name = 2;

        // The schema version of the resource type that the resource is being
        // moved from.
        int64 source_schema_version = 3;

        // The raw state of the resource being moved. Only the json field is
        // populated, as there should be no legacy providers using the flatmap
        // format that support newly introduced RPCs.
        RawState source_state = 4;

        // The resource type that the resource is being moved to.
        string target_type_name = 5;

        // The private state of the resource being moved.
        bytes source_private = 6;

        // The raw identity of the resource being moved. Only the json field is
        // populated, as there should be no legacy providers using the flatmap
        // format that support newly introduced RPCs.
        RawState source_identity = 7;

        // The identity schema version of the resource type that the resource
        // is being moved from.
        int64 source_identity_schema_version = 8;
    }

    message Response {
        // The state of the resource after it has been moved.
        DynamicValue target_state = 1;

        // Any diagnostics that occurred during the move.
        repeated Diagnostic diagnostics = 2;

        // The private state of the resource after it has been moved.
        bytes target_private = 3;

        ResourceIdentityData target_identity = 4;
    }
}

message ReadDataSource {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
        DynamicValue provider_meta = 3;
        ClientCapabilities client_capabilities = 4;
    }
    message Response {
        DynamicValue state = 1;
        repeated Diagnostic diagnostics = 2;
        // deferred is set if the provider is deferring the change. If set the caller
        // needs to handle the deferral.
        Deferred deferred = 3;
    }
}

message OpenEphemeralResource {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
        ClientCapabilities client_capabilities = 3;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
        optional google.protobuf.Timestamp renew_at = 2;
        DynamicValue result = 3;
        optional bytes private = 4;
        Deferred deferred = 5;
    }
}

message RenewEphemeralResource {
    message Request {
        string type_name = 1;
        optional bytes private = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
        optional google.protobuf.Timestamp renew_at = 2;
        optional bytes private = 3;
    }
}

message CloseEphemeralResource {
    message Request {
        string type_name = 1;
        optional bytes private = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message GetFunctions {
    message Request {}

    message Response {
        // functions is a mapping of function names to definitions.
        map<string, Function> functions = 1;

        // diagnostics is any warnings or errors.
        repeated Diagnostic diagnostics = 2;
    }
}

message CallFunction {
    message Request {
        string name = 1;
        repeated DynamicValue arguments = 2;
    }
    message Response {
        DynamicValue result = 1;
        FunctionError error = 2;
    }
}

message ListResource {
    message Request {
        // type_name is the list resource type name.
        string type_name = 1;

        // configuration is the list ConfigSchema-based configuration data.
        DynamicValue config = 2;

        // when include_resource_object is set to true, the provider should
        // include the full resource object for each result
        bool include_resource_object = 3;

        // The maximum number of results that Terraform is expecting.
        // The stream will stop, once this limit is reached.
        int64 limit = 4;
    }

    message Event {
        // identity is the resource identity data of the resource instance.
        ResourceIdentityData identity = 1;

        // display_name can be displayed in a UI to make it easier for humans to identify a resource
        string display_name = 2;

        // optional resource object which can be useful when combining list blocks in configuration
        optional DynamicValue resource_object = 3;

        // A warning or error diagnostics for this event
        repeated Diagnostic diagnostic = 4;
    }
}

message ValidateListResourceConfig {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
        DynamicValue include_resource_object = 3;
        DynamicValue limit = 4;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ValidateStateStore {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message ConfigureStateStore {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
        StateStoreClientCapabilities capabilities = 3;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
        StateStoreServerCapabilities capabilities = 2;
    }
}

message StateStoreClientCapabilities {
    int64 chunk_size = 1; // suggested chunk size by Core
}

message StateStoreServerCapabilities {
    int64 chunk_size = 1; // chosen chunk size by plugin
}

message ReadStateBytes {
    message Request {
        string type_name = 1;
        string state_id = 2;
    }
    message Response {
        bytes bytes = 1;
        // total_length is the overall size of all of the state byte chunks that will be received
        int64 total_length = 2;
        StateRange range = 3;
        repeated Diagnostic diagnostics = 4;
    }
}

message WriteStateBytes {
    message RequestChunk {
        // meta is sent with the first chunk only
        optional RequestChunkMeta meta = 1;

        bytes bytes = 2;
        // total_length is the overall size of all of the state byte chunks that will be sent.
        int64 total_length = 3;
        StateRange range = 4;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message RequestChunkMeta {
    string type_name = 1;
    string state_id = 2;
}

message StateRange {
    // start is the starting byte index for a chunk of state byte data.
    // This index is in relation to the entire byte array that will be sent or received.
    int64 start = 1;
    // end is the ending byte index for a chunk of state byte data.
    // This index is in relation to the entire byte array that will be sent or received.
    int64 end = 2;
}

message LockState {
    message Request {
        string type_name = 1;
        string state_id = 2;
        // operation represents an ongoing operation due to which lock is held (e.g. refresh, plan, apply)
        string operation = 3;
    }
    message Response {
        string lock_id = 1;
        repeated Diagnostic diagnostics = 2;
    }
}

message UnlockState {
    message Request {
        string type_name = 1;
        string state_id = 2;
        string lock_id = 3;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message GetStates {
	message Request {
		string type_name = 1;
    }
    message Response {
        repeated string state_id = 1;
        repeated Diagnostic diagnostics = 2;
    }
}

message DeleteState {
	message Request {
		string type_name = 1;
		string state_id = 2;
    }
	message Response {
        repeated Diagnostic diagnostics = 1;
    }
}

message PlanAction {
    message Request {
        string action_type = 1;
        // config of the action, based on the schema of the actual action
        DynamicValue config = 2;
        // metadata
        ClientCapabilities client_capabilities = 3;
    }

    message Response {
        repeated Diagnostic diagnostics = 1;
        // metadata
        Deferred deferred = 2;
    }
}

message InvokeAction {
    message Request {
        string action_type = 1;
        // response from the plan
        DynamicValue config = 2;
        // metadata
        ClientCapabilities client_capabilities = 3;
    }

    message Event {
      message Progress {
        // message to be printed in the console / HCPT
        string message = 1;
      }

      message Completed {
        repeated Diagnostic diagnostics = 1;
    }

    oneof type {
      Progress progress = 1;
      Completed completed = 2;
    }
  }
}

message ValidateActionConfig {
    message Request {
        string type_name = 1;
        DynamicValue config = 2;
    }
    message Response {
        repeated Diagnostic diagnostics = 1;
    }
}
