//===-- Variable.cpp --------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/Variable.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"

#include "llvm/ADT/Twine.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// Variable constructor
//----------------------------------------------------------------------
Variable::Variable(
    lldb::user_id_t uid, const char *name,
    const char *mangled, // The mangled or fully qualified name of the variable.
    const lldb::SymbolFileTypeSP &symfile_type_sp, ValueType scope,
    SymbolContextScope *context, const RangeList &scope_range,
    Declaration *decl_ptr, const DWARFExpression &location, bool external,
    bool artificial, bool static_member)
    : UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
      m_symfile_type_sp(symfile_type_sp), m_scope(scope),
      m_owner_scope(context), m_scope_range(scope_range),
      m_declaration(decl_ptr), m_location(location), m_external(external),
      m_artificial(artificial), m_static_member(static_member) {}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
Variable::~Variable() {}

lldb::LanguageType Variable::GetLanguage() const {
  SymbolContext variable_sc;
  m_owner_scope->CalculateSymbolContext(&variable_sc);
  if (variable_sc.comp_unit)
    return variable_sc.comp_unit->GetLanguage();
  return lldb::eLanguageTypeUnknown;
}

ConstString Variable::GetName() const {
  ConstString name = m_mangled.GetName(GetLanguage());
  if (name)
    return name;
  return m_name;
}

ConstString Variable::GetUnqualifiedName() const { return m_name; }

bool Variable::NameMatches(const ConstString &name) const {
  if (m_name == name)
    return true;
  SymbolContext variable_sc;
  m_owner_scope->CalculateSymbolContext(&variable_sc);

  LanguageType language = eLanguageTypeUnknown;
  if (variable_sc.comp_unit)
    language = variable_sc.comp_unit->GetLanguage();
  return m_mangled.NameMatches(name, language);
}
bool Variable::NameMatches(const RegularExpression &regex) const {
  if (regex.Execute(m_name.AsCString()))
    return true;
  if (m_mangled)
    return m_mangled.NameMatches(regex, GetLanguage());
  return false;
}

Type *Variable::GetType() {
  if (m_symfile_type_sp)
    return m_symfile_type_sp->GetType();
  return nullptr;
}

void Variable::Dump(Stream *s, bool show_context) const {
  s->Printf("%p: ", static_cast<const void *>(this));
  s->Indent();
  *s << "Variable" << (const UserID &)*this;

  if (m_name)
    *s << ", name = \"" << m_name << "\"";

  if (m_symfile_type_sp) {
    Type *type = m_symfile_type_sp->GetType();
    if (type) {
      *s << ", type = {" << type->GetID() << "} " << (void *)type << " (";
      type->DumpTypeName(s);
      s->PutChar(')');
    }
  }

  if (m_scope != eValueTypeInvalid) {
    s->PutCString(", scope = ");
    switch (m_scope) {
    case eValueTypeVariableGlobal:
      s->PutCString(m_external ? "global" : "static");
      break;
    case eValueTypeVariableArgument:
      s->PutCString("parameter");
      break;
    case eValueTypeVariableLocal:
      s->PutCString("local");
      break;
    case eValueTypeVariableThreadLocal:
      s->PutCString("thread local");
      break;
    default:
      *s << "??? (" << m_scope << ')';
    }
  }

  if (show_context && m_owner_scope != nullptr) {
    s->PutCString(", context = ( ");
    m_owner_scope->DumpSymbolContext(s);
    s->PutCString(" )");
  }

  bool show_fullpaths = false;
  m_declaration.Dump(s, show_fullpaths);

  if (m_location.IsValid()) {
    s->PutCString(", location = ");
    lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
    if (m_location.IsLocationList()) {
      SymbolContext variable_sc;
      m_owner_scope->CalculateSymbolContext(&variable_sc);
      if (variable_sc.function)
        loclist_base_addr = variable_sc.function->GetAddressRange()
                                .GetBaseAddress()
                                .GetFileAddress();
    }
    ABI *abi = nullptr;
    if (m_owner_scope) {
      ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
      if (module_sp)
        abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()).get();
    }
    m_location.GetDescription(s, lldb::eDescriptionLevelBrief,
                              loclist_base_addr, abi);
  }

  if (m_external)
    s->PutCString(", external");

  if (m_artificial)
    s->PutCString(", artificial");

  s->EOL();
}

