/*
 * Copyright 2010-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.kotlin.serialization.js.ast;

option java_outer_classname = "JsAstProtoBuf";
option optimize_for = LITE_RUNTIME;


message Location {
    required int32 startLine = 1;
    required int32 startChar = 2;
}

enum SideEffects {
    AFFECTS_STATE = 1;
    DEPENDS_ON_STATE = 2;
    PURE = 3;
}

message JsImportedModule {
    required int32 external_name = 1;
    required int32 internal_name = 2;
    optional Expression plain_reference = 3;
}


// Expressions
//

message Expression {
    optional int32 fileId = 1;
    optional Location location = 2;
    optional bool synthetic = 3 [default = false];
    optional SideEffects side_effects = 4 [default = AFFECTS_STATE];
    optional JsImportedModule local_alias = 5;
    repeated Comment before_comments = 6;
    repeated Comment after_comments = 7;

    oneof expression {
        int32 simple_name_reference = 22;
        ThisLiteral this_literal = 23;
        NullLiteral null_literal = 24;
        TrueLiteral true_literal = 25;
        FalseLiteral false_literal = 26;
        int32 string_literal = 27;
        RegExpLiteral reg_exp_literal = 28;
        int32 int_literal = 29;
        double double_literal = 30;
        ArrayLiteral array_literal = 31;
        ObjectLiteral object_literal = 32;
        Function function = 33;
        DocComment doc_comment = 34;
        BinaryOperation binary = 35;
        UnaryOperation unary = 36;
        Conditional conditional = 37;
        ArrayAccess array_access = 38;
        NameReference name_reference = 39;
        PropertyReference property_reference = 40;
        Invocation invocation = 41;
        Instantiation instantiation = 42;
        SuperLiteral super_literal = 43;
        Class class = 44;
    }
}

message ThisLiteral {
}

message SuperLiteral {
}

message NullLiteral {
}

message TrueLiteral {
}

message FalseLiteral {
}

message RegExpLiteral {
    required int32 pattern_string_id = 1;
    optional int32 flags_string_id = 2;
}

message ArrayLiteral {
    repeated Expression element = 1;
}

message ObjectLiteral {
    repeated ObjectLiteralEntry entry = 1;
    optional bool multiline = 2 [default = true];
}

message ObjectLiteralEntry {
    required Expression key = 1;
    required Expression value = 2;
}

message Function {
    repeated Parameter parameter = 1;
    optional int32 name_id = 2;
    required Statement body = 3;
    optional bool local = 4 [default = false];
    repeated Modifier modifier = 5;
    optional bool is_es6_arrow = 6 [default = false];

    enum Modifier {
        STATIC = 1;
        GET = 2;
        SET = 3;
        GENERATOR = 4;
    }
}

message Class {
    optional int32 name_id = 1;
    optional Expression super_expression = 2;
    optional Function constructor = 3;
    repeated Function member = 4;
}

message Parameter {
    required int32 name_id = 1;
    optional bool has_default_value = 2 [default = false];
}

message DocComment {
    repeated DocCommentTag tag = 1;
}

message DocCommentTag {
    required int32 name_id = 1;
    oneof value {
        int32 value_string_id = 2;
        Expression expression = 3;
    }
}

message Comment {
    required string text = 1;
    required bool multiline = 2;
}

message BinaryOperation {
    required Expression left = 1;
    required Expression right = 2;
    required Type type = 3;

    enum Type {
        MUL = 1;
        DIV = 2;
        MOD = 3;
        ADD = 4;
        SUB = 5;
        SHL = 6;
        SHR = 7;
        SHRU = 8;
        LT = 9;
        LTE = 10;
        GT = 11;
        GTE = 12;
        INSTANCEOF = 13;
        IN = 14;
        EQ = 15;
        NEQ = 16;
        REF_EQ = 17;
        REF_NEQ = 18;
        BIT_AND = 19;
        BIT_XOR = 20;
        BIT_OR = 21;
        AND = 22;
        OR = 23;
        ASG = 24;
        ASG_ADD = 25;
        ASG_SUB = 26;
        ASG_MUL = 27;
        ASG_DIV = 28;
        ASG_MOD = 29;
        ASG_SHL = 30;
        ASG_SHR = 31;
        ASG_SHRU = 32;
        ASG_BIT_AND = 33;
        ASG_BIT_OR = 34;
        ASG_BIT_XOR = 35;
        COMMA = 36;
    }
}

message UnaryOperation {
    required Expression operand = 1;
    required Type type = 2;
    required bool postfix = 3;

    enum Type {
        BIT_NOT = 1;
        DEC = 2;
        DELETE = 3;
        INC = 4;
        NEG = 5;
        POS = 6;
        NOT = 7;
        TYPEOF = 8;
        VOID = 9;
    }
}

message Conditional {
    required Expression test_expression = 1;
    required Expression then_expression = 2;
    required Expression else_expression = 3;
}

message ArrayAccess {
    required Expression array = 1;
    required Expression index = 2;
}

message NameReference {
    required int32 name_id = 1;
    optional Expression qualifier = 2;
    optional InlineStrategy inline_strategy = 3 [default=NOT_INLINE];
}

message PropertyReference {
    required int32 string_id = 1;
    optional Expression qualifier = 2;
    optional InlineStrategy inline_strategy = 3 [default=NOT_INLINE];
}

message Invocation {
    required Expression qualifier = 1;
    repeated Expression argument = 2;
    optional InlineStrategy inline_strategy = 3 [default=NOT_INLINE];
}

message Instantiation {
    required Expression qualifier = 1;
    repeated Expression argument = 2;
}


// Statements
//

message Statement {
    optional int32 fileId = 1;
    optional Location location = 2;
    optional bool synthetic = 3 [default = false];
    repeated Comment before_comments = 4;
    repeated Comment after_comments = 5;

    oneof statement {
        Return return_statement = 21;
        Throw throw_statement = 22;
        Break break_statement = 23;
        Continue continue_statement = 24;
        Debugger debugger = 25;
        ExpressionStatement expression = 26;
        Vars vars = 27;
        Block block = 28;
        CompositeBlock composite_block = 29;
        Label label = 30;
        If if_statement = 31;
        Switch switch_statement = 32;
        While while_statement = 33;
        DoWhile do_while_statement = 34;
        For for_statement = 35;
        ForIn for_in_statement = 36;
        Try try_statement = 37;
        Empty empty = 38;
        SingleLineComment single_line_comment = 39;
        MultiLineComment multi_line_comment = 40;
    }
}

message Return {
    optional Expression value = 1;
}

message Throw {
    required Expression exception = 1;
}

message Break {
    optional int32 label_id = 1;
}

message Continue {
    optional int32 label_id = 1;
}

message Debugger {
}

message ExpressionStatement {
    required Expression expression = 1;
    optional int32 exported_tag_id = 2;
}

message Vars {
    repeated VarDeclaration declaration = 1;
    optional bool multiline = 2 [default = false];
    optional int32 exported_package_id = 3;
}

message VarDeclaration {
    required int32 name_id = 1;
    optional Expression initial_value = 2;
    optional int32 fileId = 3;
    optional Location location = 4;
}

message Block {
    repeated Statement statement = 1;
}

message CompositeBlock {
    repeated Statement statement = 1;
}

message Label {
    required int32 nameId = 1;
    required Statement inner_statement = 2;
}

message If {
    required Expression condition = 1;
    required Statement then_statement = 2;
    optional Statement else_statement = 3;
}

message Switch {
    required Expression expression = 1;
    repeated SwitchEntry entry = 2;
}

message SwitchEntry {
    optional Expression label = 1;
    repeated Statement statement = 2;

    optional int32 fileId = 3;
    optional Location location = 4;
}

message While {
    required Expression condition = 1;
    required Statement body = 2;
}

message DoWhile {
    required Expression condition = 1;
    required Statement body = 2;
}

message For {
    oneof init {
        Statement variables = 1;
        Expression expression = 2;
        EmptyInit empty = 3;
    }
    optional Expression condition = 4;
    optional Expression increment = 5;
    required Statement body = 6;
}

message EmptyInit {
}

message ForIn {
    oneof value {
        int32 nameId = 1;
        Expression expression = 2;
    }
    required Expression iterable = 3;
    required Statement body = 4;
}

message Try {
    required Statement tryBlock = 1;
    optional Catch catchBlock = 2;
    optional Statement finallyBlock = 3;
}

message Catch {
    required Parameter parameter = 1;
    required Statement body = 2;
}

message Empty {
}

message SingleLineComment {
    required string message = 1;
}

message MultiLineComment {
    required string message = 1;
}

enum InlineStrategy {
    AS_FUNCTION = 0;
    IN_PLACE = 1;
    NOT_INLINE = 2;
}


// Fragment

message Fragment {
    repeated ImportedModule imported_module = 1;
    repeated Import import_entry = 2;
    optional CompositeBlock declaration_block = 3;
    optional CompositeBlock export_block = 4;
    optional CompositeBlock initializer_block = 5;
    repeated NameBinding name_binding = 6;
    repeated ClassModel class_model = 7;
    repeated Expression module_expression = 8;
    repeated InlineModule inline_module = 9;
    optional string package_fqn = 10;
    optional Statement tests_invocation = 11;
    optional Statement main_invocation = 12;
    repeated InlinedLocalDeclarations inlined_local_declarations = 13;
    repeated IrClassModel ir_class_model = 14;
    optional string dts = 15;
    optional int32 suite_function = 16;
    repeated int32 definitions = 17;
    optional CompositeBlock polyfills = 18;
    repeated int32 optionalCrossModuleImports = 19;
}

message InlinedLocalDeclarations {
    required int32 tag = 1;
    required CompositeBlock block = 2;
}

message ImportedModule {
    required int32 external_name_id = 1;
    required int32 internal_name_id = 2;
    optional Expression plain_reference = 3;
}

message Import {
    required int32 signature_id = 1;
    required Expression expression = 2;
}

message NameBinding {
    required int32 signature_id = 1;
    required int32 nameId = 2;
}

message ClassModel {
    required int32 name_id = 1;
    optional int32 super_name_id = 2;
    repeated int32 interface_name_id = 4;
    optional CompositeBlock post_declaration_block = 3;
}

message IrClassModel {
    required int32 name_id = 1;
    repeated int32 super_classes = 2;
    optional CompositeBlock pre_declaration_block = 3;
    optional CompositeBlock post_declaration_block = 4;
}

message InlineModule {
    required int32 signature_id = 1;
    required int32 expression_id = 2;
}

// Tables
//

message StringTable {
    repeated string entry = 1;
}

message NameTable {
    repeated Name entry = 1;
}

message Name {
    required bool temporary = 1;
    optional int32 identifier = 2;
    optional LocalAlias local_name_id = 3;
    optional bool imported = 4 [default = false];
    optional SpecialFunction special_function = 5;
}

message LocalAlias {
    required int32 local_name_id = 1;
    optional int32 tag = 2;
}

enum SpecialFunction {
    DEFINE_INLINE_FUNCTION = 1;
    WRAP_FUNCTION = 2;
    TO_BOXED_CHAR = 3;
    UNBOX_CHAR = 4;
    SUSPEND_CALL = 5;
    COROUTINE_RESULT = 6;
    COROUTINE_CONTROLLER = 7;
    COROUTINE_RECEIVER = 8;
    SET_COROUTINE_RESULT = 9;
    GET_KCLASS = 10;
    GET_REIFIED_TYPE_PARAMETER_KTYPE = 11;
}


// Chunk
//

message Chunk {
    required StringTable string_table = 1;
    required NameTable name_table = 2;
    required Fragment fragment = 3;
}

// InlineData
//

message InlineData {
    repeated string inline_function_tags = 1;
}
