// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/fm2js/xfa_lexer.h"

#include "core/fxcrt/fx_ext.h"

namespace {

struct XFA_FMDChar {
  static const FX_WCHAR* inc(const FX_WCHAR*& p) {
    ++p;
    return p;
  }
  static const FX_WCHAR* dec(const FX_WCHAR*& p) {
    --p;
    return p;
  }
  static uint16_t get(const FX_WCHAR* p) { return *p; }
  static bool isWhiteSpace(const FX_WCHAR* p) {
    return (*p) == 0x09 || (*p) == 0x0b || (*p) == 0x0c || (*p) == 0x20;
  }
  static bool isLineTerminator(const FX_WCHAR* p) {
    return *p == 0x0A || *p == 0x0D;
  }
  static bool isBinary(const FX_WCHAR* p) { return (*p) >= '0' && (*p) <= '1'; }
  static bool isOctal(const FX_WCHAR* p) { return (*p) >= '0' && (*p) <= '7'; }
  static bool isDigital(const FX_WCHAR* p) {
    return (*p) >= '0' && (*p) <= '9';
  }
  static bool isHex(const FX_WCHAR* p) {
    return isDigital(p) || ((*p) >= 'a' && (*p) <= 'f') ||
           ((*p) >= 'A' && (*p) <= 'F');
  }
  static bool isAlpha(const FX_WCHAR* p) {
    return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
  }
  static bool isAvalid(const FX_WCHAR* p, bool flag = 0);
  static bool string2number(const FX_WCHAR* s,
                            FX_DOUBLE* pValue,
                            const FX_WCHAR*& pEnd);
  static bool isUnicodeAlpha(uint16_t ch);
};

inline bool XFA_FMDChar::isAvalid(const FX_WCHAR* p, bool flag) {
  if (*p == 0) {
    return 1;
  }
  if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D ||
      (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
    return 1;
  }
  if (!flag) {
    if (*p == 0x0B || *p == 0x0C) {
      return 1;
    }
  }
  return 0;
}

inline bool XFA_FMDChar::string2number(const FX_WCHAR* s,
                                       FX_DOUBLE* pValue,
                                       const FX_WCHAR*& pEnd) {
  if (s) {
    *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd);
  }
  return 0;
}

inline bool XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
  if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
      ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
      ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' ||
      ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
      ch == '+' || ch == '-' || ch == '*' || ch == '/') {
    return false;
  }
  return true;
}

const XFA_FMKeyword keyWords[] = {
    {TOKand, 0x00000026, L"&"},
    {TOKlparen, 0x00000028, L"("},
    {TOKrparen, 0x00000029, L")"},
    {TOKmul, 0x0000002a, L"*"},
    {TOKplus, 0x0000002b, L"+"},
    {TOKcomma, 0x0000002c, L","},
    {TOKminus, 0x0000002d, L"-"},
    {TOKdot, 0x0000002e, L"."},
    {TOKdiv, 0x0000002f, L"/"},
    {TOKlt, 0x0000003c, L"<"},
    {TOKassign, 0x0000003d, L"="},
    {TOKgt, 0x0000003e, L">"},
    {TOKlbracket, 0x0000005b, L"["},
    {TOKrbracket, 0x0000005d, L"]"},
    {TOKor, 0x0000007c, L"|"},
    {TOKdotscream, 0x0000ec11, L".#"},
    {TOKdotstar, 0x0000ec18, L".*"},
    {TOKdotdot, 0x0000ec1c, L".."},
    {TOKle, 0x000133f9, L"<="},
    {TOKne, 0x000133fa, L"<>"},
    {TOKeq, 0x0001391a, L"=="},
    {TOKge, 0x00013e3b, L">="},
    {TOKdo, 0x00020153, L"do"},
    {TOKkseq, 0x00020676, L"eq"},
    {TOKksge, 0x000210ac, L"ge"},
    {TOKksgt, 0x000210bb, L"gt"},
    {TOKif, 0x00021aef, L"if"},
    {TOKin, 0x00021af7, L"in"},
    {TOKksle, 0x00022a51, L"le"},
    {TOKkslt, 0x00022a60, L"lt"},
    {TOKksne, 0x00023493, L"ne"},
    {TOKksor, 0x000239c1, L"or"},
    {TOKnull, 0x052931bb, L"null"},
    {TOKbreak, 0x05518c25, L"break"},
    {TOKksand, 0x09f9db33, L"and"},
    {TOKend, 0x0a631437, L"end"},
    {TOKeof, 0x0a63195a, L"eof"},
    {TOKfor, 0x0a7d67a7, L"for"},
    {TOKnan, 0x0b4f91dd, L"nan"},
    {TOKksnot, 0x0b4fd9b1, L"not"},
    {TOKvar, 0x0c2203e9, L"var"},
    {TOKthen, 0x2d5738cf, L"then"},
    {TOKelse, 0x45f65ee9, L"else"},
    {TOKexit, 0x4731d6ba, L"exit"},
    {TOKdownto, 0x4caadc3b, L"downto"},
    {TOKreturn, 0x4db8bd60, L"return"},
    {TOKinfinity, 0x5c0a010a, L"infinity"},
    {TOKendwhile, 0x5c64bff0, L"endwhile"},
    {TOKforeach, 0x67e31f38, L"foreach"},
    {TOKendfunc, 0x68f984a3, L"endfunc"},
    {TOKelseif, 0x78253218, L"elseif"},
    {TOKwhile, 0x84229259, L"while"},
    {TOKendfor, 0x8ab49d7e, L"endfor"},
    {TOKthrow, 0x8db05c94, L"throw"},
    {TOKstep, 0xa7a7887c, L"step"},
    {TOKupto, 0xb5155328, L"upto"},
    {TOKcontinue, 0xc0340685, L"continue"},
    {TOKfunc, 0xcdce60ec, L"func"},
    {TOKendif, 0xe0e8fee6, L"endif"},
};

const XFA_FM_TOKEN KEYWORD_START = TOKdo;
const XFA_FM_TOKEN KEYWORD_END = TOKendif;

}  // namespace

const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
  if (op < KEYWORD_START || op > KEYWORD_END)
    return L"";
  return keyWords[op].m_keyword;
}

CXFA_FMToken::CXFA_FMToken() : m_type(TOKreserver), m_uLinenum(1) {}

CXFA_FMToken::CXFA_FMToken(uint32_t uLineNum)
    : m_type(TOKreserver), m_uLinenum(uLineNum) {}

CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
                           CXFA_FMErrorInfo* pErrorInfo)
    : m_ptr(wsFormCalc.c_str()), m_uCurrentLine(1), m_pErrorInfo(pErrorInfo) {}

CXFA_FMLexer::~CXFA_FMLexer() {}

CXFA_FMToken* CXFA_FMLexer::NextToken() {
  m_pToken.reset(Scan());
  return m_pToken.get();
}

CXFA_FMToken* CXFA_FMLexer::Scan() {
  uint16_t ch = 0;
  CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
  if (!XFA_FMDChar::isAvalid(m_ptr)) {
    ch = XFA_FMDChar::get(m_ptr);
    Error(kFMErrUnsupportedChar, ch);
    return p;
  }
  int iRet = 0;
  while (1) {
    if (!XFA_FMDChar::isAvalid(m_ptr)) {
      ch = XFA_FMDChar::get(m_ptr);
      Error(kFMErrUnsupportedChar, ch);
      return p;
    }
    ch = XFA_FMDChar::get(m_ptr);
    switch (ch) {
      case 0:
        p->m_type = TOKeof;
        return p;
      case 0x0A:
        ++m_uCurrentLine;
        p->m_uLinenum = m_uCurrentLine;
        XFA_FMDChar::inc(m_ptr);
        break;
      case 0x0D:
        XFA_FMDChar::inc(m_ptr);
        break;
      case ';': {
        const FX_WCHAR* pTemp = 0;
        Comment(m_ptr, pTemp);
        m_ptr = pTemp;
      } break;
      case '"': {
        const FX_WCHAR* pTemp = 0;
        p->m_type = TOKstring;
        iRet = String(p, m_ptr, pTemp);
        m_ptr = pTemp;
      }
        return p;
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9': {
        p->m_type = TOKnumber;
        const FX_WCHAR* pTemp = 0;
        iRet = Number(p, m_ptr, pTemp);
        m_ptr = pTemp;
        if (iRet) {
          Error(kFMErrBadSuffixNumber);
          return p;
        }
      }
        return p;
      case '=':
        XFA_FMDChar::inc(m_ptr);
        if (XFA_FMDChar::isAvalid(m_ptr)) {
          ch = XFA_FMDChar::get(m_ptr);
          if (ch == '=') {
            p->m_type = TOKeq;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else {
            p->m_type = TOKassign;
            return p;
          }
        } else {
          ch = XFA_FMDChar::get(m_ptr);
          Error(kFMErrUnsupportedChar, ch);
          return p;
        }
        break;
      case '<':
        XFA_FMDChar::inc(m_ptr);
        if (XFA_FMDChar::isAvalid(m_ptr)) {
          ch = XFA_FMDChar::get(m_ptr);
          if (ch == '=') {
            p->m_type = TOKle;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else if (ch == '>') {
            p->m_type = TOKne;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else {
            p->m_type = TOKlt;
            return p;
          }
        } else {
          ch = XFA_FMDChar::get(m_ptr);
          Error(kFMErrUnsupportedChar, ch);
          return p;
        }
        break;
      case '>':
        XFA_FMDChar::inc(m_ptr);
        if (XFA_FMDChar::isAvalid(m_ptr)) {
          ch = XFA_FMDChar::get(m_ptr);
          if (ch == '=') {
            p->m_type = TOKge;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else {
            p->m_type = TOKgt;
            return p;
          }
        } else {
          ch = XFA_FMDChar::get(m_ptr);
          Error(kFMErrUnsupportedChar, ch);
          return p;
        }
        break;
      case ',':
        p->m_type = TOKcomma;
        XFA_FMDChar::inc(m_ptr);
        return p;
      case '(':
        p->m_type = TOKlparen;
        XFA_FMDChar::inc(m_ptr);
        return p;
      case ')':
        p->m_type = TOKrparen;
        XFA_FMDChar::inc(m_ptr);
        return p;
      case '[':
        p->m_type = TOKlbracket;
        XFA_FMDChar::inc(m_ptr);
        return p;
      case ']':
        p->m_type = TOKrbracket;
        XFA_FMDChar::inc(m_ptr);
        return p;
      case '&':
        XFA_FMDChar::inc(m_ptr);
        p->m_type = TOKand;
        return p;
      case '|':
        XFA_FMDChar::inc(m_ptr);
        p->m_type = TOKor;
        return p;
      case '+':
        XFA_FMDChar::inc(m_ptr);
        p->m_type = TOKplus;
        return p;
      case '-':
        XFA_FMDChar::inc(m_ptr);
        p->m_type = TOKminus;
        return p;
      case '*':
        XFA_FMDChar::inc(m_ptr);
        p->m_type = TOKmul;
        return p;
      case '/':
        XFA_FMDChar::inc(m_ptr);
        if (XFA_FMDChar::isAvalid(m_ptr)) {
          ch = XFA_FMDChar::get(m_ptr);
          if (ch == '/') {
            const FX_WCHAR* pTemp = 0;
            Comment(m_ptr, pTemp);
            m_ptr = pTemp;
            break;
          } else {
            p->m_type = TOKdiv;
            return p;
          }
        } else {
          ch = XFA_FMDChar::get(m_ptr);
          Error(kFMErrUnsupportedChar, ch);
          return p;
        }
        break;
      case '.':
        XFA_FMDChar::inc(m_ptr);
        if (XFA_FMDChar::isAvalid(m_ptr)) {
          ch = XFA_FMDChar::get(m_ptr);
          if (ch == '.') {
            p->m_type = TOKdotdot;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else if (ch == '*') {
            p->m_type = TOKdotstar;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else if (ch == '#') {
            p->m_type = TOKdotscream;
            XFA_FMDChar::inc(m_ptr);
            return p;
          } else if (ch <= '9' && ch >= '0') {
            p->m_type = TOKnumber;
            const FX_WCHAR* pTemp = 0;
            XFA_FMDChar::dec(m_ptr);
            iRet = Number(p, m_ptr, pTemp);
            m_ptr = pTemp;
            if (iRet) {
              Error(kFMErrBadSuffixNumber);
            }
            return p;
          } else {
            p->m_type = TOKdot;
            return p;
          }
        } else {
          ch = XFA_FMDChar::get(m_ptr);
          Error(kFMErrUnsupportedChar, ch);
          return p;
        }
      case 0x09:
      case 0x0B:
      case 0x0C:
      case 0x20:
        XFA_FMDChar::inc(m_ptr);
        break;
      default: {
        const FX_WCHAR* pTemp = 0;
        iRet = Identifiers(p, m_ptr, pTemp);
        m_ptr = pTemp;
        if (iRet) {
          return p;
        }
        p->m_type = IsKeyword(p->m_wstring);
      }
        return p;
    }
  }
}

uint32_t CXFA_FMLexer::Number(CXFA_FMToken* t,
                              const FX_WCHAR* p,
                              const FX_WCHAR*& pEnd) {
  FX_DOUBLE number = 0;
  if (XFA_FMDChar::string2number(p, &number, pEnd)) {
    return 1;
  }
  if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
    return 1;
  }
  t->m_wstring = CFX_WideStringC(p, (pEnd - p));
  return 0;
}

uint32_t CXFA_FMLexer::String(CXFA_FMToken* t,
                              const FX_WCHAR* p,
                              const FX_WCHAR*& pEnd) {
  const FX_WCHAR* pStart = p;
  uint16_t ch = 0;
  XFA_FMDChar::inc(p);
  ch = XFA_FMDChar::get(p);
  while (ch) {
    if (!XFA_FMDChar::isAvalid(p)) {
      ch = XFA_FMDChar::get(p);
      pEnd = p;
      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
      Error(kFMErrUnsupportedChar, ch);
      return 1;
    }
    if (ch == '"') {
      XFA_FMDChar::inc(p);
      if (!XFA_FMDChar::isAvalid(p)) {
        ch = XFA_FMDChar::get(p);
        pEnd = p;
        t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
        Error(kFMErrUnsupportedChar, ch);
        return 1;
      }
      ch = XFA_FMDChar::get(p);
      if (ch == '"') {
        goto NEXT;
      } else {
        break;
      }
    }
  NEXT:
    XFA_FMDChar::inc(p);
    ch = XFA_FMDChar::get(p);
  }
  pEnd = p;
  t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
  return 0;
}

uint32_t CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
                                   const FX_WCHAR* p,
                                   const FX_WCHAR*& pEnd) {
  const FX_WCHAR* pStart = p;
  uint16_t ch = 0;
  ch = XFA_FMDChar::get(p);
  XFA_FMDChar::inc(p);
  if (!XFA_FMDChar::isAvalid(p)) {
    pEnd = p;
    t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
    Error(kFMErrUnsupportedChar, ch);
    return 1;
  }
  ch = XFA_FMDChar::get(p);
  while (ch) {
    if (!XFA_FMDChar::isAvalid(p)) {
      pEnd = p;
      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
      Error(kFMErrUnsupportedChar, ch);
      return 1;
    }
    ch = XFA_FMDChar::get(p);
    if (XFA_FMDChar::isUnicodeAlpha(ch)) {
      XFA_FMDChar::inc(p);
    } else {
      pEnd = p;
      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
      return 0;
    }
  }
  pEnd = p;
  t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
  return 0;
}

void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
  unsigned ch = 0;
  XFA_FMDChar::inc(p);
  ch = XFA_FMDChar::get(p);
  while (ch) {
    if (ch == 0x0D) {
      XFA_FMDChar::inc(p);
      pEnd = p;
      return;
    }
    if (ch == 0x0A) {
      ++m_uCurrentLine;
      XFA_FMDChar::inc(p);
      pEnd = p;
      return;
    }
    XFA_FMDChar::inc(p);
    ch = XFA_FMDChar::get(p);
  }
  pEnd = p;
}

XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
  uint32_t uHash = FX_HashCode_GetW(str, true);
  int32_t iStart = KEYWORD_START;
  int32_t iEnd = KEYWORD_END;
  do {
    int32_t iMid = (iStart + iEnd) / 2;
    XFA_FMKeyword keyword = keyWords[iMid];
    if (uHash == keyword.m_uHash)
      return keyword.m_type;
    if (uHash < keyword.m_uHash)
      iEnd = iMid - 1;
    else
      iStart = iMid + 1;
  } while (iStart <= iEnd);
  return TOKidentifier;
}

void CXFA_FMLexer::Error(const FX_WCHAR* msg, ...) {
  m_pErrorInfo->linenum = m_uCurrentLine;
  va_list ap;
  va_start(ap, msg);
  m_pErrorInfo->message.FormatV(msg, ap);
  va_end(ap);
}

bool CXFA_FMLexer::HasError() const {
  if (m_pErrorInfo->message.IsEmpty()) {
    return false;
  }
  return true;
}
