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

#include <memory>
#include <utility>
#include <vector>

#include "third_party/base/ptr_util.h"

namespace {

const int kMaxAssignmentChainLength = 12;

}  // namespace

CXFA_FMParse::CXFA_FMParse(const CFX_WideStringC& wsFormcalc)
    : m_pToken(nullptr), m_ParserError(false) {
  m_lexer = pdfium::MakeUnique<CXFA_FMLexer>(wsFormcalc);
}

CXFA_FMParse::~CXFA_FMParse() {}

std::unique_ptr<CXFA_FMFunctionDefinition> CXFA_FMParse::Parse() {
  NextToken();
  if (HasError())
    return nullptr;

  auto expressions = ParseTopExpression();
  if (HasError())
    return nullptr;

  std::vector<CFX_WideStringC> arguments;
  return pdfium::MakeUnique<CXFA_FMFunctionDefinition>(
      1, true, L"", std::move(arguments), std::move(expressions));
}

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

void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
  if (m_pToken->m_type != op)
    m_ParserError = true;
  NextToken();
}

std::vector<std::unique_ptr<CXFA_FMExpression>>
CXFA_FMParse::ParseTopExpression() {
  std::unique_ptr<CXFA_FMExpression> expr;
  std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
  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 expressions;
    }

    expr = m_pToken->m_type == TOKfunc ? ParseFunction() : ParseExpression();
    if (!expr)
      break;
    expressions.push_back(std::move(expr));
  }
  return expressions;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseFunction() {
  CFX_WideStringC ident;
  std::vector<CFX_WideStringC> arguments;
  std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    m_ParserError = true;
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    NextToken();
  } else {
    while (1) {
      if (m_pToken->m_type == TOKidentifier) {
        arguments.push_back(m_pToken->m_wstring);
        NextToken();
        if (m_pToken->m_type == TOKcomma) {
          NextToken();
          continue;
        }
        if (m_pToken->m_type == TOKrparen)
          NextToken();
        else
          Check(TOKrparen);
      } else {
        m_ParserError = true;
        NextToken();
      }
      break;
    }
  }
  Check(TOKdo);
  if (m_pToken->m_type == TOKendfunc) {
    NextToken();
  } else {
    expressions = ParseTopExpression();
    Check(TOKendfunc);
  }
  if (HasError())
    return nullptr;

  return pdfium::MakeUnique<CXFA_FMFunctionDefinition>(
      line, false, ident, std::move(arguments), std::move(expressions));
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseExpression() {
  std::unique_ptr<CXFA_FMExpression> expr;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKvar:
      expr = ParseVarExpression();
      break;
    case TOKnull:
    case TOKnumber:
    case TOKstring:
    case TOKplus:
    case TOKminus:
    case TOKksnot:
    case TOKidentifier:
    case TOKlparen:
      expr = ParseExpExpression();
      break;
    case TOKif:
      expr = ParseIfExpression();
      break;
    case TOKwhile:
      expr = ParseWhileExpression();
      break;
    case TOKfor:
      expr = ParseForExpression();
      break;
    case TOKforeach:
      expr = ParseForeachExpression();
      break;
    case TOKdo:
      expr = ParseDoExpression();
      break;
    case TOKbreak:
      expr = pdfium::MakeUnique<CXFA_FMBreakExpression>(line);
      NextToken();
      break;
    case TOKcontinue:
      expr = pdfium::MakeUnique<CXFA_FMContinueExpression>(line);
      NextToken();
      break;
    default:
      m_ParserError = true;
      NextToken();
      break;
  }
  return expr;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseVarExpression() {
  CFX_WideStringC ident;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier) {
    m_ParserError = true;
  } else {
    ident = m_pToken->m_wstring;
    NextToken();
  }
  std::unique_ptr<CXFA_FMExpression> expr;
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    expr = ParseExpExpression();
  }
  if (HasError())
    return nullptr;

  return pdfium::MakeUnique<CXFA_FMVarExpression>(line, ident, std::move(expr));
}

