// 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_fmparse.h"

#include <memory>
#include <utility>

CXFA_FMParse::CXFA_FMParse() : m_pToken(nullptr), m_pErrorInfo(0) {}

CXFA_FMParse::~CXFA_FMParse() {}

int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
                           CXFA_FMErrorInfo* pErrorInfo) {
  m_pErrorInfo = pErrorInfo;
  m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo));
  return 0;
}

void CXFA_FMParse::NextToken() {
  m_pToken = m_lexer->NextToken();
  while (m_pToken->m_type == TOKreserver) {
    if (m_lexer->HasError()) {
      break;
    }
    m_pToken = m_lexer->NextToken();
  }
}

void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
  if (m_pToken->m_type != op) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken, XFA_FM_KeywordToString(op),
          ws_TempString.c_str());
  }
  NextToken();
}

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

CFX_ArrayTemplate<CXFA_FMExpression*>* CXFA_FMParse::ParseTopExpression() {
  std::unique_ptr<CXFA_FMExpression> e;
  CFX_ArrayTemplate<CXFA_FMExpression*>* expression =
      new CFX_ArrayTemplate<CXFA_FMExpression*>();
  while (1) {
    if (m_pToken->m_type == TOKeof || m_pToken->m_type == TOKendfunc ||
        m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif ||
        m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) {
      return expression;
    }

    if (m_pToken->m_type == TOKfunc) {
      e.reset(ParseFunction());
      if (e) {
        expression->Add(e.release());
      } else {
        break;
      }
    } else {
      e.reset(ParseExpression());
      if (e) {
        expression->Add(e.release());
      } else {
        break;
      }
    }
  }
  return expression;
}

CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
  std::unique_ptr<CXFA_FMExpression> e;
  CFX_WideStringC ident;
  std::unique_ptr<CFX_WideStringCArray> pArguments;
  std::unique_ptr<CFX_ArrayTemplate<CXFA_FMExpression*>> pExpressions;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
          ws_TempString.c_str());
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    NextToken();
  } else {
    pArguments.reset(new CFX_WideStringCArray());
    CFX_WideStringC p;
    while (1) {
      if (m_pToken->m_type == TOKidentifier) {
        p = m_pToken->m_wstring;
        pArguments->Add(p);
        NextToken();
        if (m_pToken->m_type == TOKcomma) {
          NextToken();
          continue;
        } else if (m_pToken->m_type == TOKrparen) {
          NextToken();
          break;
        } else {
          Check(TOKrparen);
          break;
        }
      } else {
        CFX_WideString ws_TempString(m_pToken->m_wstring);
        Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
              ws_TempString.c_str());
        NextToken();
        break;
      }
    }
  }
  Check(TOKdo);
  if (m_pToken->m_type == TOKendfunc) {
    NextToken();
  } else {
    pExpressions.reset(ParseTopExpression());
    Check(TOKendfunc);
  }
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMFunctionDefinition(line, 0, ident, std::move(pArguments),
                                          pExpressions.release()));
  } else {
    if (pArguments)
      pArguments->RemoveAll();
    if (pExpressions) {
      for (int i = 0; i < pExpressions->GetSize(); ++i)
        delete pExpressions->GetAt(i);
    }
  }
  return e.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
  std::unique_ptr<CXFA_FMExpression> e;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKvar:
      e.reset(ParseVarExpression());
      break;
    case TOKnull:
    case TOKnumber:
    case TOKstring:
    case TOKplus:
    case TOKminus:
    case TOKksnot:
    case TOKidentifier:
    case TOKlparen:
      e.reset(ParseExpExpression());
      break;
    case TOKif:
      e.reset(ParseIfExpression());
      break;
    case TOKwhile:
      e.reset(ParseWhileExpression());
      break;
    case TOKfor:
      e.reset(ParseForExpression());
      break;
    case TOKforeach:
      e.reset(ParseForeachExpression());
      break;
    case TOKdo:
      e.reset(ParseDoExpression());
      break;
    case TOKbreak:
      e.reset(new CXFA_FMBreakExpression(line));
      NextToken();
      break;
    case TOKcontinue:
      e.reset(new CXFA_FMContinueExpression(line));
      NextToken();
      break;
    default:
      CFX_WideString ws_TempString(m_pToken->m_wstring);
      Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  return e.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
  std::unique_ptr<CXFA_FMExpression> e;
  CFX_WideStringC ident;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
          ws_TempString.c_str());
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    e.reset(ParseExpExpression());
  }
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMVarExpression(line, ident, e.release()));
  } else {
    e.reset();
  }
  return e.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());
  while (m_pToken->m_type == TOKassign) {
    NextToken();
    std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
    if (m_pErrorInfo->message.IsEmpty()) {
      pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
                                              pExp2.release()));
    } else {
      pExp1.reset();
    }
  }
  return pExp1.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseSimpleExpression());
  std::unique_ptr<CXFA_FMExpression> e;
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMExpExpression(line, pExp1.release()));
  } else {
    e.reset();
  }
  return e.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseLogicalAndExpression());
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKor:
      case TOKksor: {
        NextToken();
        std::unique_ptr<CXFA_FMSimpleExpression> e2(
            ParseLogicalAndExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMLogicalOrExpression(line, TOKor, e1.release(),
                                                  e2.release()));
        } else {
          e1.reset();
        }
        continue;
      }
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseEqualityExpression());
  for (;;) {
    switch (m_pToken->m_type) {
      case TOKand:
      case TOKksand: {
        NextToken();
        std::unique_ptr<CXFA_FMSimpleExpression> e2(ParseEqualityExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMLogicalAndExpression(line, TOKand, e1.release(),
                                                   e2.release()));
        } else {
          e1.reset();
        }
        continue;
      }
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseRelationalExpression());
  for (;;) {
    std::unique_ptr<CXFA_FMSimpleExpression> e2;
    switch (m_pToken->m_type) {
      case TOKeq:
      case TOKkseq:
        NextToken();
        e2.reset(ParseRelationalExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMEqualityExpression(line, TOKeq, e1.release(),
                                                 e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKne:
      case TOKksne:
        NextToken();
        e2.reset(ParseRelationalExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMEqualityExpression(line, TOKne, e1.release(),
                                                 e2.release()));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseAddtiveExpression());
  for (;;) {
    std::unique_ptr<CXFA_FMSimpleExpression> e2;
    switch (m_pToken->m_type) {
      case TOKlt:
      case TOKkslt:
        NextToken();
        e2.reset(ParseAddtiveExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMRelationalExpression(line, TOKlt, e1.release(),
                                                   e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKgt:
      case TOKksgt:
        NextToken();
        e2.reset(ParseAddtiveExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMRelationalExpression(line, TOKgt, e1.release(),
                                                   e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKle:
      case TOKksle:
        NextToken();
        e2.reset(ParseAddtiveExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMRelationalExpression(line, TOKle, e1.release(),
                                                   e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKge:
      case TOKksge:
        NextToken();
        e2.reset(ParseAddtiveExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMRelationalExpression(line, TOKge, e1.release(),
                                                   e2.release()));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseMultiplicativeExpression());
  for (;;) {
    std::unique_ptr<CXFA_FMSimpleExpression> e2;
    switch (m_pToken->m_type) {
      case TOKplus:
        NextToken();
        e2.reset(ParseMultiplicativeExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMAdditiveExpression(line, TOKplus, e1.release(),
                                                 e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKminus:
        NextToken();
        e2.reset(ParseMultiplicativeExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMAdditiveExpression(line, TOKminus, e1.release(),
                                                 e2.release()));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseUnaryExpression());
  for (;;) {
    std::unique_ptr<CXFA_FMSimpleExpression> e2;
    switch (m_pToken->m_type) {
      case TOKmul:
        NextToken();
        e2.reset(ParseUnaryExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMMultiplicativeExpression(
              line, TOKmul, e1.release(), e2.release()));
        } else {
          e1.reset();
        }
        continue;
      case TOKdiv:
        NextToken();
        e2.reset(ParseUnaryExpression());
        if (m_pErrorInfo->message.IsEmpty()) {
          e1.reset(new CXFA_FMMultiplicativeExpression(
              line, TOKdiv, e1.release(), e2.release()));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> e;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKplus:
      NextToken();
      e.reset(ParseUnaryExpression());
      if (m_pErrorInfo->message.IsEmpty()) {
        e.reset(new CXFA_FMPosExpression(line, e.release()));
      } else {
        e.reset();
      }
      break;
    case TOKminus:
      NextToken();
      e.reset(ParseUnaryExpression());
      if (m_pErrorInfo->message.IsEmpty()) {
        e.reset(new CXFA_FMNegExpression(line, e.release()));
      } else {
        e.reset();
      }
      break;
    case TOKksnot:
      NextToken();
      e.reset(ParseUnaryExpression());
      if (m_pErrorInfo->message.IsEmpty()) {
        e.reset(new CXFA_FMNotExpression(line, e.release()));
      } else {
        e.reset();
      }
      break;
    default:
      e.reset(ParsePrimaryExpression());
      break;
  }
  return e.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> e;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKnumber:
      e.reset(new CXFA_FMNumberExpression(line, m_pToken->m_wstring));
      NextToken();
      break;
    case TOKstring:
      e.reset(new CXFA_FMStringExpression(line, m_pToken->m_wstring));
      NextToken();
      break;
    case TOKidentifier: {
      CFX_WideStringC wsIdentifier(m_pToken->m_wstring);
      NextToken();
      if (m_pToken->m_type == TOKlbracket) {
        CXFA_FMSimpleExpression* s = ParseIndexExpression();
        if (s) {
          e.reset(new CXFA_FMDotAccessorExpression(line, nullptr, TOKdot,
                                                   wsIdentifier, s));
        }
        NextToken();
      } else {
        e.reset(new CXFA_FMIdentifierExpression(line, wsIdentifier));
      }
    } break;
    case TOKif:
      e.reset(new CXFA_FMIdentifierExpression(line, m_pToken->m_wstring));
      NextToken();
      break;
    case TOKnull:
      e.reset(new CXFA_FMNullExpression(line));
      NextToken();
      break;
    case TOKlparen:
      e.reset(ParseParenExpression());
      break;
    default:
      CFX_WideString ws_TempString(m_pToken->m_wstring);
      Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  e.reset(ParsePostExpression(e.release()));
  if (!(m_pErrorInfo->message.IsEmpty()))
    e.reset();
  return e.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression(
    CXFA_FMSimpleExpression* e) {
  uint32_t line = m_pToken->m_uLinenum;
  while (1) {
    switch (m_pToken->m_type) {
      case TOKlparen: {
        NextToken();
        std::unique_ptr<CFX_ArrayTemplate<CXFA_FMSimpleExpression*>> pArray;
        if (m_pToken->m_type != TOKrparen) {
          pArray.reset(new CFX_ArrayTemplate<CXFA_FMSimpleExpression*>());
          while (m_pToken->m_type != TOKrparen) {
            if (CXFA_FMSimpleExpression* expr = ParseSimpleExpression())
              pArray->Add(expr);
            if (m_pToken->m_type == TOKcomma) {
              NextToken();
            } else if (m_pToken->m_type == TOKeof ||
                       m_pToken->m_type == TOKreserver) {
              break;
            }
          }
          if (m_pToken->m_type != TOKrparen) {
            CFX_WideString ws_TempString(m_pToken->m_wstring);
            Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
                  XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
          }
        }
        if (m_pErrorInfo->message.IsEmpty()) {
          e = new CXFA_FMCallExpression(line, e, pArray.release(), false);
          NextToken();
          if (m_pToken->m_type != TOKlbracket) {
            continue;
          }
          CXFA_FMSimpleExpression* s = ParseIndexExpression();
          if (s) {
            e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
                                                 FX_WSTRC(L""), s);
          } else {
            delete e;
            e = nullptr;
          }
        } else {
          if (pArray) {
            for (int32_t i = 0; i < pArray->GetSize(); ++i)
              delete pArray->GetAt(i);
          }
          delete e;
          e = nullptr;
        }
      } break;
      case TOKdot:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          uint32_t tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlparen) {
            CXFA_FMSimpleExpression* pExpAccessor;
            CXFA_FMSimpleExpression* pExpCall;
            pExpAccessor = e;
            NextToken();
            std::unique_ptr<CFX_ArrayTemplate<CXFA_FMSimpleExpression*>> pArray;
            if (m_pToken->m_type != TOKrparen) {
              pArray.reset(new CFX_ArrayTemplate<CXFA_FMSimpleExpression*>());
              while (m_pToken->m_type != TOKrparen) {
                CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
                pArray->Add(exp);
                if (m_pToken->m_type == TOKcomma) {
                  NextToken();
                } else if (m_pToken->m_type == TOKeof ||
                           m_pToken->m_type == TOKreserver) {
                  break;
                }
              }
              if (m_pToken->m_type != TOKrparen) {
                CFX_WideString ws_TempString(m_pToken->m_wstring);
                Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
                      XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
              }
            }
            if (m_pErrorInfo->message.IsEmpty()) {
              CXFA_FMSimpleExpression* pIdentifier =
                  new CXFA_FMIdentifierExpression(tempLine, tempStr);
              pExpCall = new CXFA_FMCallExpression(line, pIdentifier,
                                                   pArray.release(), true);
              e = new CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);
              NextToken();
              if (m_pToken->m_type != TOKlbracket) {
                continue;
              }
              CXFA_FMSimpleExpression* s = ParseIndexExpression();
              if (s) {
                e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
                                                     FX_WSTRC(L""), s);
              } else {
                delete e;
                e = nullptr;
              }
            } else {
              if (pArray) {
                for (int32_t i = 0; i < pArray->GetSize(); ++i)
                  delete pArray->GetAt(i);
              }
              delete e;
              e = nullptr;
            }
          } else if (m_pToken->m_type == TOKlbracket) {
            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
            if (!(m_pErrorInfo->message.IsEmpty())) {
              delete e;
              return nullptr;
            }
            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr,
                                                 s.release());
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, nullptr, false);
            e = new CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString(m_pToken->m_wstring);
          Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotdot:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          uint32_t tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlbracket) {
            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
            if (!(m_pErrorInfo->message.IsEmpty())) {
              delete e;
              return nullptr;
            }
            e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot,
                                                    tempStr, s.release());
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, nullptr, false);
            e = new CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr,
                                                    s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString(m_pToken->m_wstring);
          Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotscream:
        NextToken();
        if (m_pToken->m_type == TOKidentifier) {
          CFX_WideStringC tempStr = m_pToken->m_wstring;
          uint32_t tempLine = m_pToken->m_uLinenum;
          NextToken();
          if (m_pToken->m_type == TOKlbracket) {
            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
            if (!(m_pErrorInfo->message.IsEmpty())) {
              delete e;
              return nullptr;
            }
            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream,
                                                 tempStr, s.release());
          } else {
            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
                tempLine, ACCESSOR_NO_INDEX, nullptr, false);
            e = new CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr,
                                                 s);
            continue;
          }
        } else {
          CFX_WideString ws_TempString(m_pToken->m_wstring);
          Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier,
                ws_TempString.c_str());
          return e;
        }
        break;
      case TOKdotstar: {
        CXFA_FMSimpleExpression* s =
            new CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, nullptr, false);
        e = new CXFA_FMDotAccessorExpression(line, e, TOKdotstar,
                                             FX_WSTRC(L"*"), s);
      } break;
      default:
        return e;
    }
    NextToken();
  }
  return e;
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> pExp;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> s;
  XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
  if (m_pToken->m_type == TOKmul) {
    pExp.reset(
        new CXFA_FMIndexExpression(line, accessorIndex, s.release(), true));
    NextToken();
    if (m_pToken->m_type != TOKrbracket) {
      CFX_WideString ws_TempString(m_pToken->m_wstring);
      Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
            XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
      pExp.reset();
    }
    return pExp.release();
  }
  if (m_pToken->m_type == TOKplus) {
    accessorIndex = ACCESSOR_POSITIVE_INDEX;
    NextToken();
  } else if (m_pToken->m_type == TOKminus) {
    accessorIndex = ACCESSOR_NEGATIVE_INDEX;
    NextToken();
  }
  s.reset(ParseSimpleExpression());
  if (m_pToken->m_type != TOKrbracket) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
          XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
  } else {
    pExp.reset(
        new CXFA_FMIndexExpression(line, accessorIndex, s.release(), false));
  }
  return pExp.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
  Check(TOKlparen);

  if (m_pToken->m_type == TOKrparen) {
    Error(m_pToken->m_uLinenum, kFMErrExpectedNonEmptyExpression);
    NextToken();
    return nullptr;
  }

  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());

  while (m_pToken->m_type == TOKassign) {
    NextToken();
    std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
    if (m_pErrorInfo->message.IsEmpty()) {
      pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
                                              pExp2.release()));
    } else {
      pExp1.reset();
    }
  }
  Check(TOKrparen);
  return pExp1.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  CXFA_FMExpression* e = nullptr;
  std::unique_ptr<CFX_ArrayTemplate<CXFA_FMExpression*>> expression(
      new CFX_ArrayTemplate<CXFA_FMExpression*>());

  while (1) {
    switch (m_pToken->m_type) {
      case TOKeof:
      case TOKendif:
      case TOKelseif:
      case TOKelse:
      case TOKendwhile:
      case TOKendfor:
      case TOKend:
      case TOKendfunc:
      case TOKreserver:
        break;
      case TOKfunc:
        e = ParseFunction();
        if (e) {
          expression->Add(e);
        }
        continue;
      default:
        e = ParseExpression();
        if (e) {
          expression->Add(e);
        }
        continue;
    }
    break;
  }
  std::unique_ptr<CXFA_FMBlockExpression> pExp;
  if (m_pErrorInfo->message.IsEmpty()) {
    pExp.reset(new CXFA_FMBlockExpression(line, expression.release()));
  } else {
    for (int i = 0; i < expression->GetSize(); ++i)
      delete static_cast<CXFA_FMExpression*>(expression->GetAt(i));
  }
  return pExp.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  const FX_WCHAR* pStartPos = m_lexer->SavePos();
  NextToken();
  Check(TOKlparen);
  std::unique_ptr<CXFA_FMSimpleExpression> pExpression;
  while (m_pToken->m_type != TOKrparen) {
    pExpression.reset(ParseSimpleExpression());
    if (m_pToken->m_type != TOKcomma)
      break;
    NextToken();
  }
  Check(TOKrparen);
  if (m_pToken->m_type != TOKthen) {
    m_lexer->SetCurrentLine(line);
    m_pToken = new CXFA_FMToken(line);
    m_pToken->m_type = TOKidentifier;
    m_pToken->m_wstring = FX_WSTRC(L"if");
    m_lexer->SetToken(m_pToken);
    m_lexer->RestorePos(pStartPos);
    return ParseExpExpression();
  }
  Check(TOKthen);
  std::unique_ptr<CXFA_FMExpression> pIfExpression(ParseBlockExpression());
  std::unique_ptr<CXFA_FMExpression> pElseExpression;
  switch (m_pToken->m_type) {
    case TOKeof:
    case TOKendif:
      Check(TOKendif);
      break;
    case TOKif:
      pElseExpression.reset(ParseIfExpression());
      Check(TOKendif);
      break;
    case TOKelseif:
      pElseExpression.reset(ParseIfExpression());
      break;
    case TOKelse:
      NextToken();
      pElseExpression.reset(ParseBlockExpression());
      Check(TOKendif);
      break;
    default:
      CFX_WideString ws_TempString(m_pToken->m_wstring);
      Error(m_pToken->m_uLinenum, kFMErrExpectedEndIf, ws_TempString.c_str());
      NextToken();
      break;
  }
  std::unique_ptr<CXFA_FMIfExpression> pExp;
  if (m_pErrorInfo->message.IsEmpty()) {
    pExp.reset(new CXFA_FMIfExpression(line, pExpression.release(),
                                       pIfExpression.release(),
                                       pElseExpression.release()));
  }
  return pExp.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> pCondition(ParseParenExpression());
  Check(TOKdo);
  std::unique_ptr<CXFA_FMExpression> pExpression(ParseBlockExpression());
  Check(TOKendwhile);
  std::unique_ptr<CXFA_FMExpression> e;
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMWhileExpression(line, pCondition.release(),
                                       pExpression.release()));
  }
  return e.release();
}

CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> e;
  switch (m_pToken->m_type) {
    case TOKidentifier:
      e.reset(ParseSimpleExpression());
      break;
    default:
      CFX_WideString ws_TempString(m_pToken->m_wstring);
      Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression,
            ws_TempString.c_str());
      NextToken();
      break;
  }
  return e.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
  CFX_WideStringC wsVariant;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  wsVariant = m_pToken->m_wstring;
  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> pAssignment;
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    pAssignment.reset(ParseSimpleExpression());
  } else {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  int32_t iDirection = 0;
  if (m_pToken->m_type == TOKupto) {
    iDirection = 1;
  } else if (m_pToken->m_type == TOKdownto) {
    iDirection = -1;
  } else {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken, L"upto or downto",
          ws_TempString.c_str());
  }
  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> pAccessor(ParseSimpleExpression());
  std::unique_ptr<CXFA_FMSimpleExpression> pStep;
  if (m_pToken->m_type == TOKstep) {
    NextToken();
    pStep.reset(ParseSimpleExpression());
  }
  Check(TOKdo);
  std::unique_ptr<CXFA_FMExpression> pList(ParseBlockExpression());
  Check(TOKendfor);
  std::unique_ptr<CXFA_FMExpression> e;
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMForExpression(line, wsVariant, pAssignment.release(),
                                     pAccessor.release(), iDirection,
                                     pStep.release(), pList.release()));
  }
  return e.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
  std::unique_ptr<CXFA_FMExpression> e;
  CFX_WideStringC wsIdentifier;
  std::unique_ptr<CFX_ArrayTemplate<CXFA_FMSimpleExpression*>> pAccessors;
  std::unique_ptr<CXFA_FMExpression> pList;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrExpectedToken,
          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
  }
  wsIdentifier = m_pToken->m_wstring;
  NextToken();
  Check(TOKin);
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    CFX_WideString ws_TempString(m_pToken->m_wstring);
    Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression,
          ws_TempString.c_str());
    NextToken();
  } else {
    pAccessors.reset(new CFX_ArrayTemplate<CXFA_FMSimpleExpression*>());
    while (m_pToken->m_type != TOKrparen) {
      CXFA_FMSimpleExpression* s = ParseSimpleExpression();
      if (s) {
        pAccessors->Add(s);
      }
      if (m_pToken->m_type == TOKcomma) {
        NextToken();
      } else {
        break;
      }
    }
    Check(TOKrparen);
  }
  Check(TOKdo);
  pList.reset(ParseBlockExpression());
  Check(TOKendfor);
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMForeachExpression(
        line, wsIdentifier, pAccessors.release(), pList.release()));
  } else {
    if (pAccessors) {
      for (int i = 0; i < pAccessors->GetSize(); ++i)
        delete static_cast<CXFA_FMSimpleExpression*>(pAccessors->GetAt(i));
    }
  }
  return e.release();
}

CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
  std::unique_ptr<CXFA_FMExpression> e;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  e.reset(ParseBlockExpression());
  Check(TOKend);
  if (m_pErrorInfo->message.IsEmpty()) {
    e.reset(new CXFA_FMDoExpression(line, e.release()));
  } else {
    e.reset();
  }
  return e.release();
}
