syntax = "proto3";
option go_package = "github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/proto";

package proto;

service RuleSet {
    rpc GetName(GetName.Request) returns (GetName.Response);
    rpc GetVersion(GetVersion.Request) returns (GetVersion.Response);
    rpc GetVersionConstraint(GetVersionConstraint.Request) returns (GetVersionConstraint.Response);
    rpc GetSDKVersion(GetSDKVersion.Request) returns (GetSDKVersion.Response);
    rpc GetRuleNames(GetRuleNames.Request) returns (GetRuleNames.Response);
    rpc GetConfigSchema(GetConfigSchema.Request) returns (GetConfigSchema.Response);
    rpc ApplyGlobalConfig(ApplyGlobalConfig.Request) returns (ApplyGlobalConfig.Response);
    rpc ApplyConfig(ApplyConfig.Request) returns (ApplyConfig.Response);
    rpc Check(Check.Request) returns (Check.Response);
}

message GetName {
    message Request {}
    message Response {
        string name = 1;
    }
}

message GetVersion {
    message Request {}
    message Response {
        string version = 1;
    }
}

message GetVersionConstraint {
    message Request {}
    message Response {
        string constraint = 1;
    }
}

message GetSDKVersion {
    message Request {}
    message Response {
        string version = 1;
    }
}

message GetRuleNames {
    message Request {}
    message Response {
        repeated string names = 1;
    }
}

message GetConfigSchema {
    message Request {}
    message Response {
        BodySchema schema = 1;
    }
}

message ApplyGlobalConfig {
    message Config {
        map<string, RuleConfig> rules = 1;
        bool disabled_by_default = 2;
        repeated string only = 3;
        bool fix = 4;
    }
    message RuleConfig {
        string name = 1;
        bool enabled = 2;
    }

    message Request {
        Config config = 1;
    }
    message Response {}
}

message ApplyConfig {
    message Request {
        BodyContent content = 1;
    }
    message Response {}
}

message Check {
    message Request {
        uint32 runner = 1;
    }
    message Response {}
}

service Runner {
    rpc GetOriginalwd(GetOriginalwd.Request) returns (GetOriginalwd.Response);
    rpc GetModulePath(GetModulePath.Request) returns (GetModulePath.Response);
    rpc GetModuleContent(GetModuleContent.Request) returns (GetModuleContent.Response);
    rpc GetFile(GetFile.Request) returns (GetFile.Response);
    rpc GetFiles(GetFiles.Request) returns (GetFiles.Response);
    rpc GetRuleConfigContent(GetRuleConfigContent.Request) returns (GetRuleConfigContent.Response);
    rpc EvaluateExpr(EvaluateExpr.Request) returns (EvaluateExpr.Response);
    rpc EmitIssue(EmitIssue.Request) returns (EmitIssue.Response);
    rpc ApplyChanges(ApplyChanges.Request) returns (ApplyChanges.Response);
}

enum ModuleCtxType {
    MODULE_CTX_TYPE_UNSPECIFIED = 0;
    MODULE_CTX_TYPE_SELF = 1;
    MODULE_CTX_TYPE_ROOT = 2;
}

message GetOriginalwd {
    message Request {}
    message Response {
        string path = 1;
    }
}

message GetModulePath {
    message Request {}
    message Response {
        repeated string path = 1;
    }
}

message GetModuleContent {
    message Hint {
        string resource_type = 1;
    }
    enum ExpandMode {
        EXPAND_MODE_UNSPECIFIED = 0;
        EXPAND_MODE_NONE = 1;
        EXPAND_MODE_EXPAND = 2;
    }
    message Option {
        reserved 3;
        ModuleCtxType module_ctx = 1;
        Hint hint = 2;
        ExpandMode expand_mode = 4;
    }

    message Request {
        BodySchema schema = 1;
        Option option = 2;
    }
    message Response {
        BodyContent content = 1;
    }
}

message GetFile {
    message Request {
        string name = 1;
    }
    message Response {
        bytes file = 1;
    }
}

message GetFiles {
    message Request {
    }
    message Response {
        map<string, bytes> files = 1;
    }
}

message GetRuleConfigContent {
    message Request {
        string name = 1;
        BodySchema schema = 2;
    }
    message Response {
        BodyContent content = 1;
    }
}

message EvaluateExpr {
    message Option {
        bytes type = 1;
        ModuleCtxType module_ctx = 2;
    }

    message Request {
        reserved 1, 2;
        Option option = 3;
        Expression expression = 4;
    }
    message Response {
        bytes value = 1;
        repeated ValueMark marks = 2;
    }
}

message EmitIssue {
    enum Severity {
        SEVERITY_UNSPECIFIED = 0;
        SEVERITY_ERROR = 1;
        SEVERITY_WARNING = 2;
        SEVERITY_NOTICE = 3;
    }
    message Rule {
        string name = 1;
        bool enabled = 2;
        Severity severity = 3;
        string link = 4;
    }

    message Request {
        Rule rule = 1;
        string message = 2;
        Range range = 3;
        bool fixable = 4;
    }
    message Response {
        bool applied = 1;
    }
}

message ApplyChanges {
    message Request {
        map<string, bytes> changes = 1;
    }
    message Response {}
}

enum SchemaMode {
    SCHEMA_MODE_UNSPECIFIED = 0;
    SCHEMA_MODE_DEFAULT = 1;
    SCHEMA_MODE_JUST_ATTRIBUTES = 2;
}

message BodySchema {
    message Attribute {
        string name = 1;
        bool required = 2;
    }
    message Block {
        string type = 1;
        repeated string label_names = 2;
        BodySchema body = 3;
    }

    repeated Attribute attributes = 1;
    repeated Block blocks = 2;
    SchemaMode Mode = 3;
}

message BodyContent {
    message Attribute {
        reserved 2, 3;
        string name = 1;
        Range range = 4;
        Range name_range = 5;
        Expression expression = 6;
    }
    message Block {
        string type = 1;
        repeated string labels = 2;
        BodyContent body = 3;
        Range def_range = 4;
        Range type_range = 5;
        repeated Range label_ranges = 6;
    }

    map<string, Attribute> attributes = 1;
    repeated Block blocks = 2;
}

message Expression {
    bytes bytes = 1;
    Range range = 2;
    bytes value = 3;
    repeated ValueMark value_marks = 4;
}

message Range {
    message Pos {
        int64 line = 1;
        int64 column = 2;
        int64 byte = 3;
    }

    string filename = 1;
    Pos start = 2;
    Pos end = 3;
}

message AttributePath {
    message Step {
        oneof selector {
            string attribute_name = 1;
            string element_key_string = 2;
            int64 element_key_int = 3;
        }
    }
    repeated Step steps = 1;
}

message ValueMark {
    AttributePath path = 1;
    bool sensitive = 2;
    bool ephemeral = 3;
}

enum ErrorCode {
    ERROR_CODE_UNSPECIFIED = 0;
    ERROR_CODE_UNKNOWN_VALUE = 1;
    ERROR_CODE_NULL_VALUE = 2;
    ERROR_CODE_UNEVALUABLE = 3;
    ERROR_CODE_SENSITIVE = 4;
}

message ErrorDetail {
    ErrorCode code = 1;
    string message = 2;
}