std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseSimpleExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseLogicalOrExpression();
  int level = 1;
  while (m_pToken->m_type == TOKassign) {
    NextToken();
    std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression();
    if (level++ == kMaxAssignmentChainLength)
      m_ParserError = true;
    if (!HasError()) {
      pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
          line, TOKassign, std::move(pExp1), std::move(pExp2));
    } else {
      pExp1.reset();
    }
  }
  return pExp1;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseExpExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseSimpleExpression();
  if (HasError())
    return nullptr;

  return pdfium::MakeUnique<CXFA_FMExpExpression>(line, std::move(pExp1));
}

std::unique_ptr<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 (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMLogicalOrExpression>(
              line, TOKor, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      }
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<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 (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMLogicalAndExpression>(
              line, TOKand, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      }
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<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 = ParseRelationalExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
              line, TOKeq, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKne:
      case TOKksne:
        NextToken();
        e2 = ParseRelationalExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
              line, TOKne, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<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 = ParseAddtiveExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
              line, TOKlt, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKgt:
      case TOKksgt:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
              line, TOKgt, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKle:
      case TOKksle:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
              line, TOKle, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKge:
      case TOKksge:
        NextToken();
        e2 = ParseAddtiveExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
              line, TOKge, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<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 = ParseMultiplicativeExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
              line, TOKplus, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKminus:
        NextToken();
        e2 = ParseMultiplicativeExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
              line, TOKminus, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<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 = ParseUnaryExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
              line, TOKmul, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      case TOKdiv:
        NextToken();
        e2 = ParseUnaryExpression();
        if (!HasError()) {
          e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
              line, TOKdiv, std::move(e1), std::move(e2));
        } else {
          e1.reset();
        }
        continue;
      default:
        break;
    }
    break;
  }
  return e1;
}

std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseUnaryExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> expr;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKplus:
      NextToken();
      expr = ParseUnaryExpression();
      if (!HasError())
        expr = pdfium::MakeUnique<CXFA_FMPosExpression>(line, std::move(expr));
      else
        expr.reset();
      break;
    case TOKminus:
      NextToken();
      expr = ParseUnaryExpression();
      if (!HasError())
        expr = pdfium::MakeUnique<CXFA_FMNegExpression>(line, std::move(expr));
      else
        expr.reset();
      break;
    case TOKksnot:
      NextToken();
      expr = ParseUnaryExpression();
      if (!HasError())
        expr = pdfium::MakeUnique<CXFA_FMNotExpression>(line, std::move(expr));
      else
        expr.reset();
      break;
    default:
      expr = ParsePrimaryExpression();
      break;
  }
  return expr;
}

std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParsePrimaryExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> expr;
  uint32_t line = m_pToken->m_uLinenum;
  switch (m_pToken->m_type) {
    case TOKnumber:
      expr = pdfium::MakeUnique<CXFA_FMNumberExpression>(line,
                                                         m_pToken->m_wstring);
      NextToken();
      break;
    case TOKstring:
      expr = pdfium::MakeUnique<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) {
        std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
        if (s) {
          expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
              line, nullptr, TOKdot, wsIdentifier, std::move(s));
        }
        NextToken();
      } else {
        expr =
            pdfium::MakeUnique<CXFA_FMIdentifierExpression>(line, wsIdentifier);
      }
      break;
    }
    case TOKif:
      expr = pdfium::MakeUnique<CXFA_FMIdentifierExpression>(
          line, m_pToken->m_wstring);
      NextToken();
      break;
    case TOKnull:
      expr = pdfium::MakeUnique<CXFA_FMNullExpression>(line);
      NextToken();
      break;
    case TOKlparen:
      expr = ParseParenExpression();
      break;
    default:
      m_ParserError = true;
      NextToken();
      break;
  }
  expr = ParsePostExpression(std::move(expr));
  if (HasError())
    expr.reset();
  return expr;
}