bool Variable::DumpDeclaration(Stream *s, bool show_fullpaths,
                               bool show_module) {
  bool dumped_declaration_info = false;
  if (m_owner_scope) {
    SymbolContext sc;
    m_owner_scope->CalculateSymbolContext(&sc);
    sc.block = nullptr;
    sc.line_entry.Clear();
    bool show_inlined_frames = false;
    const bool show_function_arguments = true;
    const bool show_function_name = true;

    dumped_declaration_info = sc.DumpStopContext(
        s, nullptr, Address(), show_fullpaths, show_module, show_inlined_frames,
        show_function_arguments, show_function_name);

    if (sc.function)
      s->PutChar(':');
  }
  if (m_declaration.DumpStopContext(s, false))
    dumped_declaration_info = true;
  return dumped_declaration_info;
}

size_t Variable::MemorySize() const { return sizeof(Variable); }

CompilerDeclContext Variable::GetDeclContext() {
  Type *type = GetType();
  if (type)
    return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
  return CompilerDeclContext();
}

CompilerDecl Variable::GetDecl() {
  Type *type = GetType();
  return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl();
}

void Variable::CalculateSymbolContext(SymbolContext *sc) {
  if (m_owner_scope) {
    m_owner_scope->CalculateSymbolContext(sc);
    sc->variable = this;
  } else
    sc->Clear(false);
}

bool Variable::LocationIsValidForFrame(StackFrame *frame) {
  // Is the variable is described by a single location?
  if (!m_location.IsLocationList()) {
    // Yes it is, the location is valid.
    return true;
  }

  if (frame) {
    Function *function =
        frame->GetSymbolContext(eSymbolContextFunction).function;
    if (function) {
      TargetSP target_sp(frame->CalculateTarget());

      addr_t loclist_base_load_addr =
          function->GetAddressRange().GetBaseAddress().GetLoadAddress(
              target_sp.get());
      if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
        return false;
      // It is a location list. We just need to tell if the location list
      // contains the current address when converted to a load address
      return m_location.LocationListContainsAddress(
          loclist_base_load_addr,
          frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));
    }
  }
  return false;
}

bool Variable::LocationIsValidForAddress(const Address &address) {
  // Be sure to resolve the address to section offset prior to calling this
  // function.
  if (address.IsSectionOffset()) {
    SymbolContext sc;
    CalculateSymbolContext(&sc);
    if (sc.module_sp == address.GetModule()) {
      // Is the variable is described by a single location?
      if (!m_location.IsLocationList()) {
        // Yes it is, the location is valid.
        return true;
      }

      if (sc.function) {
        addr_t loclist_base_file_addr =
            sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
        if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
          return false;
        // It is a location list. We just need to tell if the location list
        // contains the current address when converted to a load address
        return m_location.LocationListContainsAddress(loclist_base_file_addr,
                                                      address.GetFileAddress());
      }
    }
  }
  return false;
}

bool Variable::IsInScope(StackFrame *frame) {
  switch (m_scope) {
  case eValueTypeRegister:
  case eValueTypeRegisterSet:
    return frame != nullptr;

  case eValueTypeConstResult:
  case eValueTypeVariableGlobal:
  case eValueTypeVariableStatic:
  case eValueTypeVariableThreadLocal:
    return true;

  case eValueTypeVariableArgument:
  case eValueTypeVariableLocal:
    if (frame) {
      // We don't have a location list, we just need to see if the block that
      // this variable was defined in is currently
      Block *deepest_frame_block =
          frame->GetSymbolContext(eSymbolContextBlock).block;
      if (deepest_frame_block) {
        SymbolContext variable_sc;
        CalculateSymbolContext(&variable_sc);

        // Check for static or global variable defined at the compile unit
        // level that wasn't defined in a block
        if (variable_sc.block == nullptr)
          return true;

        // Check if the variable is valid in the current block
        if (variable_sc.block != deepest_frame_block &&
            !variable_sc.block->Contains(deepest_frame_block))
          return false;

        // If no scope range is specified then it means that the scope is the
        // same as the scope of the enclosing lexical block.
        if (m_scope_range.IsEmpty())
          return true;

        addr_t file_address = frame->GetFrameCodeAddress().GetFileAddress();
        return m_scope_range.FindEntryThatContains(file_address) != nullptr;
      }
    }
    break;

  default:
    break;
  }
  return false;
}

Status Variable::GetValuesForVariableExpressionPath(
    llvm::StringRef variable_expr_path, ExecutionContextScope *scope,
    GetVariableCallback callback, void *baton, VariableList &variable_list,
    ValueObjectList &valobj_list) {
  Status error;
  if (!callback || variable_expr_path.empty()) {
    error.SetErrorString("unknown error");
    return error;
  }

  switch (variable_expr_path.front()) {
  case '*':
    error = Variable::GetValuesForVariableExpressionPath(
        variable_expr_path.drop_front(), scope, callback, baton, variable_list,
        valobj_list);
    if (error.Fail()) {
      error.SetErrorString("unknown error");
      return error;
    }
    for (uint32_t i = 0; i < valobj_list.GetSize();) {
      Status tmp_error;
      ValueObjectSP valobj_sp(
          valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error));
      if (tmp_error.Fail()) {
        variable_list.RemoveVariableAtIndex(i);
        valobj_list.RemoveValueObjectAtIndex(i);
      } else {
        valobj_list.SetValueObjectAtIndex(i, valobj_sp);
        ++i;
      }
    }
    return error;
  case '&': {
    error = Variable::GetValuesForVariableExpressionPath(
        variable_expr_path.drop_front(), scope, callback, baton, variable_list,
        valobj_list);
    if (error.Success()) {
      for (uint32_t i = 0; i < valobj_list.GetSize();) {
        Status tmp_error;
        ValueObjectSP valobj_sp(
            valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error));
        if (tmp_error.Fail()) {
          variable_list.RemoveVariableAtIndex(i);
          valobj_list.RemoveValueObjectAtIndex(i);
        } else {
          valobj_list.SetValueObjectAtIndex(i, valobj_sp);
          ++i;
        }
      }
    } else {
      error.SetErrorString("unknown error");
    }
    return error;
  } break;

  default: {
    static RegularExpression g_regex(
        llvm::StringRef("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)"));
    RegularExpression::Match regex_match(1);
    std::string variable_name;
    variable_list.Clear();
    if (!g_regex.Execute(variable_expr_path, &regex_match)) {
      error.SetErrorStringWithFormat(
          "unable to extract a variable name from '%s'",
          variable_expr_path.str().c_str());
      return error;
    }
    if (!regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name)) {
      error.SetErrorStringWithFormat(
          "unable to extract a variable name from '%s'",
          variable_expr_path.str().c_str());
      return error;
    }
    if (!callback(baton, variable_name.c_str(), variable_list)) {
      error.SetErrorString("unknown error");
      return error;
    }
    uint32_t i = 0;
    while (i < variable_list.GetSize()) {
      VariableSP var_sp(variable_list.GetVariableAtIndex(i));
      ValueObjectSP valobj_sp;
      if (!var_sp) {
        variable_list.RemoveVariableAtIndex(i);
        continue;
      }
      ValueObjectSP variable_valobj_sp(
          ValueObjectVariable::Create(scope, var_sp));
      if (!variable_valobj_sp) {
        variable_list.RemoveVariableAtIndex(i);
        continue;
      }

      llvm::StringRef variable_sub_expr_path =
          variable_expr_path.drop_front(variable_name.size());
      if (!variable_sub_expr_path.empty()) {
        valobj_sp = variable_valobj_sp->GetValueForExpressionPath(
            variable_sub_expr_path);
        if (!valobj_sp) {
          error.SetErrorStringWithFormat(
              "invalid expression path '%s' for variable '%s'",
              variable_sub_expr_path.str().c_str(),
              var_sp->GetName().GetCString());
          variable_list.RemoveVariableAtIndex(i);
          continue;
        }
      } else {
        // Just the name of a variable with no extras
        valobj_sp = variable_valobj_sp;
      }

      valobj_list.Append(valobj_sp);
      ++i;
    }

    if (variable_list.GetSize() > 0) {
      error.Clear();
      return error;
    }
  } break;
  }
  error.SetErrorString("unknown error");
  return error;
}

bool Variable::DumpLocationForAddress(Stream *s, const Address &address) {
  // Be sure to resolve the address to section offset prior to calling this
  // function.
  if (address.IsSectionOffset()) {
    SymbolContext sc;
    CalculateSymbolContext(&sc);
    if (sc.module_sp == address.GetModule()) {
      ABI *abi = nullptr;
      if (m_owner_scope) {
        ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
        if (module_sp)
          abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()).get();
      }

      const addr_t file_addr = address.GetFileAddress();
      if (sc.function) {
        if (sc.function->GetAddressRange().ContainsFileAddress(address)) {
          addr_t loclist_base_file_addr =
              sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
          if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
            return false;
          return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief,
                                                   loclist_base_file_addr,
                                                   file_addr, abi);
        }
      }
      return m_location.DumpLocationForAddress(
          s, eDescriptionLevelBrief, LLDB_INVALID_ADDRESS, file_addr, abi);
    }
  }
  return false;
}

