// 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>

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();
}