std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
    std::unique_ptr<CXFA_FMSimpleExpression> expr) {
  uint32_t line = m_pToken->m_uLinenum;
  while (1) {
    switch (m_pToken->m_type) {
      case TOKlparen: {
        NextToken();
        std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions;
        if (m_pToken->m_type != TOKrparen) {
          while (m_pToken->m_type != TOKrparen) {
            if (std::unique_ptr<CXFA_FMSimpleExpression> expr =
                    ParseSimpleExpression())
              expressions.push_back(std::move(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)
            m_ParserError = true;
        }
        if (!HasError()) {
          expr = pdfium::MakeUnique<CXFA_FMCallExpression>(
              line, std::move(expr), std::move(expressions), false);
          NextToken();
          if (m_pToken->m_type != TOKlbracket)
            continue;

          std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
          if (s) {
            expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
                line, std::move(expr), TOKcall, L"", std::move(s));
          } else {
            expr.reset();
          }
        } else {
          expr.reset();
        }
        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) {
            std::unique_ptr<CXFA_FMSimpleExpression> pExpCall;
            NextToken();
            std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions;
            if (m_pToken->m_type != TOKrparen) {
              while (m_pToken->m_type != TOKrparen) {
                std::unique_ptr<CXFA_FMSimpleExpression> exp =
                    ParseSimpleExpression();
                expressions.push_back(std::move(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)
                m_ParserError = true;
            }
            if (!HasError()) {
              std::unique_ptr<CXFA_FMSimpleExpression> pIdentifier =
                  pdfium::MakeUnique<CXFA_FMIdentifierExpression>(tempLine,
                                                                  tempStr);
              pExpCall = pdfium::MakeUnique<CXFA_FMCallExpression>(
                  line, std::move(pIdentifier), std::move(expressions), true);
              expr = pdfium::MakeUnique<CXFA_FMMethodCallExpression>(
                  line, std::move(expr), std::move(pExpCall));
              NextToken();
              if (m_pToken->m_type != TOKlbracket)
                continue;

              std::unique_ptr<CXFA_FMSimpleExpression> s =
                  ParseIndexExpression();
              if (s) {
                expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
                    line, std::move(expr), TOKcall, L"", std::move(s));
              } else {
                expr.reset();
              }
            } else {
              expr.reset();
            }
          } else if (m_pToken->m_type == TOKlbracket) {
            std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
            if (HasError())
              return nullptr;

            expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
                tempLine, std::move(expr), TOKdot, tempStr, std::move(s));
          } else {
            std::unique_ptr<CXFA_FMSimpleExpression> s =
                pdfium::MakeUnique<CXFA_FMIndexExpression>(
                    tempLine, ACCESSOR_NO_INDEX, nullptr, false);
            expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
                line, std::move(expr), TOKdot, tempStr, std::move(s));
            continue;
          }
        } else {
          m_ParserError = true;
          return expr;
        }
        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 (HasError())
              return nullptr;

            expr = pdfium::MakeUnique<CXFA_FMDotDotAccessorExpression>(
                tempLine, std::move(expr), TOKdotdot, tempStr, std::move(s));
          } else {
            std::unique_ptr<CXFA_FMSimpleExpression> s =
                pdfium::MakeUnique<CXFA_FMIndexExpression>(
                    tempLine, ACCESSOR_NO_INDEX, nullptr, false);
            expr = pdfium::MakeUnique<CXFA_FMDotDotAccessorExpression>(
                line, std::move(expr), TOKdotdot, tempStr, std::move(s));
            continue;
          }
        } else {
          m_ParserError = true;
          return expr;
        }
        break;
      case TOKdotscream: {
        NextToken();
        if (m_pToken->m_type != TOKidentifier) {
          m_ParserError = true;
          return expr;
        }
        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 =
              pdfium::MakeUnique<CXFA_FMIndexExpression>(
                  tempLine, ACCESSOR_NO_INDEX, nullptr, false);
          expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
              line, std::move(expr), TOKdotscream, tempStr, std::move(s));
          continue;
        }
        std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
        if (HasError())
          return nullptr;

        expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
            tempLine, std::move(expr), TOKdotscream, tempStr, std::move(s));
        break;
      }
      case TOKdotstar: {
        std::unique_ptr<CXFA_FMSimpleExpression> s =
            pdfium::MakeUnique<CXFA_FMIndexExpression>(line, ACCESSOR_NO_INDEX,
                                                       nullptr, false);
        expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
            line, std::move(expr), TOKdotstar, L"*", std::move(s));
        break;
      }
      default:
        return expr;
    }
    NextToken();
  }
  return expr;
}

