// File: /workspace/github_cpp_makefile_star2_O3/AutomataLab[P]JSONSki/src/JSONPathParser.cpp
// Function: JSONPathParser::updateQueryAutomaton(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, QueryAutomaton&)
void JSONPathParser::updateQueryAutomaton(string query, QueryAutomaton &qa) {
    int length = query.size();
    int lexer_state = 0;
    int query_state = START_STATE;
    char buffer[MAX_KEY_LENGTH];
    for (int i = 0; i < length; ++i) {
        char ch = query[i];
        switch (lexer_state) {
            case 0: { // begin of the path
                if (ch == '.') {
                    lexer_state = 1;
                } else if (ch == '[') {
                    lexer_state = 2;
                    qa.updateStateTransInfo(query_state, false, NONE, ARRAY, NULL, query_state + 1);
                    // cout<<"("<<query_state<<", false, NONE, ARRAY, NULL, "<<(query_state + 1)<<")"<<endl;
                    ++query_state;
                }
                break;
            }
            case 1: { // in object
                int key_end = 0;
                while (ch != '.' && ch != '[') {
                    buffer[key_end++] = ch;
                    if (i + 1 == length) break;
                    ch = query[++i];
                }
                buffer[key_end] = '\0';
                if (i + 1 < length) {
                    if (ch == '[') {
                        lexer_state = 2;
                        // current query state -> expected key-array pair
                        qa.updateStateTransInfo(query_state, false, ARRAY, NONE, buffer, query_state + 1);
                        // cout<<"("<<query_state<<", false, ARRAY, NONE, "<<buffer<<", "<<(query_state + 1)<<")"<<endl;
                        // state transition for [
                        qa.updateStateTransInfo(query_state + 1, false, NONE, NONE, NULL, query_state + 2);
                        // cout<<"("<<(query_state + 1)<<", false, NONE, NONE, NULL, "<<(query_state + 2)<<")"<<endl;
                        query_state += 2;
                        // break;
                    } else if (ch == '.') {
                        lexer_state = 1;
                        qa.updateStateTransInfo(query_state, false, OBJECT, NONE, buffer, query_state + 1);
                        // cout<<"("<<query_state<<", false, OBJECT, NONE, "<<buffer<<", "<<(query_state + 1)<<")"<<endl;
                        ++query_state;
                        // break;
                    } 
                } else {
                    // output info
                    qa.updateStateTransInfo(query_state, false, PRIMITIVE, NONE, buffer, query_state + 1);
                    // cout<<"("<<query_state<<", false, PRIMITIVE, NONE, "<<buffer<<", "<<(query_state + 1)<<")"<<endl;
                    qa.updateStateTransInfo(query_state + 1, true, NONE, NONE, NULL, query_state + 1);
                    // cout<<"("<<(query_state + 1)<<", true, NONE, NONE, NULL, "<<(query_state + 1)<<")"<<endl;
                }
                break;
            }
            case 2: { // in array
                int start_idx = 0;
                int end_idx = -1;
                int index_end = 0;
                bool has_colon = false;
                while (ch != ']') {
                    if (ch == ':') {
                        buffer[index_end] = '\0';
                        start_idx = atoi(buffer);
                        end_idx = INT_MAX;
                        index_end = 0;
                        has_colon = true;
                    }
                    else if (ch >= '0' && ch <= '9') {
                        buffer[index_end++] = ch;
                    }
                    if (i + 1 == length) break;
                    ch = query[++i];
                }
                if (has_colon == false && index_end > 0) {
                    buffer[index_end] = '\0';
                    start_idx = atoi(buffer);
                    end_idx = start_idx + 1;
                } else if (index_end > 0) {
                    buffer[index_end] = '\0';
                    end_idx = atoi(buffer);
                }
                if (end_idx > -1) {
                    qa.addIndexConstraints(query_state, start_idx, end_idx);
                    // cout<<"index constraints "<<start_idx<<" "<<end_idx<<" current state "<<query_state<<endl;
                }
                if (i + 1 < length) {
                    ch = query[++i];
                    if (ch == '.') {
                        lexer_state = 1;
                        qa.updateStateTransInfo(query_state, false, NONE, OBJECT, NULL, query_state + 1);
                        // cout<<"("<<query_state<<", false, NONE, OBJECT, NULL, "<<(query_state + 1)<<")"<<endl;
                    } else if (ch == '[') {
                        cout<<"additional ["<<endl;
                        lexer_state = 2;
                        qa.updateStateTransInfo(query_state, false, NONE, ARRAY, NULL, query_state + 1);
                        // cout<<"("<<query_state<<", false, NONE, ARRAY, NULL, "<<(query_state + 1)<<")"<<endl;
                        ++query_state;
                    }
                } else {
                    qa.updateStateTransInfo(query_state, true, NONE, PRIMITIVE, NULL, query_state);
                    // cout<<"("<<query_state<<", false, NONE, PRIMITIVE, NULL, "<<(query_state + 1)<<")"<<endl;
                }
                break;
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, 0x18(%rsp)
movl 0x8(%rdi), %r9d
testl %r9d, %r9d
jle 0x165c6
movq %rsi, %rbx
addq $0x4, %rbx
leal -0x1(%r9), %r12d
movl $0x1, %eax
movq %rax, (%rsp)
xorl %r13d, %r13d
xorl %ebp, %ebp
movq %r9, 0x8(%rsp)
movslq %r13d, %rdx
movq 0x18(%rsp), %rax
movq (%rax), %r15
movb (%r15,%rdx), %cl
testl %ebp, %ebp
je 0x16217
cmpl $0x1, %ebp
jne 0x16261
movl %r9d, %eax
subl %edx, %eax
movl %r12d, %edi
subl %edx, %edi
leaq (%r15,%rdx), %r8
incq %r8
xorl %esi, %esi
movzbl %cl, %edx
cmpb $0x2e, %dl
je 0x162c2
cmpl $0x5b, %edx
je 0x162c2
movb %cl, 0x20(%rsp,%rsi)
cmpq %rsi, %rdi
je 0x163d6
movb (%r8,%rsi), %cl
incq %rsi
jmp 0x161ec
movzbl %cl, %eax
cmpl $0x2e, %eax
je 0x164eb
cmpl $0x5b, %eax
jne 0x163cf
movq (%rsp), %rcx
leal 0x1(%rcx), %eax
decl %ecx
movslq %ecx, %rcx
imulq $0x49c, %rcx, %rcx      # imm = 0x49C
movl $0x66, 0x6c(%rbx,%rcx)
movl %eax, 0x70(%rbx,%rcx)
movb $0x0, 0x48c(%rbx,%rcx)
movl $0x2, %ebp
movq %rax, (%rsp)
jmp 0x165ba
leaq (%r15,%rdx), %r14
incq %r14
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ebp, %ebp
xorl %edx, %edx
xorl %esi, %esi
cmpb $0x3a, %cl
je 0x16294
movzbl %cl, %edi
cmpl $0x5d, %edi
je 0x162cf
leal -0x30(%rcx), %edi
cmpb $0x9, %dil
ja 0x162b2
movslq %edx, %rdi
incl %edx
movb %cl, 0x20(%rsp,%rdi)
jmp 0x162b2
movslq %edx, %rax
movb $0x0, 0x20(%rsp,%rax)
leaq 0x20(%rsp), %rdi
callq 0x134c0
movl %eax, %ebp
movb $0x1, %sil
xorl %edx, %edx
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl %r13d, %r12d
je 0x162cc
movb (%r14), %cl
incl %r13d
incq %r14
jmp 0x16273
addl %esi, %r13d
movl %esi, %eax
jmp 0x163d9
movl %r12d, %r13d
testb $0x1, %sil
sete %cl
testl %edx, %edx
setg %sil
andb %cl, %sil
cmpb $0x1, %sil
jne 0x162fc
movl %edx, %eax
movb $0x0, 0x20(%rsp,%rax)
leaq 0x20(%rsp), %rdi
callq 0x134c0
movl %eax, %ebp
incl %eax
jmp 0x16311
testl %edx, %edx
jle 0x16311
movl %edx, %eax
movb $0x0, 0x20(%rsp,%rax)
leaq 0x20(%rsp), %rdi
callq 0x134c0
testl %eax, %eax
sets %cl
cmpl $0x0, (%rsp)
sete %dl
orb %cl, %dl
jne 0x16347
movq (%rsp), %rcx
decl %ecx
movslq %ecx, %rcx
imulq $0x49c, %rcx, %rcx      # imm = 0x49C
movb $0x1, 0x498(%rbx,%rcx)
movl %ebp, 0x490(%rbx,%rcx)
movl %eax, 0x494(%rbx,%rcx)
movslq %r13d, %r14
incq %r14
cmpl 0x8(%rsp), %r14d
jge 0x163a1
movzbl (%r15,%r14), %eax
movl $0x2, %ebp
cmpl $0x5b, %eax
je 0x16545
cmpl $0x2e, %eax
jne 0x165b2
movq (%rsp), %rcx
leal 0x1(%rcx), %eax
decl %ecx
movslq %ecx, %rcx
imulq $0x49c, %rcx, %rcx      # imm = 0x49C
movl $0x65, 0x6c(%rbx,%rcx)
movl %eax, 0x70(%rbx,%rcx)
movb $0x0, 0x48c(%rbx,%rcx)
movl $0x1, %ebp
jmp 0x165b2
movq (%rsp), %rcx
leal -0x1(%rcx), %eax
cltq
imulq $0x49c, %rax, %rax      # imm = 0x49C
movl $0x67, 0x6c(%rbx,%rax)
movl %ecx, 0x70(%rbx,%rax)
movb $0x1, 0x48c(%rbx,%rax)
movl $0x2, %ebp
jmp 0x165b5
xorl %ebp, %ebp
jmp 0x165ba
movl %r12d, %r13d
cltq
movb $0x0, 0x20(%rsp,%rax)
leal 0x1(%r13), %eax
cmpl %r9d, %eax
jge 0x16480
movl $0x1, %ebp
cmpb $0x2e, %cl
je 0x164f5
cmpl $0x5b, %edx
jne 0x165ba
movq (%rsp), %rbp
leal 0x1(%rbp), %eax
movl %eax, 0x14(%rsp)
leal -0x1(%rbp), %eax
cltq
imulq $0x49c, %rax, %r14      # imm = 0x49C
leaq (%rbx,%r14), %rdi
leaq 0x20(%rsp), %r15
movq %r15, %rsi
callq 0x135d0
movq %r15, %rdi
callq 0x13370
movl %eax, 0x64(%rbx,%r14)
movl $0x66, 0x68(%rbx,%r14)
movl 0x14(%rsp), %eax
movl %eax, 0x70(%rbx,%r14)
xorl %ecx, %ecx
movb %cl, 0x48c(%rbx,%r14)
movq 0x8(%rsp), %r9
movslq %ebp, %rax
addl $0x2, %ebp
imulq $0x49c, %rax, %rax      # imm = 0x49C
movq %rbp, (%rsp)
movl %ebp, 0x70(%rbx,%rax)
movb %cl, 0x48c(%rbx,%rax)
movl $0x2, %ebp
jmp 0x165ba
movq (%rsp), %rbp
leal 0x1(%rbp), %eax
movl %eax, 0x14(%rsp)
leal -0x1(%rbp), %eax
cltq
imulq $0x49c, %rax, %r14      # imm = 0x49C
leaq (%rbx,%r14), %rdi
leaq 0x20(%rsp), %r15
movq %r15, %rsi
callq 0x135d0
movq %r15, %rdi
callq 0x13370
movl %eax, 0x64(%rbx,%r14)
movl $0x67, 0x68(%rbx,%r14)
movl 0x14(%rsp), %ecx
movl %ecx, 0x70(%rbx,%r14)
movb $0x0, 0x48c(%rbx,%r14)
movq 0x8(%rsp), %r9
movslq %ebp, %rax
imulq $0x49c, %rax, %rax      # imm = 0x49C
movl %ecx, 0x70(%rbx,%rax)
movb $0x1, 0x48c(%rbx,%rax)
movl $0x1, %ebp
jmp 0x165ba
movq (%rsp), %rax
leal 0x1(%rax), %r14d
decl %eax
cltq
imulq $0x49c, %rax, %r15      # imm = 0x49C
leaq (%rbx,%r15), %rdi
leaq 0x20(%rsp), %rsi
callq 0x135d0
leaq 0x20(%rsp), %rdi
callq 0x13370
movl %eax, 0x64(%rbx,%r15)
movl $0x65, 0x68(%rbx,%r15)
movl %r14d, 0x70(%rbx,%r15)
movb $0x0, 0x48c(%rbx,%r15)
movl %r14d, %eax
movq %rax, (%rsp)
jmp 0x165b5
movl $0xc, %edx
leaq 0xe8f2f(%rip), %r15     # 0xff480
movq %r15, %rdi
leaq 0xaeaa9(%rip), %rsi     # 0xc5004
callq 0x8ec40
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x6fd90
movsbl %al, %esi
movq %r15, %rdi
callq 0x8e740
movq %rax, %rdi
callq 0x8dd10
movq (%rsp), %rcx
leal 0x1(%rcx), %eax
decl %ecx
movslq %ecx, %rcx
imulq $0x49c, %rcx, %rcx      # imm = 0x49C
movl $0x66, 0x6c(%rbx,%rcx)
movl %eax, 0x70(%rbx,%rcx)
movb $0x0, 0x48c(%rbx,%rcx)
movq %rax, (%rsp)
movl %r14d, %r13d
movq 0x8(%rsp), %r9
incl %r13d
cmpl %r9d, %r13d
jl 0x161bd
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq