// SPDX-License-Identifier: Apache-2.0
syntax = "proto3";

package substrait;

import "substrait/type.proto";

option csharp_namespace = "Substrait.Protobuf";
option go_package = "github.com/substrait-io/substrait-go/proto";
option java_multiple_files = true;
option java_package = "io.substrait.proto";

message DerivationExpression {
  oneof kind {
    Type.Boolean bool = 1;
    Type.I8 i8 = 2;
    Type.I16 i16 = 3;
    Type.I32 i32 = 5;
    Type.I64 i64 = 7;
    Type.FP32 fp32 = 10;
    Type.FP64 fp64 = 11;
    Type.String string = 12;
    Type.Binary binary = 13;
    Type.Timestamp timestamp = 14;
    Type.Date date = 16;
    Type.Time time = 17;
    Type.IntervalYear interval_year = 19;
    Type.IntervalDay interval_day = 20;
    Type.TimestampTZ timestamp_tz = 29;
    Type.UUID uuid = 32;

    ExpressionFixedChar fixed_char = 21;
    ExpressionVarChar varchar = 22;
    ExpressionFixedBinary fixed_binary = 23;
    ExpressionDecimal decimal = 24;

    ExpressionStruct struct = 25;
    ExpressionList list = 27;
    ExpressionMap map = 28;

    ExpressionUserDefined user_defined = 30;

    // Deprecated in favor of user_defined, which allows nullability and
    // variations to be specified. If user_defined_pointer is encountered,
    // treat it as being non-nullable and having the default variation.
    uint32 user_defined_pointer = 31 [deprecated = true];

    string type_parameter_name = 33;
    string integer_parameter_name = 34;

    int32 integer_literal = 35;
    UnaryOp unary_op = 36;
    BinaryOp binary_op = 37;
    IfElse if_else = 38;
    ReturnProgram return_program = 39;
  }

  message ExpressionFixedChar {
    DerivationExpression length = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message ExpressionVarChar {
    DerivationExpression length = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message ExpressionFixedBinary {
    DerivationExpression length = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message ExpressionDecimal {
    DerivationExpression scale = 1;
    DerivationExpression precision = 2;
    uint32 variation_pointer = 3;
    Type.Nullability nullability = 4;
  }

  message ExpressionStruct {
    repeated DerivationExpression types = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message ExpressionNamedStruct {
    repeated string names = 1;
    ExpressionStruct struct = 2;
  }

  message ExpressionList {
    DerivationExpression type = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message ExpressionMap {
    DerivationExpression key = 1;
    DerivationExpression value = 2;
    uint32 variation_pointer = 3;
    Type.Nullability nullability = 4;
  }

  message ExpressionUserDefined {
    uint32 type_pointer = 1;
    uint32 variation_pointer = 2;
    Type.Nullability nullability = 3;
  }

  message IfElse {
    DerivationExpression if_condition = 1;
    DerivationExpression if_return = 2;
    DerivationExpression else_return = 3;
  }

  message UnaryOp {
    UnaryOpType op_type = 1;
    DerivationExpression arg = 2;

    enum UnaryOpType {
      UNARY_OP_TYPE_UNSPECIFIED = 0;
      UNARY_OP_TYPE_BOOLEAN_NOT = 1;
    }
  }

  message BinaryOp {
    BinaryOpType op_type = 1;
    DerivationExpression arg1 = 2;
    DerivationExpression arg2 = 3;

    enum BinaryOpType {
      BINARY_OP_TYPE_UNSPECIFIED = 0;
      BINARY_OP_TYPE_PLUS = 1;
      BINARY_OP_TYPE_MINUS = 2;
      BINARY_OP_TYPE_MULTIPLY = 3;
      BINARY_OP_TYPE_DIVIDE = 4;
      BINARY_OP_TYPE_MIN = 5;
      BINARY_OP_TYPE_MAX = 6;
      BINARY_OP_TYPE_GREATER_THAN = 7;
      BINARY_OP_TYPE_LESS_THAN = 8;
      BINARY_OP_TYPE_AND = 9;
      BINARY_OP_TYPE_OR = 10;
      BINARY_OP_TYPE_EQUALS = 11;
      BINARY_OP_TYPE_COVERS = 12;
    }
  }

  message ReturnProgram {
    message Assignment {
      string name = 1;
      DerivationExpression expression = 2;
    }

    repeated Assignment assignments = 1;
    DerivationExpression final_expression = 2;
  }
}