std::unique_ptr<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 = pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex,
                                                      std::move(s), true);
    NextToken();
    if (m_pToken->m_type != TOKrbracket) {
      m_ParserError = true;
      pExp.reset();
    }
    return pExp;
  }
  if (m_pToken->m_type == TOKplus) {
    accessorIndex = ACCESSOR_POSITIVE_INDEX;
    NextToken();
  } else if (m_pToken->m_type == TOKminus) {
    accessorIndex = ACCESSOR_NEGATIVE_INDEX;
    NextToken();
  }
  s = ParseSimpleExpression();
  if (m_pToken->m_type != TOKrbracket) {
    m_ParserError = true;
  } else {
    pExp = pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex,
                                                      std::move(s), false);
  }
  return pExp;
}

std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseParenExpression() {
  Check(TOKlparen);

  if (m_pToken->m_type == TOKrparen) {
    m_ParserError = true;
    NextToken();
    return nullptr;
  }

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

  int level = 1;
  while (m_pToken->m_type == TOKassign) {
    NextToken();
    std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression();
    if (level++ == kMaxAssignmentChainLength)
      m_ParserError = true;
    if (!HasError()) {
      pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
          line, TOKassign, std::move(pExp1), std::move(pExp2));
    } else {
      pExp1.reset();
    }
  }
  Check(TOKrparen);
  return pExp1;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseBlockExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  std::unique_ptr<CXFA_FMExpression> expr;
  std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;

  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:
        expr = ParseFunction();
        if (expr) {
          expressions.push_back(std::move(expr));
        }
        continue;
      default:
        expr = ParseExpression();
        if (expr) {
          expressions.push_back(std::move(expr));
        }
        continue;
    }
    break;
  }
  std::unique_ptr<CXFA_FMBlockExpression> pExp;
  if (!HasError()) {
    pExp = pdfium::MakeUnique<CXFA_FMBlockExpression>(line,
                                                      std::move(expressions));
  }
  return pExp;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseIfExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  const wchar_t* pStartPos = m_lexer->GetPos();
  NextToken();
  Check(TOKlparen);
  std::unique_ptr<CXFA_FMSimpleExpression> pExpression;
  while (m_pToken->m_type != TOKrparen) {
    pExpression = ParseSimpleExpression();
    if (m_pToken->m_type != TOKcomma)
      break;
    NextToken();
  }
  Check(TOKrparen);
  if (m_pToken->m_type != TOKthen) {
    m_lexer->SetCurrentLine(line);
    auto pNewToken = pdfium::MakeUnique<CXFA_FMToken>(line);
    m_pToken = pNewToken.get();
    m_pToken->m_type = TOKidentifier;
    m_pToken->m_wstring = L"if";
    m_lexer->SetToken(std::move(pNewToken));
    m_lexer->SetPos(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 = ParseIfExpression();
      Check(TOKendif);
      break;
    case TOKelseif:
      pElseExpression = ParseIfExpression();
      break;
    case TOKelse:
      NextToken();
      pElseExpression = ParseBlockExpression();
      Check(TOKendif);
      break;
    default:
      m_ParserError = true;
      NextToken();
      break;
  }
  std::unique_ptr<CXFA_FMIfExpression> pExp;
  if (!HasError()) {
    pExp = pdfium::MakeUnique<CXFA_FMIfExpression>(line, std::move(pExpression),
                                                   std::move(pIfExpression),
                                                   std::move(pElseExpression));
  }
  return pExp;
}

