//===- lib/Driver/WinLinkModuleDef.cpp ------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Windows module definition file parser.
///
//===----------------------------------------------------------------------===//

#include "lld/Driver/WinLinkModuleDef.h"
#include "llvm/ADT/StringSwitch.h"

namespace lld {
namespace moduledef {

Token Lexer::lex() {
  for (;;) {
    _buffer = _buffer.trim();
    if (_buffer.empty() || _buffer[0] == '\0')
      return Token(Kind::eof, _buffer);

    switch (_buffer[0]) {
    case ';': {
      size_t end = _buffer.find('\n');
      _buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end);
      continue;
    }
    case '=':
      _buffer = _buffer.drop_front();
      return Token(Kind::equal, "=");
    case ',':
      _buffer = _buffer.drop_front();
      return Token(Kind::comma, ",");
    case '"': {
      size_t end = _buffer.find('"', 1);
      Token ret;
      if (end == _buffer.npos) {
        ret = Token(Kind::identifier, _buffer.substr(1, end));
        _buffer = "";
      } else {
        ret = Token(Kind::identifier, _buffer.substr(1, end - 1));
        _buffer = _buffer.drop_front(end + 1);
      }
      return ret;
    }
    default: {
      size_t end = _buffer.find_first_not_of(
          "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
          "0123456789_.*~+!@#$%^&*()/");
      StringRef word = _buffer.substr(0, end);
      Kind kind = llvm::StringSwitch<Kind>(word)
                      .Case("BASE", Kind::kw_base)
                      .Case("DATA", Kind::kw_data)
                      .Case("EXPORTS", Kind::kw_exports)
                      .Case("HEAPSIZE", Kind::kw_heapsize)
                      .Case("LIBRARY", Kind::kw_library)
                      .Case("NAME", Kind::kw_name)
                      .Case("NONAME", Kind::kw_noname)
                      .Case("PRIVATE", Kind::kw_private)
                      .Case("STACKSIZE", Kind::kw_stacksize)
                      .Case("VERSION", Kind::kw_version)
                      .Default(Kind::identifier);
      _buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end);
      return Token(kind, word);
    }
    }
  }
}

void Parser::consumeToken() {
  if (_tokBuf.empty()) {
    _tok = _lex.lex();
    return;
  }
  _tok = _tokBuf.back();
  _tokBuf.pop_back();
}

bool Parser::consumeTokenAsInt(uint64_t &result) {
  consumeToken();
  if (_tok._kind != Kind::identifier) {
    ungetToken();
    error(_tok, "Integer expected");
    return false;
  }
  if (_tok._range.getAsInteger(10, result)) {
    error(_tok, "Integer expected");
    return false;
  }
  return true;
}

bool Parser::expectAndConsume(Kind kind, Twine msg) {
  consumeToken();
  if (_tok._kind != kind) {
    error(_tok, msg);
    return false;
  }
  return true;
}

void Parser::ungetToken() { _tokBuf.push_back(_tok); }

void Parser::error(const Token &tok, Twine msg) {
  _lex.getSourceMgr().PrintMessage(
      llvm::SMLoc::getFromPointer(tok._range.data()), llvm::SourceMgr::DK_Error,
      msg);
}

bool Parser::parse(std::vector<Directive *> &ret) {
  for (;;) {
    Directive *dir = nullptr;
    if (!parseOne(dir))
      return false;
    if (!dir)
      return true;
    ret.push_back(dir);
  }
}

bool Parser::parseOne(Directive *&ret) {
  consumeToken();
  switch (_tok._kind) {
  case Kind::eof:
    return true;
  case Kind::kw_exports: {
    // EXPORTS
    std::vector<PECOFFLinkingContext::ExportDesc> exports;
    for (;;) {
      PECOFFLinkingContext::ExportDesc desc;
      if (!parseExport(desc))
        break;
      exports.push_back(desc);
    }
    ret = new (_alloc) Exports(exports);
    return true;
  }
  case Kind::kw_heapsize: {
    // HEAPSIZE
    uint64_t reserve, commit;
    if (!parseMemorySize(reserve, commit))
      return false;
    ret = new (_alloc) Heapsize(reserve, commit);
    return true;
  }
  case Kind::kw_library: {
    // LIBRARY
    std::string name;
    uint64_t baseaddr;
    if (!parseName(name, baseaddr))
      return false;
    if (!StringRef(name).endswith_lower(".dll"))
      name.append(".dll");
    ret = new (_alloc) Library(name, baseaddr);
    return true;
  }
  case Kind::kw_stacksize: {
    // STACKSIZE
    uint64_t reserve, commit;
    if (!parseMemorySize(reserve, commit))
      return false;
    ret = new (_alloc) Stacksize(reserve, commit);
    return true;
  }
  case Kind::kw_name: {
    // NAME
    std::string outputPath;
    uint64_t baseaddr;
    if (!parseName(outputPath, baseaddr))
      return false;
    ret = new (_alloc) Name(outputPath, baseaddr);
    return true;
  }
  case Kind::kw_version: {
    // VERSION
    int major, minor;
    if (!parseVersion(major, minor))
      return false;
    ret = new (_alloc) Version(major, minor);
    return true;
  }
  default:
    error(_tok, Twine("Unknown directive: ") + _tok._range);
    return false;
  }
}

bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) {
  consumeToken();
  if (_tok._kind != Kind::identifier) {
    ungetToken();
    return false;
  }
  result.name = _tok._range;

  consumeToken();
  if (_tok._kind == Kind::equal) {
    consumeToken();
    if (_tok._kind != Kind::identifier)
      return false;
    result.externalName = result.name;
    result.name = _tok._range;
  } else {
    ungetToken();
  }

  for (;;) {
    consumeToken();
    if (_tok._kind == Kind::identifier && _tok._range[0] == '@') {
      _tok._range.drop_front().getAsInteger(10, result.ordinal);
      consumeToken();
      if (_tok._kind == Kind::kw_noname) {
        result.noname = true;
      } else {
        ungetToken();
      }
      continue;
    }
    if (_tok._kind == Kind::kw_data) {
      result.isData = true;
      continue;
    }
    if (_tok._kind == Kind::kw_private) {
      result.isPrivate = true;
      continue;
    }
    ungetToken();
    return true;
  }
}

// HEAPSIZE/STACKSIZE reserve[,commit]
bool Parser::parseMemorySize(uint64_t &reserve, uint64_t &commit) {
  if (!consumeTokenAsInt(reserve))
    return false;

  consumeToken();
  if (_tok._kind != Kind::comma) {
    ungetToken();
    commit = 0;
    return true;
  }

  if (!consumeTokenAsInt(commit))
    return false;
  return true;
}

// NAME [outputPath] [BASE=address]
bool Parser::parseName(std::string &outputPath, uint64_t &baseaddr) {
  consumeToken();
  if (_tok._kind == Kind::identifier) {
    outputPath = _tok._range;
  } else {
    outputPath = "";
    ungetToken();
    return true;
  }
  consumeToken();
  if (_tok._kind == Kind::kw_base) {
    if (!expectAndConsume(Kind::equal, "'=' expected"))
      return false;
    if (!consumeTokenAsInt(baseaddr))
      return false;
  } else {
    ungetToken();
    baseaddr = 0;
  }
  return true;
}

// VERSION major[.minor]
bool Parser::parseVersion(int &major, int &minor) {
  consumeToken();
  if (_tok._kind != Kind::identifier)
    return false;
  StringRef v1, v2;
  std::tie(v1, v2) = _tok._range.split('.');
  if (v1.getAsInteger(10, major))
    return false;
  if (v2.empty()) {
    minor = 0;
  } else if (v2.getAsInteger(10, minor)) {
    return false;
  }
  return true;
}

} // moddef
} // namespace lld
