syntax = "proto3";

package golem.rib;

import "golem/rib/function_name.proto";
import "golem/rib/type_name.proto";
import "golem/common/uuid.proto";

message Expr {
  oneof expr {
    LetExpr let = 1;
    SelectFieldExpr select_field = 2;
    SelectIndexExpr select_index = 3;
    SequenceExpr sequence = 4;
    RecordExpr record = 5;
    TupleExpr tuple = 6;
    LiteralExpr literal = 7;
    NumberExpr number = 8;
    FlagsExpr flags = 9;
    IdentifierExpr identifier = 10;
    BooleanExpr boolean = 11;
    ConcatExpr concat = 12;
    MultipleExpr multiple = 13;
    NotExpr not = 14;
    GreaterThanExpr greater_than = 15;
    GreaterThanOrEqualToExpr greater_than_or_equal = 16;
    LessThanOrEqualToExpr less_than_or_equal = 17;
    EqualToExpr equal_to = 18;
    LessThanExpr less_than = 19;
    CondExpr cond = 20;
    PatternMatchExpr pattern_match = 21;
    OptionExpr option = 22;
    ResultExpr result = 23;
    CallExpr call = 24;
    AndExpr and = 25;
    GetTagExpr tag = 26;
    UnwrapExpr unwrap = 27;
    ThrowExpr throw = 28;
    OrExpr or = 29;
    ListComprehensionExpr list_comprehension = 30;
    ListReduceExpr list_reduce = 31;
    AddExpr add = 32;
    SubtractExpr subtract = 33;
    MultiplyExpr multiply = 34;
    DivideExpr divide = 35;
    LazyInvokeMethodExpr lazy_invoke_method = 36;
    RangeExpr range = 37;
    SelectIndexExprV1 select_index_v1 = 38;
    LengthExpr length = 39;
    GenerateWorkerNameExpr generate_worker_name = 40;
  }
}

message RangeExpr {
    oneof range_expr {
        RangeFrom range_from = 2;
        Range range = 5;
        RangeInclusive range_inclusive = 6;
    }
}

message LengthExpr {
    Expr expr = 1;
}

message Range {
    Expr from = 1;
    Expr to = 2;
}

message RangeFrom {
    Expr from = 1;
}

message RangeInclusive {
    Expr from = 1;
    Expr to = 2;
}

message LetExpr {
  string name = 1;
  Expr expr = 2;
  optional TypeName type_name = 3;
}

message SelectFieldExpr {
  string field = 1;
  Expr expr = 2;
  optional TypeName type_name = 3;
}

message SelectIndexExpr {
  uint64 index = 1;
  Expr expr = 2;
  optional TypeName type_name = 3;
}

message SelectIndexExprV1 {
  Expr index = 1;
  Expr expr = 2;
  optional TypeName type_name = 3;
}

message SequenceExpr {
  repeated Expr exprs = 1;
  optional TypeName type_name = 2;
}

message RecordExpr {
  repeated RecordFieldExpr fields = 1;
}

message RecordFieldExpr {
  string name = 1;
  Expr expr = 2;
}

message ThrowExpr {
  string message = 1;
}

message GenerateWorkerNameExpr{}

message TupleExpr {
  repeated Expr exprs = 1;
}

message LiteralExpr {
  string value = 1;
}

message NumberExpr {
  optional double float = 1;
  optional TypeName type_name = 2;
  optional string number = 3;
}

message FlagsExpr {
  repeated string values = 1;
}

message IdentifierExpr {
  string name = 1;
  optional TypeName type_name = 2;
}

message BooleanExpr {
  bool value = 1;
}

message ConcatExpr {
  repeated Expr exprs = 1;
}

message MultipleExpr {
  repeated Expr exprs = 1;
}

message NotExpr {
  Expr expr = 1;
}

message GetTagExpr {
  Expr expr = 1;
}

message UnwrapExpr {
  Expr expr = 1;
}

message GreaterThanExpr {
  Expr left = 1;
  Expr right = 2;
}

message AndExpr {
  Expr left = 1;
  Expr right = 2;
}

message OrExpr {
  Expr left = 1;
  Expr right = 2;
}

message GreaterThanOrEqualToExpr {
  Expr left = 1;
  Expr right = 2;
}

message LessThanOrEqualToExpr {
  Expr left = 1;
  Expr right = 2;
}

message EqualToExpr {
  Expr left = 1;
  Expr right = 2;
}

message LessThanExpr {
  Expr left = 1;
  Expr right = 2;
}

message AddExpr {
  Expr left = 1;
  Expr right = 2;
}

message MultiplyExpr {
  Expr left = 1;
  Expr right = 2;
}

message SubtractExpr {
  Expr left = 1;
  Expr right = 2;
}

message DivideExpr {
  Expr left = 1;
  Expr right = 2;
}

message CondExpr {
  Expr left = 1;
  Expr cond = 2;
  Expr right = 3;
}

message PatternMatchExpr {
  Expr expr = 1;
  repeated MatchArm patterns = 2;
}

message OptionExpr {
  optional Expr expr = 1;
  optional TypeName type_name = 2;
}

