// File: /workspace/github_c_makefile_star2_O3/justy989[P]ce/ce_app.c
// Function: extract_completion_from_response
CeComplete_t* _extract_completion_from_response(CeJsonObj_t* obj, CePoint_t* start){
     CeComplete_t* result = NULL;

     CeJsonFindResult_t result_find = ce_json_obj_find(obj, "result");
     if(result_find.type != CE_JSON_TYPE_OBJECT){
          return result;
     }

     // TODO: check isIncomplete

     CeJsonObj_t* result_obj = ce_json_obj_get_obj(obj, &result_find);

     CeJsonFindResult_t items_find = ce_json_obj_find(result_obj, "items");
     if(items_find.type != CE_JSON_TYPE_ARRAY){
          return result;
     }

     CeJsonArray_t* items_array = ce_json_obj_get_array(result_obj, &items_find);
     if(items_array == NULL){
          return result;
     }

     int64_t completion_count = 0;
     char** completions = NULL;
     char** descriptions = NULL;

     for(int64_t i = 0; i < items_array->count; i++){
          CeJsonValue_t* value = items_array->values + i;
          if(value->type != CE_JSON_TYPE_OBJECT){
               continue;
          }

          CeJsonFindResult_t insert_text_find = ce_json_obj_find(&value->obj, "insertText");
          if(insert_text_find.type != CE_JSON_TYPE_STRING){
               continue;
          }

          CeJsonFindResult_t detail_find = ce_json_obj_find(&value->obj, "detail");

          char* completion = strdup(ce_json_obj_get_string(&value->obj, &insert_text_find));


          CeJsonFindResult_t label_find = ce_json_obj_find(&value->obj, "label");

          char* description = NULL;
          if(label_find.type == CE_JSON_TYPE_STRING){
               int64_t completion_len = strlen(completion);
               char* match = strstr(ce_json_obj_get_string(&value->obj, &label_find),
                                    completion);
               if(match && strlen(match + completion_len) > 0){
                    char buffer[BUFSIZ];
                    if(detail_find.type == CE_JSON_TYPE_STRING){
                         snprintf(buffer, BUFSIZ, "%s%s",
                                  ce_json_obj_get_string(&value->obj, &detail_find),
                                  match + completion_len);
                    }else{
                         snprintf(buffer, BUFSIZ, "%s", match + completion_len);
                    }
                    description = strdup(buffer);
               }else if(detail_find.type == CE_JSON_TYPE_STRING){
                    description = strdup(ce_json_obj_get_string(&value->obj, &detail_find));
               }
          }else{
               description = strdup(ce_json_obj_get_string(&value->obj, &detail_find));
          }

          int64_t new_completion_count = completion_count + 1;
          completions = realloc(completions, new_completion_count * sizeof(completions[0]));
          descriptions = realloc(descriptions, new_completion_count * sizeof(descriptions[0]));
          completions[completion_count] = completion;
          descriptions[completion_count] = description;
          completion_count = new_completion_count;

          CeJsonFindResult_t text_edit_find = ce_json_obj_find(&value->obj, "textEdit");
          if(text_edit_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* text_edit_obj = ce_json_obj_get_obj(&value->obj, &text_edit_find);
          if(text_edit_obj == NULL){
               continue;
          }
          CeJsonFindResult_t range_find = ce_json_obj_find(text_edit_obj, "range");
          if(range_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* range_obj = ce_json_obj_get_obj(text_edit_obj, &range_find);
          if(range_obj == NULL){
               continue;
          }
          CeJsonFindResult_t start_find = ce_json_obj_find(range_obj, "start");
          if(start_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* start_obj = ce_json_obj_get_obj(range_obj, &start_find);
          if(start_obj == NULL){
               continue;
          }
          CeJsonFindResult_t line_find = ce_json_obj_find(start_obj, "line");
          if(line_find.type != CE_JSON_TYPE_NUMBER){
               continue;
          }
          CeJsonFindResult_t character_find = ce_json_obj_find(start_obj, "character");
          if(character_find.type != CE_JSON_TYPE_NUMBER){
               continue;
          }
          start->x = *ce_json_obj_get_number(start_obj, &character_find);
          start->y = *ce_json_obj_get_number(start_obj, &line_find);
     }

     result = malloc(sizeof(*result));
     memset(result, 0, sizeof(*result));
     ce_complete_init(result, (const char**)completions, (const char**)descriptions, completion_count);
     for(int64_t i = 0; i < completion_count; i++){
          free(completions[i]);
          free(descriptions[i]);
     }
     free(completions);
     free(descriptions);
     return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20d8, %rsp           # imm = 0x20D8
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x1c396(%rip), %rsi     # 0x2ebb9
callq 0x1c943
movl %eax, 0xc0(%rsp)
movq %rdx, 0xc8(%rsp)
cmpl $0x1, %eax
jne 0x12bc3
leaq 0xc0(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c996
movq %rax, %rbx
leaq 0x1c366(%rip), %rsi     # 0x2ebc0
movq %rax, %rdi
callq 0x1c943
movl %eax, 0xb0(%rsp)
movq %rdx, 0xb8(%rsp)
cmpl $0x2, %eax
jne 0x12bc3
leaq 0xb0(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c9b1
testq %rax, %rax
je 0x12bc3
movq %rax, %rbx
movq 0x8(%rax), %rax
testq %rax, %rax
jle 0x12bda
movq %r14, 0x30(%rsp)
movl $0x8, %r12d
leaq 0x1c311(%rip), %r14     # 0x2ebc6
xorl %r13d, %r13d
movq $0x0, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
xorl %r15d, %r15d
movq %rbx, 0x38(%rsp)
movq (%rbx), %rbp
cmpl $0x1, -0x8(%rbp,%r12)
jne 0x12bb1
addq %r12, %rbp
movq %rbp, %rdi
movq %r14, %rsi
callq 0x1c943
movl %eax, 0xa0(%rsp)
movq %rdx, 0xa8(%rsp)
cmpl $0x3, %eax
jne 0x12bad
movq %r13, 0x48(%rsp)
movq %rbp, %rdi
leaq 0x1c2bb(%rip), %rsi     # 0x2ebd1
callq 0x1c943
movl %eax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
movq %rbp, %rdi
leaq 0xa0(%rsp), %rsi
callq 0x1c9cc
movq %rax, %rdi
callq 0xd640
movq %rax, %rbx
movq %rbp, %rdi
leaq 0x1c28f(%rip), %rsi     # 0x2ebd8
callq 0x1c943
movl %eax, 0x90(%rsp)
movq %rdx, 0x98(%rsp)
cmpl $0x3, %eax
movq %rbx, 0x40(%rsp)
jne 0x129e0
movq %rbx, %rdi
callq 0xd210
movq %rax, %r14
movq %rbp, %rdi
leaq 0x90(%rsp), %rsi
callq 0x1c9cc
movq %rax, %rdi
movq %rbx, %rsi
callq 0xd6f0
testq %rax, %rax
je 0x129d9
movq %rax, %r13
cmpb $0x0, (%rax,%r14)
je 0x129d9
addq %r14, %r13
cmpl $0x3, 0x20(%rsp)
jne 0x129fd
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1c9cc
movl $0x2000, %esi           # imm = 0x2000
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1c214(%rip), %rdx     # 0x2ebde
movq %rax, %rcx
movq %r13, %r8
xorl %eax, %eax
callq 0xd260
jmp 0x12a1e
cmpl $0x3, 0x20(%rsp)
jne 0x129f2
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1c9cc
movq %rax, %rdi
jmp 0x12a21
movq $0x0, 0x8(%rsp)
jmp 0x12a2b
movl $0x2000, %esi           # imm = 0x2000
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1df52(%rip), %rdx     # 0x30966
movq %r13, %rcx
xorl %eax, %eax
callq 0xd260
movq %rbx, %rdi
callq 0xd640
movq %rax, 0x8(%rsp)
movq 0x48(%rsp), %r13
leaq 0x8(,%r13,8), %r14
movq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0xd520
movq %rax, %rbx
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0xd520
movq %rbx, 0x10(%rsp)
movq 0x40(%rsp), %rcx
movq %rcx, (%rbx,%r13,8)
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rcx
movq %rcx, (%rax,%r13,8)
movq %rbp, %rdi
leaq 0x1c168(%rip), %rsi     # 0x2ebe3
callq 0x1c943
movl %eax, 0xd0(%rsp)
movq %rdx, 0xd8(%rsp)
cmpl $0x1, %eax
leaq 0x1c12d(%rip), %r14     # 0x2ebc6
jne 0x12ba5
movq %rbp, %rdi
leaq 0xd0(%rsp), %rsi
callq 0x1c996
testq %rax, %rax
je 0x12ba5
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1c127(%rip), %rsi     # 0x2ebec
callq 0x1c943
movl %eax, 0x80(%rsp)
movq %rdx, 0x88(%rsp)
cmpl $0x1, %eax
jne 0x12ba5
movq %rbx, %rdi
leaq 0x80(%rsp), %rsi
callq 0x1c996
testq %rax, %rax
je 0x12ba5
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1abc1(%rip), %rsi     # 0x2d6c9
callq 0x1c943
movl %eax, 0x70(%rsp)
movq %rdx, 0x78(%rsp)
cmpl $0x1, %eax
jne 0x12ba5
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x1c996
testq %rax, %rax
je 0x12ba5
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1b17f(%rip), %rsi     # 0x2dcbd
callq 0x1c943
movl %eax, 0x60(%rsp)
movq %rdx, 0x68(%rsp)
cmpl $0x4, %eax
jne 0x12ba5
movq %rbx, %rdi
leaq 0x1c097(%rip), %rsi     # 0x2ebf2
callq 0x1c943
movl %eax, 0x50(%rsp)
movq %rdx, 0x58(%rsp)
cmpl $0x4, %eax
jne 0x12ba5
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
callq 0x1c9e5
cvttsd2si (%rax), %rax
movq 0x30(%rsp), %r14
movq %rax, (%r14)
movq %rbx, %rdi
leaq 0x60(%rsp), %rsi
callq 0x1c9e5
cvttsd2si (%rax), %rax
movq %rax, 0x8(%r14)
leaq 0x1c021(%rip), %r14     # 0x2ebc6
incq %r13
movq 0x38(%rsp), %rbx
movq 0x8(%rbx), %rax
incq %r15
addq $0x18, %r12
cmpq %rax, %r15
jl 0x128d2
jmp 0x12bef
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x20d8, %rsp           # imm = 0x20D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq $0x0, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r13d, %r13d
movl $0x1, %edi
movl $0x20, %esi
callq 0xd380
movq %rax, %rbx
movq %rax, %rdi
movq 0x10(%rsp), %r12
movq %r12, %rsi
movq 0x18(%rsp), %r15
movq %r15, %rdx
movq %r13, %rcx
callq 0x1994c
testq %r13, %r13
jle 0x12c3e
xorl %r14d, %r14d
movq (%r12,%r14,8), %rdi
callq 0xd090
movq (%r15,%r14,8), %rdi
callq 0xd090
incq %r14
cmpq %r14, %r13
jne 0x12c24
movq %r12, %rdi
callq 0xd090
movq %r15, %rdi
callq 0xd090
jmp 0x12bc5