static void PrivateAutoComplete(
    StackFrame *frame, llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type,
    StringList &matches, bool &word_complete);

static void PrivateAutoCompleteMembers(
    StackFrame *frame, const std::string &partial_member_name,
    llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type,
    StringList &matches, bool &word_complete);

static void PrivateAutoCompleteMembers(
    StackFrame *frame, const std::string &partial_member_name,
    llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type,
    StringList &matches, bool &word_complete) {

  // We are in a type parsing child members
  const uint32_t num_bases = compiler_type.GetNumDirectBaseClasses();

  if (num_bases > 0) {
    for (uint32_t i = 0; i < num_bases; ++i) {
      CompilerType base_class_type =
          compiler_type.GetDirectBaseClassAtIndex(i, nullptr);

      PrivateAutoCompleteMembers(
          frame, partial_member_name, partial_path, prefix_path,
          base_class_type.GetCanonicalType(), matches, word_complete);
    }
  }

  const uint32_t num_vbases = compiler_type.GetNumVirtualBaseClasses();

  if (num_vbases > 0) {
    for (uint32_t i = 0; i < num_vbases; ++i) {
      CompilerType vbase_class_type =
          compiler_type.GetVirtualBaseClassAtIndex(i, nullptr);

      PrivateAutoCompleteMembers(
          frame, partial_member_name, partial_path, prefix_path,
          vbase_class_type.GetCanonicalType(), matches, word_complete);
    }
  }

  // We are in a type parsing child members
  const uint32_t num_fields = compiler_type.GetNumFields();

  if (num_fields > 0) {
    for (uint32_t i = 0; i < num_fields; ++i) {
      std::string member_name;

      CompilerType member_compiler_type = compiler_type.GetFieldAtIndex(
          i, member_name, nullptr, nullptr, nullptr);

      if (partial_member_name.empty() ||
          member_name.find(partial_member_name) == 0) {
        if (member_name == partial_member_name) {
          PrivateAutoComplete(
              frame, partial_path,
              prefix_path + member_name, // Anything that has been resolved
                                         // already will be in here
              member_compiler_type.GetCanonicalType(), matches, word_complete);
        } else {
          matches.AppendString((prefix_path + member_name).str());
        }
      }
    }
  }
}

