syntax = "proto3";

package golem.rib;

import "wasm/ast/type.proto";
import "wasm/rpc/type_annotated_value.proto";
import "golem/rib/function_name.proto";
import "golem/rib/expr.proto";


message RibIR {
    oneof instruction {
        wasm.rpc.TypeAnnotatedValue push_lit = 1;
        VariableId assign_var = 2;
        VariableId load_var = 3;
        wasm.ast.Type create_and_push_record = 4;
        string update_record = 5;
        PushListInstruction push_list = 6;
        wasm.ast.Type create_some = 7;
        PushNoneInstruction create_none = 8;
        wasm.ast.Type create_ok_result = 9;
        wasm.ast.Type create_err_result = 10;
        string select_field = 11;
        uint64 select_index = 12;
        EqualTo equal_to = 13;
        GreaterThan greater_than = 14;
        LessThan less_than = 15;
        GreaterThanOrEqualTo greater_than_or_equal_to = 16;
        LessThanOrEqualTo less_than_or_equal_to = 17;
        JumpInstruction jump_if_false = 18;
        JumpInstruction jump = 19;
        JumpInstruction label = 20;
        wasm.ast.Type deconstruct = 21;
        InvokeFunctionInstruction invoke_function = 22;
        string throw = 23;
        wasm.rpc.TypeAnnotatedValue push_flag = 24;
        GetTag get_tag = 25;
        VariantConstructionInstruction variant_construction = 26;
        PushTupleInstruction push_tuple = 27;
        Negate negate = 28;
        ConcatInstruction concat = 29;
        EnumConstructionInstruction enum_construction = 30;
        And and = 31;
        CreateFunctionNameInstruction create_function_name = 32;
        Or or = 33;
        ListToIterator list_to_iterator = 34;
        CreateSink create_sink = 35;
        AdvanceIterator advance_iterator = 36;
        SinkToList sink_to_list = 37;
        PushToSink push_to_sink = 38;
        wasm.ast.Type plus = 39;
        wasm.ast.Type minus = 40;
        wasm.ast.Type multiply = 41;
        wasm.ast.Type divide = 42;
        IsEmpty is_empty = 43;
        SelectIndexV1 select_index_v1 = 44;
        Length length = 45;
        GenerateWorkerName generate_worker_name = 46;
    }
}

message Length {}

message GenerateWorkerName {
  optional VariableId variable_id = 1;
}

message SelectIndexV1{}

message VariableId {
    oneof variable_id {
        Global global = 1;
        Local local = 2;
        MatchIdentifier match_identifier = 3;
        ListComprehensionIdentifier list_comprehension_identifier = 4;
        ListAggregationIdentifier list_aggregation_identifier = 5;
    }
}

message Global {
    string name = 1;
}

message ListComprehensionIdentifier {
    string name = 1;
}

message ListAggregationIdentifier {
    string name = 1;
}


message MatchIdentifier {
    string name = 1;
    uint32 match_arm_index  = 2;
}

message Local {
    string name = 1;
    optional uint64 id = 2;
}

message PushListInstruction {
    wasm.ast.Type list_type = 1;
    uint64 list_size = 2;
}

message ConcatInstruction {
    uint64 arg_size = 1;
}

message PushTupleInstruction {
    wasm.ast.Type tuple_type = 1;
    uint64 tuple_size = 2;
}

message PushNoneInstruction {
   optional wasm.ast.Type none_type = 1;
}

message UpdateInstruction {}

message JumpInstruction {
    uint64 instruction_id = 1;
}

message InvokeFunctionInstruction {
    golem.rib.ComponentDependencyKey component = 1;
    uint64 argument_count = 2;
    wasm.ast.Type return_type = 3;
    InstanceVariable instance_variable = 4;

}

message InstanceVariable {
    oneof kind {
        WitWorker worker = 1;
        WitResource resource = 2;
    }
}

message WitWorker {
  golem.rib.VariableId variable_id = 1;
}

message WitResource {
  golem.rib.VariableId variable_id = 1;
}

enum WorkerNamePresence {
    PRESENT = 0;
    ABSENT = 1;
}

message VariantConstructionInstruction {
    string variant_name = 1;
    wasm.ast.Type return_type = 3;
}

message EnumConstructionInstruction {
    string enum_name = 1;
    wasm.ast.Type return_type = 2;
}

message CreateFunctionNameInstruction {
   golem.rib.ParsedFunctionSite site = 1;
   FunctionReferenceType function_reference_details = 2;
}


message EqualTo {}
message GreaterThan {}
message LessThan {}
message GreaterThanOrEqualTo {}
message LessThanOrEqualTo {}
message GetTag {}
message Negate {}
message And {}
message Or {}
message IsEmpty{}

message FunctionReferenceType {
  oneof type {
    Function function = 1;
    RawResourceConstructor raw_resource_constructor = 2;
    RawResourceDrop raw_resource_drop = 3;
    RawResourceMethod raw_resource_method = 4;
    RawResourceStaticMethod raw_resource_static_method = 5;
    IndexedResourceConstructor indexed_resource_constructor = 6;
    IndexedResourceMethod indexed_resource_method = 7;
    IndexedResourceStaticMethod indexed_resource_static_method = 8;
    IndexedResourceDrop indexed_resource_drop = 9;
  }
}

message Function {
  string name = 1;
}

message RawResourceConstructor {
  string resource_name = 1;
}

message RawResourceDrop {
  string resource_name = 1;
}

message RawResourceMethod {
  string resource_name = 1;
  string method_name = 2;
}

message RawResourceStaticMethod {
  string resource_name = 1;
  string method_name = 2;
}

message IndexedResourceConstructor {
  string resource_name = 1;
  uint32 arg_size = 2;
}

message IndexedResourceMethod {
  string resource_name = 1;
  uint32 arg_size = 2;
  string method_name = 3;
}

message IndexedResourceStaticMethod {
  string resource_name = 1;
  uint32 arg_size = 2;
  string method_name = 3;
}

message IndexedResourceDrop {
  string resource_name = 1;
  uint32 arg_size = 2;
}

message SinkToList {}

message PushToSink {}

message AdvanceIterator {}

message CreateSink {
   wasm.ast.Type list_type = 1;
}
message ListToIterator {}