message ResultExpr {
  oneof result {
    Expr ok = 1;
    Expr err = 2;
  }
  optional TypeName type_name = 3;
}

message CallExpr {
  optional InvocationName name = 1;
  repeated Expr params = 2;
  optional CallType call_type = 3;
  optional string generic_type_parameter = 4;
}

message LazyInvokeMethodExpr {
  golem.rib.Expr lhs = 1;
  string method = 2;
  optional string generic_type_parameter = 3;
  repeated golem.rib.Expr args = 4;
}

message CallType {
   oneof name {
       golem.rib.DynamicParsedFunctionName parsed = 1;
       string variant_constructor = 2;
       string enum_constructor = 3;
       golem.rib.InstanceCreationType instance_creation = 4;
     }
}

message ComponentDependencyKey {
  string component_name = 1;
  golem.common.UUID value = 2;
  optional string root_package_name = 3;
  optional string root_package_version = 4;
}

message InstanceCreationType {
    oneof kind {
        WorkerInstance worker = 1;
        ResourceInstanceWithWorkerName resource = 2;
    }
}

message WorkerInstance {
    optional golem.rib.Expr worker_name = 1;
    optional ComponentDependencyKey component = 2;
}

message ResourceInstanceWithWorkerName {
    optional golem.rib.Expr worker_name = 1;
    golem.rib.FullyQualifiedResourceConstructor resource_name = 2;
    optional ComponentDependencyKey component = 3;

}

message FullyQualifiedResourceConstructor {
  optional PackageName package_name = 1;
  optional InterfaceName interface_name = 2;
  string resource_name = 3;
}

message PackageName {
  string namespace = 1;
  string package_name = 2;
  optional string version = 3;
}

message InterfaceName {
  string name = 1;
  optional string version = 2;
}

/** Legacy call-type that holds fully formed function names and not dynamic functions. This is kept for backward compatibility */
message InvocationName {
   oneof name {
     golem.rib.ParsedFunctionName parsed = 1;
     string variant_constructor = 2;
     string enum_constructor = 3;
   }
}

message MatchArm {
  ArmPattern pattern = 1;
  Expr expr = 2;
}

message ArmPattern {
  oneof pattern {
    WildCardArmPattern wild_card = 1;
    AsArmPattern as = 2;
    ConstructorArmPattern constructor = 3;
    LiteralArmPattern literal = 4;
    TupleConstructorArmPattern tuple_constructor = 5;
    ListConstructorArmPattern list_constructor = 6;
    RecordConstructorArmPattern record_constructor = 7;
  }
}

message WildCardArmPattern {

}

message AsArmPattern {
  string name = 1;
  ArmPattern pattern = 2;
}

message ConstructorArmPattern {
  string name = 1;
  repeated ArmPattern patterns = 2;
}

message TupleConstructorArmPattern {
  repeated ArmPattern patterns = 1;
}

message ListConstructorArmPattern {
  repeated ArmPattern patterns = 1;
}

message RecordConstructorArmPattern {
   repeated RecordFieldArmPattern fields = 1;
}

message RecordFieldArmPattern {
    string name = 1;
    ArmPattern pattern = 2;
}


message LiteralArmPattern {
  Expr expr = 1;
}

message DynamicParsedFunctionName {
  golem.rib.ParsedFunctionSite site = 1;
  DynamicParsedFunctionReference function = 2;
}

message DynamicParsedFunctionReference {
  oneof function_reference {
    golem.rib.FunctionFunctionReference function = 1;
    golem.rib.RawResourceConstructorFunctionReference raw_resource_constructor = 2;
    golem.rib.RawResourceDropFunctionReference raw_resource_drop = 3;
    golem.rib.RawResourceMethodFunctionReference raw_resource_method = 4;
    golem.rib.RawResourceStaticMethodFunctionReference raw_resource_static_method = 5;
    DynamicIndexedResourceConstructorFunctionReference indexed_resource_constructor = 6;
    DynamicIndexedResourceMethodFunctionReference indexed_resource_method = 7;
    DynamicIndexedResourceStaticMethodFunctionReference indexed_resource_static_method = 8;
    DynamicIndexedResourceDropFunctionReference indexed_resource_drop = 9;
  }
}

message DynamicIndexedResourceConstructorFunctionReference {
  string resource = 1;
  repeated golem.rib.Expr resource_params = 2;
}

message DynamicIndexedResourceMethodFunctionReference {
  string resource = 1;
  repeated golem.rib.Expr resource_params = 2;
  string method = 3;
}

message DynamicIndexedResourceStaticMethodFunctionReference {
  string resource = 1;
  repeated golem.rib.Expr resource_params = 2;
  string method = 3;
}

message DynamicIndexedResourceDropFunctionReference {
  string resource = 1;
  repeated golem.rib.Expr resource_params = 2;
}

message ListComprehensionExpr {
  string iterated_variable = 1;
  Expr iterable_expr = 2;
  Expr yield_expr = 3;
}

message ListReduceExpr {
  string reduce_variable = 1;
  string iterated_variable = 2;
  Expr iterable_expr = 3;
  Expr init_value_expr = 4;
  Expr yield_expr = 5;
}