static void PrivateAutoComplete(
    StackFrame *frame, llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type,
    StringList &matches, bool &word_complete) {
  //    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path =
  //    '%s'\n", prefix_path.c_str(), partial_path.c_str());
  std::string remaining_partial_path;

  const lldb::TypeClass type_class = compiler_type.GetTypeClass();
  if (partial_path.empty()) {
    if (compiler_type.IsValid()) {
      switch (type_class) {
      default:
      case eTypeClassArray:
      case eTypeClassBlockPointer:
      case eTypeClassBuiltin:
      case eTypeClassComplexFloat:
      case eTypeClassComplexInteger:
      case eTypeClassEnumeration:
      case eTypeClassFunction:
      case eTypeClassMemberPointer:
      case eTypeClassReference:
      case eTypeClassTypedef:
      case eTypeClassVector: {
        matches.AppendString(prefix_path.str());
        word_complete = matches.GetSize() == 1;
      } break;

      case eTypeClassClass:
      case eTypeClassStruct:
      case eTypeClassUnion:
        if (prefix_path.str().back() != '.')
          matches.AppendString((prefix_path + ".").str());
        break;

      case eTypeClassObjCObject:
      case eTypeClassObjCInterface:
        break;
      case eTypeClassObjCObjectPointer:
      case eTypeClassPointer: {
        bool omit_empty_base_classes = true;
        if (compiler_type.GetNumChildren(omit_empty_base_classes) > 0)
          matches.AppendString((prefix_path + "->").str());
        else {
          matches.AppendString(prefix_path.str());
          word_complete = true;
        }
      } break;
      }
    } else {
      if (frame) {
        const bool get_file_globals = true;

        VariableList *variable_list = frame->GetVariableList(get_file_globals);

        if (variable_list) {
          const size_t num_variables = variable_list->GetSize();
          for (size_t i = 0; i < num_variables; ++i) {
            Variable *variable = variable_list->GetVariableAtIndex(i).get();
            matches.AppendString(variable->GetName().AsCString());
          }
        }
      }
    }
  } else {
    const char ch = partial_path[0];
    switch (ch) {
    case '*':
      if (prefix_path.str().empty()) {
        PrivateAutoComplete(frame, partial_path.substr(1), "*", compiler_type,
                            matches, word_complete);
      }
      break;

    case '&':
      if (prefix_path.isTriviallyEmpty()) {
        PrivateAutoComplete(frame, partial_path.substr(1), std::string("&"),
                            compiler_type, matches, word_complete);
      }
      break;

    case '-':
      if (partial_path.size() > 1 && partial_path[1] == '>' &&
          !prefix_path.str().empty()) {
        switch (type_class) {
        case lldb::eTypeClassPointer: {
          CompilerType pointee_type(compiler_type.GetPointeeType());
          if (partial_path.size() > 2 && partial_path[2]) {
            // If there is more after the "->", then search deeper
            PrivateAutoComplete(
                frame, partial_path.substr(2), prefix_path + "->",
                pointee_type.GetCanonicalType(), matches, word_complete);
          } else {
            // Nothing after the "->", so list all members
            PrivateAutoCompleteMembers(
                frame, std::string(), std::string(), prefix_path + "->",
                pointee_type.GetCanonicalType(), matches, word_complete);
          }
        } break;
        default:
          break;
        }
      }
      break;

    case '.':
      if (compiler_type.IsValid()) {
        switch (type_class) {
        case lldb::eTypeClassUnion:
        case lldb::eTypeClassStruct:
        case lldb::eTypeClassClass:
          if (partial_path.size() > 1 && partial_path[1]) {
            // If there is more after the ".", then search deeper
            PrivateAutoComplete(frame, partial_path.substr(1),
                                prefix_path + ".", compiler_type, matches,
                                word_complete);

          } else {
            // Nothing after the ".", so list all members
            PrivateAutoCompleteMembers(frame, std::string(), partial_path,
                                       prefix_path + ".", compiler_type,
                                       matches, word_complete);
          }
          break;
        default:
          break;
        }
      }
      break;
    default:
      if (isalpha(ch) || ch == '_' || ch == '$') {
        const size_t partial_path_len = partial_path.size();
        size_t pos = 1;
        while (pos < partial_path_len) {
          const char curr_ch = partial_path[pos];
          if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$') {
            ++pos;
            continue;
          }
          break;
        }

        std::string token(partial_path, 0, pos);
        remaining_partial_path = partial_path.substr(pos);

        if (compiler_type.IsValid()) {
          PrivateAutoCompleteMembers(frame, token, remaining_partial_path,
                                     prefix_path, compiler_type, matches,
                                     word_complete);
        } else if (frame) {
          // We haven't found our variable yet
          const bool get_file_globals = true;

          VariableList *variable_list =
              frame->GetVariableList(get_file_globals);

          if (!variable_list)
            break;

          const size_t num_variables = variable_list->GetSize();
          for (size_t i = 0; i < num_variables; ++i) {
            Variable *variable = variable_list->GetVariableAtIndex(i).get();

            if (!variable)
              continue;

            const char *variable_name = variable->GetName().AsCString();
            if (strstr(variable_name, token.c_str()) == variable_name) {
              if (strcmp(variable_name, token.c_str()) == 0) {
                Type *variable_type = variable->GetType();
                if (variable_type) {
                  CompilerType variable_compiler_type(
                      variable_type->GetForwardCompilerType());
                  PrivateAutoComplete(
                      frame, remaining_partial_path,
                      prefix_path + token, // Anything that has been resolved
                                           // already will be in here
                      variable_compiler_type.GetCanonicalType(), matches,
                      word_complete);
                } else {
                  matches.AppendString((prefix_path + variable_name).str());
                }
              } else if (remaining_partial_path.empty()) {
                matches.AppendString((prefix_path + variable_name).str());
              }
            }
          }
        }
      }
      break;
    }
  }
}

size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
                              CompletionRequest &request) {
  CompilerType compiler_type;

  bool word_complete = false;
  StringList matches;
  PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
                      "", compiler_type, matches, word_complete);
  request.SetWordComplete(word_complete);
  request.AddCompletions(matches);

  return request.GetNumberOfMatches();
}