std::unique_ptr<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> expr;
  if (!HasError()) {
    expr = pdfium::MakeUnique<CXFA_FMWhileExpression>(
        line, std::move(pCondition), std::move(pExpression));
  }
  return expr;
}

std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseSubassignmentInForExpression() {
  std::unique_ptr<CXFA_FMSimpleExpression> expr;
  switch (m_pToken->m_type) {
    case TOKidentifier:
      expr = ParseSimpleExpression();
      break;
    default:
      m_ParserError = true;
      NextToken();
      break;
  }
  return expr;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseForExpression() {
  CFX_WideStringC wsVariant;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier)
    m_ParserError = true;

  wsVariant = m_pToken->m_wstring;
  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> pAssignment;
  if (m_pToken->m_type == TOKassign) {
    NextToken();
    pAssignment = ParseSimpleExpression();
  } else {
    m_ParserError = true;
  }

  int32_t iDirection = 0;
  if (m_pToken->m_type == TOKupto)
    iDirection = 1;
  else if (m_pToken->m_type == TOKdownto)
    iDirection = -1;
  else
    m_ParserError = true;

  NextToken();
  std::unique_ptr<CXFA_FMSimpleExpression> pAccessor = ParseSimpleExpression();
  std::unique_ptr<CXFA_FMSimpleExpression> pStep;
  if (m_pToken->m_type == TOKstep) {
    NextToken();
    pStep = ParseSimpleExpression();
  }
  Check(TOKdo);
  std::unique_ptr<CXFA_FMExpression> pList = ParseBlockExpression();
  Check(TOKendfor);
  std::unique_ptr<CXFA_FMExpression> expr;
  if (!HasError()) {
    expr = pdfium::MakeUnique<CXFA_FMForExpression>(
        line, wsVariant, std::move(pAssignment), std::move(pAccessor),
        iDirection, std::move(pStep), std::move(pList));
  }
  return expr;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseForeachExpression() {
  std::unique_ptr<CXFA_FMExpression> expr;
  CFX_WideStringC wsIdentifier;
  std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> pAccessors;
  std::unique_ptr<CXFA_FMExpression> pList;
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  if (m_pToken->m_type != TOKidentifier)
    m_ParserError = true;

  wsIdentifier = m_pToken->m_wstring;
  NextToken();
  Check(TOKin);
  Check(TOKlparen);
  if (m_pToken->m_type == TOKrparen) {
    m_ParserError = true;
    NextToken();
  } else {
    while (m_pToken->m_type != TOKrparen) {
      std::unique_ptr<CXFA_FMSimpleExpression> s = ParseSimpleExpression();
      if (s)
        pAccessors.push_back(std::move(s));
      if (m_pToken->m_type != TOKcomma)
        break;
      NextToken();
    }
    Check(TOKrparen);
  }
  Check(TOKdo);
  pList = ParseBlockExpression();
  Check(TOKendfor);
  if (!HasError()) {
    expr = pdfium::MakeUnique<CXFA_FMForeachExpression>(
        line, wsIdentifier, std::move(pAccessors), std::move(pList));
  }
  return expr;
}

std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseDoExpression() {
  uint32_t line = m_pToken->m_uLinenum;
  NextToken();
  std::unique_ptr<CXFA_FMExpression> expr = ParseBlockExpression();
  Check(TOKend);
  if (HasError())
    return nullptr;

  return pdfium::MakeUnique<CXFA_FMDoExpression>(line, std::move(expr));
}

bool CXFA_FMParse::HasError() const {
  return m_ParserError || m_lexer->HasError();
}
