// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/regexp_parser.h"

#include "unicode/uchar.h"
#include "unicode/uniset.h"

#include "platform/unicode.h"

#include "vm/longjump.h"
#include "vm/object_store.h"

namespace dart {

#define Z zone()

// Enables possessive quantifier syntax for testing.
static const bool FLAG_regexp_possessive_quantifier = false;

RegExpBuilder::RegExpBuilder(RegExpFlags flags)
    : zone_(Thread::Current()->zone()),
      pending_empty_(false),
      flags_(flags),
      characters_(NULL),
      pending_surrogate_(kNoPendingSurrogate),
      terms_(),
      text_(),
      alternatives_()
#ifdef DEBUG
      ,
      last_added_(ADD_NONE)
#endif
{
}

void RegExpBuilder::AddLeadSurrogate(uint16_t lead_surrogate) {
  ASSERT(Utf16::IsLeadSurrogate(lead_surrogate));
  FlushPendingSurrogate();
  // Hold onto the lead surrogate, waiting for a trail surrogate to follow.
  pending_surrogate_ = lead_surrogate;
}

void RegExpBuilder::AddTrailSurrogate(uint16_t trail_surrogate) {
  ASSERT(Utf16::IsTrailSurrogate(trail_surrogate));
  if (pending_surrogate_ != kNoPendingSurrogate) {
    uint16_t lead_surrogate = pending_surrogate_;
    pending_surrogate_ = kNoPendingSurrogate;
    ASSERT(Utf16::IsLeadSurrogate(lead_surrogate));
    uint32_t combined = Utf16::Decode(lead_surrogate, trail_surrogate);
    if (NeedsDesugaringForIgnoreCase(combined)) {
      AddCharacterClassForDesugaring(combined);
    } else {
      auto surrogate_pair = new (Z) ZoneGrowableArray<uint16_t>(2);
      surrogate_pair->Add(lead_surrogate);
      surrogate_pair->Add(trail_surrogate);
      RegExpAtom* atom = new (Z) RegExpAtom(surrogate_pair, flags_);
      AddAtom(atom);
    }
  } else {
    pending_surrogate_ = trail_surrogate;
    FlushPendingSurrogate();
  }
}

void RegExpBuilder::FlushPendingSurrogate() {
  if (pending_surrogate_ != kNoPendingSurrogate) {
    ASSERT(is_unicode());
    uint32_t c = pending_surrogate_;
    pending_surrogate_ = kNoPendingSurrogate;
    AddCharacterClassForDesugaring(c);
  }
}

void RegExpBuilder::FlushCharacters() {
  FlushPendingSurrogate();
  pending_empty_ = false;
  if (characters_ != NULL) {
    RegExpTree* atom = new (Z) RegExpAtom(characters_, flags_);
    characters_ = NULL;
    text_.Add(atom);
    LAST(ADD_ATOM);
  }
}

void RegExpBuilder::FlushText() {
  FlushCharacters();
  intptr_t num_text = text_.length();
  if (num_text == 0) {
    return;
  } else if (num_text == 1) {
    terms_.Add(text_.Last());
  } else {
    RegExpText* text = new (Z) RegExpText();
    for (intptr_t i = 0; i < num_text; i++)
      text_[i]->AppendToText(text);
    terms_.Add(text);
  }
  text_.Clear();
}

void RegExpBuilder::AddCharacter(uint16_t c) {
  FlushPendingSurrogate();
  pending_empty_ = false;
  if (NeedsDesugaringForIgnoreCase(c)) {
    AddCharacterClassForDesugaring(c);
  } else {
    if (characters_ == NULL) {
      characters_ = new (Z) ZoneGrowableArray<uint16_t>(4);
    }
    characters_->Add(c);
    LAST(ADD_CHAR);
  }
}

void RegExpBuilder::AddUnicodeCharacter(uint32_t c) {
  if (c > static_cast<uint32_t>(Utf16::kMaxCodeUnit)) {
    ASSERT(is_unicode());
    uint16_t surrogates[2];
    Utf16::Encode(c, surrogates);
    AddLeadSurrogate(surrogates[0]);
    AddTrailSurrogate(surrogates[1]);
  } else if (is_unicode() && Utf16::IsLeadSurrogate(c)) {
    AddLeadSurrogate(c);
  } else if (is_unicode() && Utf16::IsTrailSurrogate(c)) {
    AddTrailSurrogate(c);
  } else {
    AddCharacter(static_cast<uint16_t>(c));
  }
}

void RegExpBuilder::AddEscapedUnicodeCharacter(uint32_t character) {
  // A lead or trail surrogate parsed via escape sequence will not
  // pair up with any preceding lead or following trail surrogate.
  FlushPendingSurrogate();
  AddUnicodeCharacter(character);
  FlushPendingSurrogate();
}

void RegExpBuilder::AddEmpty() {
  pending_empty_ = true;
}

void RegExpBuilder::AddCharacterClass(RegExpCharacterClass* cc) {
  if (NeedsDesugaringForUnicode(cc)) {
    // With /u, character class needs to be desugared, so it
    // must be a standalone term instead of being part of a RegExpText.
    AddTerm(cc);
  } else {
    AddAtom(cc);
  }
}

void RegExpBuilder::AddCharacterClassForDesugaring(uint32_t c) {
  auto ranges = CharacterRange::List(Z, CharacterRange::Singleton(c));
  AddTerm(new (Z) RegExpCharacterClass(ranges, flags_));
}

void RegExpBuilder::AddAtom(RegExpTree* term) {
  if (term->IsEmpty()) {
    AddEmpty();
    return;
  }
  if (term->IsTextElement()) {
    FlushCharacters();
    text_.Add(term);
  } else {
    FlushText();
    terms_.Add(term);
  }
  LAST(ADD_ATOM);
}

void RegExpBuilder::AddTerm(RegExpTree* term) {
  FlushText();
  terms_.Add(term);
  LAST(ADD_ATOM);
}

void RegExpBuilder::AddAssertion(RegExpTree* assert) {
  FlushText();
  terms_.Add(assert);
  LAST(ADD_ASSERT);
}

void RegExpBuilder::NewAlternative() {
  FlushTerms();
}

void RegExpBuilder::FlushTerms() {
  FlushText();
  intptr_t num_terms = terms_.length();
  RegExpTree* alternative;
  if (num_terms == 0) {
    alternative = RegExpEmpty::GetInstance();
  } else if (num_terms == 1) {
    alternative = terms_.Last();
  } else {
    ZoneGrowableArray<RegExpTree*>* terms =
        new (Z) ZoneGrowableArray<RegExpTree*>();
    for (intptr_t i = 0; i < terms_.length(); i++) {
      terms->Add(terms_[i]);
    }
    alternative = new (Z) RegExpAlternative(terms);
  }
  alternatives_.Add(alternative);
  terms_.Clear();
  LAST(ADD_NONE);
}

bool RegExpBuilder::NeedsDesugaringForUnicode(RegExpCharacterClass* cc) {
  if (!is_unicode()) return false;
  // TODO(yangguo): we could be smarter than this. Case-insensitivity does not
  // necessarily mean that we need to desugar. It's probably nicer to have a
  // separate pass to figure out unicode desugarings.
  if (ignore_case()) return true;
  ZoneGrowableArray<CharacterRange>* ranges = cc->ranges();
  CharacterRange::Canonicalize(ranges);
  for (int i = ranges->length() - 1; i >= 0; i--) {
    uint32_t from = ranges->At(i).from();
    uint32_t to = ranges->At(i).to();
    // Check for non-BMP characters.
    if (to >= Utf16::kMaxCodeUnit) return true;
    // Check for lone surrogates.
    if (from <= Utf16::kTrailSurrogateEnd && to >= Utf16::kLeadSurrogateStart) {
      return true;
    }
  }
  return false;
}

bool RegExpBuilder::NeedsDesugaringForIgnoreCase(uint32_t c) {
  if (is_unicode() && ignore_case()) {
    icu::UnicodeSet set(c, c);
    set.closeOver(USET_CASE_INSENSITIVE);
    set.removeAllStrings();
    return set.size() > 1;
  }
  return false;
}

RegExpTree* RegExpBuilder::ToRegExp() {
  FlushTerms();
  intptr_t num_alternatives = alternatives_.length();
  if (num_alternatives == 0) {
    return RegExpEmpty::GetInstance();
  }
  if (num_alternatives == 1) {
    return alternatives_.Last();
  }
  ZoneGrowableArray<RegExpTree*>* alternatives =
      new (Z) ZoneGrowableArray<RegExpTree*>();
  for (intptr_t i = 0; i < alternatives_.length(); i++) {
    alternatives->Add(alternatives_[i]);
  }
  return new (Z) RegExpDisjunction(alternatives);
}

bool RegExpBuilder::AddQuantifierToAtom(
    intptr_t min,
    intptr_t max,
    RegExpQuantifier::QuantifierType quantifier_type) {
  if (pending_empty_) {
    pending_empty_ = false;
    return true;
  }
  RegExpTree* atom;
  if (characters_ != NULL) {
    DEBUG_ASSERT(last_added_ == ADD_CHAR);
    // Last atom was character.

    ZoneGrowableArray<uint16_t>* char_vector =
        new (Z) ZoneGrowableArray<uint16_t>();
    char_vector->AddArray(*characters_);
    intptr_t num_chars = char_vector->length();
    if (num_chars > 1) {
      ZoneGrowableArray<uint16_t>* prefix =
          new (Z) ZoneGrowableArray<uint16_t>();
      for (intptr_t i = 0; i < num_chars - 1; i++) {
        prefix->Add(char_vector->At(i));
      }
      text_.Add(new (Z) RegExpAtom(prefix, flags_));
      ZoneGrowableArray<uint16_t>* tail = new (Z) ZoneGrowableArray<uint16_t>();
      tail->Add(char_vector->At(num_chars - 1));
      char_vector = tail;
    }
    characters_ = NULL;
    atom = new (Z) RegExpAtom(char_vector, flags_);
    FlushText();
  } else if (text_.length() > 0) {
    DEBUG_ASSERT(last_added_ == ADD_ATOM);
    atom = text_.RemoveLast();
    FlushText();
  } else if (terms_.length() > 0) {
    DEBUG_ASSERT(last_added_ == ADD_ATOM);
    atom = terms_.RemoveLast();
    if (auto lookaround = atom->AsLookaround()) {
      // With /u, lookarounds are not quantifiable.
      if (is_unicode()) return false;
      // Lookbehinds are not quantifiable.
      if (lookaround->type() == RegExpLookaround::LOOKBEHIND) {
        return false;
      }
    }
    if (atom->max_match() == 0) {
      // Guaranteed to only match an empty string.
      LAST(ADD_TERM);
      if (min == 0) {
        return true;
      }
      terms_.Add(atom);
      return true;
    }
  } else {
    // Only call immediately after adding an atom or character!
    UNREACHABLE();
  }
  terms_.Add(new (Z) RegExpQuantifier(min, max, quantifier_type, atom));
  LAST(ADD_TERM);
  return true;
}

// ----------------------------------------------------------------------------
// Implementation of Parser

RegExpParser::RegExpParser(const String& in, String* error, RegExpFlags flags)
    : zone_(Thread::Current()->zone()),
      captures_(nullptr),
      named_captures_(nullptr),
      named_back_references_(nullptr),
      in_(in),
      current_(kEndMarker),
      next_pos_(0),
      captures_started_(0),
      capture_count_(0),
      has_more_(true),
      top_level_flags_(flags),
      simple_(false),
      contains_anchor_(false),
      is_scanned_for_captures_(false),
      has_named_captures_(false) {
  Advance();
}

inline uint32_t RegExpParser::ReadNext(bool update_position) {
  intptr_t position = next_pos_;
  const uint16_t c0 = in().CharAt(position);
  uint32_t c = c0;
  position++;
  if (is_unicode() && position < in().Length() && Utf16::IsLeadSurrogate(c0)) {
    const uint16_t c1 = in().CharAt(position);
    if (Utf16::IsTrailSurrogate(c1)) {
      c = Utf16::Decode(c0, c1);
      position++;
    }
  }
  if (update_position) next_pos_ = position;
  return c;
}

uint32_t RegExpParser::Next() {
  if (has_next()) {
    return ReadNext(false);
  } else {
    return kEndMarker;
  }
}

void RegExpParser::Advance() {
  if (has_next()) {
    current_ = ReadNext(true);
  } else {
    current_ = kEndMarker;
    // Advance so that position() points to 1 after the last character. This is
    // important so that Reset() to this position works correctly.
    next_pos_ = in().Length() + 1;
    has_more_ = false;
  }
}

void RegExpParser::Reset(intptr_t pos) {
  next_pos_ = pos;
  has_more_ = (pos < in().Length());
  Advance();
}

void RegExpParser::Advance(intptr_t dist) {
  next_pos_ += dist - 1;
  Advance();
}

bool RegExpParser::simple() {
  return simple_;
}

bool RegExpParser::IsSyntaxCharacterOrSlash(uint32_t c) {
  switch (c) {
    case '^':
    case '$':
    case '\\':
    case '.':
    case '*':
    case '+':
    case '?':
    case '(':
    case ')':
    case '[':
    case ']':
    case '{':
    case '}':
    case '|':
    case '/':
      return true;
    default:
      break;
  }
  return false;
}

void RegExpParser::ReportError(const char* message) {
  // Zip to the end to make sure the no more input is read.
  current_ = kEndMarker;
  next_pos_ = in().Length();

  // Throw a FormatException on parsing failures.
  const String& msg = String::Handle(
      String::Concat(String::Handle(String::New(message)), in()));
  const Array& args = Array::Handle(Array::New(1));
  args.SetAt(0, msg);
  Exceptions::ThrowByType(Exceptions::kFormat, args);
  UNREACHABLE();
}

// Pattern ::
//   Disjunction
RegExpTree* RegExpParser::ParsePattern() {
  RegExpTree* result = ParseDisjunction();
  PatchNamedBackReferences();
  ASSERT(!has_more());
  // If the result of parsing is a literal string atom, and it has the
  // same length as the input, then the atom is identical to the input.
  if (result->IsAtom() && result->AsAtom()->length() == in().Length()) {
    simple_ = true;
  }
  return result;
}

// Used for error messages where we would have fallen back on treating an
// escape as the identity escape, but we are in Unicode mode.
static const char* kUnicodeIdentity =
    "Invalid identity escape in Unicode pattern";

// Disjunction ::
//   Alternative
//   Alternative | Disjunction
// Alternative ::
//   [empty]
//   Term Alternative
// Term ::
//   Assertion
//   Atom
//   Atom Quantifier
RegExpTree* RegExpParser::ParseDisjunction() {
  // Used to store current state while parsing subexpressions.
  RegExpParserState initial_state(nullptr, INITIAL, RegExpLookaround::LOOKAHEAD,
                                  0, nullptr, top_level_flags_, Z);
  RegExpParserState* stored_state = &initial_state;
  // Cache the builder in a local variable for quick access.
  RegExpBuilder* builder = initial_state.builder();
  while (true) {
    switch (current()) {
      case kEndMarker:
        if (stored_state->IsSubexpression()) {
          // Inside a parenthesized group when hitting end of input.
          ReportError("Unterminated group");
          UNREACHABLE();
        }
        ASSERT(INITIAL == stored_state->group_type());
        // Parsing completed successfully.
        return builder->ToRegExp();
      case ')': {
        if (!stored_state->IsSubexpression()) {
          ReportError("Unmatched ')'");
          UNREACHABLE();
        }
        ASSERT(INITIAL != stored_state->group_type());

        Advance();
        // End disjunction parsing and convert builder content to new single
        // regexp atom.
        RegExpTree* body = builder->ToRegExp();

        intptr_t end_capture_index = captures_started();

        intptr_t capture_index = stored_state->capture_index();
        SubexpressionType group_type = stored_state->group_type();

        // Build result of subexpression.
        if (group_type == CAPTURE) {
          if (stored_state->IsNamedCapture()) {
            CreateNamedCaptureAtIndex(stored_state->capture_name(),
                                      capture_index);
          }
          RegExpCapture* capture = GetCapture(capture_index);
          capture->set_body(body);
          body = capture;
        } else if (group_type != GROUPING) {
          ASSERT(group_type == POSITIVE_LOOKAROUND ||
                 group_type == NEGATIVE_LOOKAROUND);
          bool is_positive = (group_type == POSITIVE_LOOKAROUND);
          body = new (Z) RegExpLookaround(
              body, is_positive, end_capture_index - capture_index,
              capture_index, stored_state->lookaround_type());
        }

        // Restore previous state.
        stored_state = stored_state->previous_state();
        builder = stored_state->builder();

        builder->AddAtom(body);
        // For compatibility with JSC and ES3, we allow quantifiers after
        // lookaheads, and break in all cases.
        break;
      }
      case '|': {
        Advance();
        builder->NewAlternative();
        continue;
      }
      case '*':
      case '+':
      case '?':
        ReportError("Nothing to repeat");
        UNREACHABLE();
      case '^': {
        Advance();
        if (builder->is_multi_line()) {
          builder->AddAssertion(new (Z) RegExpAssertion(
              RegExpAssertion::START_OF_LINE, builder->flags()));
        } else {
          builder->AddAssertion(new (Z) RegExpAssertion(
              RegExpAssertion::START_OF_INPUT, builder->flags()));
          set_contains_anchor();
        }
        continue;
      }
      case '$': {
        Advance();
        RegExpAssertion::AssertionType assertion_type =
            builder->is_multi_line() ? RegExpAssertion::END_OF_LINE
                                     : RegExpAssertion::END_OF_INPUT;
        builder->AddAssertion(
            new (Z) RegExpAssertion(assertion_type, builder->flags()));
        continue;
      }
      case '.': {
        Advance();
        auto ranges = new (Z) ZoneGrowableArray<CharacterRange>(2);
        if (builder->is_dot_all()) {
          // Everything.
          CharacterRange::AddClassEscape(
              '*', ranges,
              /*add_unicode_case_equivalents=*/false);
        } else {
          // everything except \x0a, \x0d, \u2028 and \u2029
          CharacterRange::AddClassEscape(
              '.', ranges,
              /*add_unicode_case_equivalents=*/false);
        }
        RegExpCharacterClass* cc =
            new (Z) RegExpCharacterClass(ranges, builder->flags());
        builder->AddCharacterClass(cc);
        break;
      }
      case '(': {
        stored_state = ParseOpenParenthesis(stored_state);
        builder = stored_state->builder();
        continue;
      }
      case '[': {
        RegExpTree* atom = ParseCharacterClass(builder);
        builder->AddCharacterClass(atom->AsCharacterClass());
        break;
      }
      // Atom ::
      //   \ AtomEscape
      case '\\':
        switch (Next()) {
          case kEndMarker:
            ReportError("\\ at end of pattern");
            UNREACHABLE();
          case 'b':
            Advance(2);
            builder->AddAssertion(new (Z) RegExpAssertion(
                RegExpAssertion::BOUNDARY, builder->flags()));
            continue;
          case 'B':
            Advance(2);
            builder->AddAssertion(new (Z) RegExpAssertion(
                RegExpAssertion::NON_BOUNDARY, builder->flags()));
            continue;
          // AtomEscape ::
          //   CharacterClassEscape
          //
          // CharacterClassEscape :: one of
          //   d D s S w W
          case 'd':
          case 'D':
          case 's':
          case 'S':
          case 'w':
          case 'W': {
            uint32_t c = Next();
            Advance(2);
            auto ranges = new (Z) ZoneGrowableArray<CharacterRange>(2);
            CharacterRange::AddClassEscape(
                c, ranges, is_unicode() && builder->ignore_case());
            RegExpCharacterClass* cc =
                new (Z) RegExpCharacterClass(ranges, builder->flags());
            builder->AddCharacterClass(cc);
            break;
          }
          case 'p':
          case 'P': {
            uint32_t p = Next();
            Advance(2);

            if (is_unicode()) {
              auto name_1 = new (Z) ZoneGrowableArray<char>();
              auto name_2 = new (Z) ZoneGrowableArray<char>();
              auto ranges = new (Z) ZoneGrowableArray<CharacterRange>(2);
              if (ParsePropertyClassName(name_1, name_2)) {
                if (AddPropertyClassRange(ranges, p == 'P', name_1, name_2)) {
                  RegExpCharacterClass* cc =
                      new (Z) RegExpCharacterClass(ranges, builder->flags());
                  builder->AddCharacterClass(cc);
                  break;
                }
              }
              ReportError("Invalid property name");
              UNREACHABLE();
            } else {
              builder->AddCharacter(p);
            }
            break;
          }
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9': {
            intptr_t index = 0;
            if (ParseBackReferenceIndex(&index)) {
              if (stored_state->IsInsideCaptureGroup(index)) {
                // The back reference is inside the capture group it refers to.
                // Nothing can possibly have been captured yet, so we use empty
                // instead. This ensures that, when checking a back reference,
                // the capture registers of the referenced capture are either
                // both set or both cleared.
                builder->AddEmpty();
              } else {
                RegExpCapture* capture = GetCapture(index);
                RegExpTree* atom =
                    new (Z) RegExpBackReference(capture, builder->flags());
                builder->AddAtom(atom);
              }
              break;
            }
            // With /u, no identity escapes except for syntax characters are
            // allowed. Otherwise, all identity escapes are allowed.
            if (is_unicode()) {
              ReportError(kUnicodeIdentity);
              UNREACHABLE();
            }
            uint32_t first_digit = Next();
            if (first_digit == '8' || first_digit == '9') {
              builder->AddCharacter(first_digit);
              Advance(2);
              break;
            }
          }
            FALL_THROUGH;
          case '0': {
            Advance();
            if (is_unicode() && Next() >= '0' && Next() <= '9') {
              // With /u, decimal escape with leading 0 are not parsed as octal.
              ReportError("Invalid decimal escape");
              UNREACHABLE();
            }
            uint32_t octal = ParseOctalLiteral();
            builder->AddCharacter(octal);
            break;
          }
          // ControlEscape :: one of
          //   f n r t v
          case 'f':
            Advance(2);
            builder->AddCharacter('\f');
            break;
          case 'n':
            Advance(2);
            builder->AddCharacter('\n');
            break;
          case 'r':
            Advance(2);
            builder->AddCharacter('\r');
            break;
          case 't':
            Advance(2);
            builder->AddCharacter('\t');
            break;
          case 'v':
            Advance(2);
            builder->AddCharacter('\v');
            break;
          case 'c': {
            Advance();
            uint32_t controlLetter = Next();
            // Special case if it is an ASCII letter.
            // Convert lower case letters to uppercase.
            uint32_t letter = controlLetter & ~('a' ^ 'A');
            if (letter < 'A' || 'Z' < letter) {
              // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
              // This is outside the specification. We match JSC in
              // reading the backslash as a literal character instead
              // of as starting an escape.
              if (is_unicode()) {
                // With /u, invalid escapes are not treated as identity escapes.
                ReportError(kUnicodeIdentity);
                UNREACHABLE();
              }
              builder->AddCharacter('\\');
            } else {
              Advance(2);
              builder->AddCharacter(controlLetter & 0x1f);
            }
            break;
          }
          case 'x': {
            Advance(2);
            uint32_t value;
            if (ParseHexEscape(2, &value)) {
              builder->AddCharacter(value);
            } else if (!is_unicode()) {
              builder->AddCharacter('x');
            } else {
              // With /u, invalid escapes are not treated as identity escapes.
              ReportError(kUnicodeIdentity);
              UNREACHABLE();
            }
            break;
          }
          case 'u': {
            Advance(2);
            uint32_t value;
            if (ParseUnicodeEscape(&value)) {
              builder->AddEscapedUnicodeCharacter(value);
            } else if (!is_unicode()) {
              builder->AddCharacter('u');
            } else {
              // With /u, invalid escapes are not treated as identity escapes.
              ReportError(kUnicodeIdentity);
              UNREACHABLE();
            }
            break;
          }
          case 'k':
            // Either an identity escape or a named back-reference.  The two
            // interpretations are mutually exclusive: '\k' is interpreted as
            // an identity escape for non-Unicode patterns without named
            // capture groups, and as the beginning of a named back-reference
            // in all other cases.
            if (is_unicode() || HasNamedCaptures()) {
              Advance(2);
              ParseNamedBackReference(builder, stored_state);
              break;
            }
            FALL_THROUGH;
          default:
            Advance();
            // With the unicode flag, no identity escapes except for syntax
            // characters are allowed. Otherwise, all identity escapes are
            // allowed.
            if (!is_unicode() || IsSyntaxCharacterOrSlash(current())) {
              builder->AddCharacter(current());
              Advance();
            } else {
              ReportError(kUnicodeIdentity);
              UNREACHABLE();
            }
            break;
        }
        break;
      case '{': {
        intptr_t dummy;
        if (ParseIntervalQuantifier(&dummy, &dummy)) {
          ReportError("Nothing to repeat");
          UNREACHABLE();
        }
      }
        FALL_THROUGH;
      case '}':
      case ']':
        if (is_unicode()) {
          ReportError("Lone quantifier brackets");
          UNREACHABLE();
        }
        FALL_THROUGH;
      default:
        builder->AddUnicodeCharacter(current());
        Advance();
        break;
    }  // end switch(current())

    intptr_t min;
    intptr_t max;
    switch (current()) {
      // QuantifierPrefix ::
      //   *
      //   +
      //   ?
      //   {
      case '*':
        min = 0;
        max = RegExpTree::kInfinity;
        Advance();
        break;
      case '+':
        min = 1;
        max = RegExpTree::kInfinity;
        Advance();
        break;
      case '?':
        min = 0;
        max = 1;
        Advance();
        break;
      case '{':
        if (ParseIntervalQuantifier(&min, &max)) {
          if (max < min) {
            ReportError("numbers out of order in {} quantifier.");
            UNREACHABLE();
          }
          break;
        } else {
          continue;
        }
      default:
        continue;
    }
    RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
    if (current() == '?') {
      quantifier_type = RegExpQuantifier::NON_GREEDY;
      Advance();
    } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
      // FLAG_regexp_possessive_quantifier is a debug-only flag.
      quantifier_type = RegExpQuantifier::POSSESSIVE;
      Advance();
    }
    if (!builder->AddQuantifierToAtom(min, max, quantifier_type)) {
      ReportError("invalid quantifier.");
      UNREACHABLE();
    }
  }
}

#ifdef DEBUG
// Currently only used in an ASSERT.
static bool IsSpecialClassEscape(uint32_t c) {
  switch (c) {
    case 'd':
    case 'D':
    case 's':
    case 'S':
    case 'w':
    case 'W':
      return true;
    default:
      return false;
  }
}
#endif

RegExpParser::RegExpParserState* RegExpParser::ParseOpenParenthesis(
    RegExpParserState* state) {
  RegExpLookaround::Type lookaround_type = state->lookaround_type();
  bool is_named_capture = false;
  const RegExpCaptureName* capture_name = nullptr;
  SubexpressionType subexpr_type = CAPTURE;
  Advance();
  if (current() == '?') {
    switch (Next()) {
      case ':':
        Advance(2);
        subexpr_type = GROUPING;
        break;
      case '=':
        Advance(2);
        lookaround_type = RegExpLookaround::LOOKAHEAD;
        subexpr_type = POSITIVE_LOOKAROUND;
        break;
      case '!':
        Advance(2);
        lookaround_type = RegExpLookaround::LOOKAHEAD;
        subexpr_type = NEGATIVE_LOOKAROUND;
        break;
      case '<':
        Advance();
        if (Next() == '=') {
          Advance(2);
          lookaround_type = RegExpLookaround::LOOKBEHIND;
          subexpr_type = POSITIVE_LOOKAROUND;
          break;
        } else if (Next() == '!') {
          Advance(2);
          lookaround_type = RegExpLookaround::LOOKBEHIND;
          subexpr_type = NEGATIVE_LOOKAROUND;
          break;
        }
        is_named_capture = true;
        has_named_captures_ = true;
        Advance();
        break;
      default:
        ReportError("Invalid group");
        UNREACHABLE();
    }
  }

  if (subexpr_type == CAPTURE) {
    if (captures_started_ >= kMaxCaptures) {
      ReportError("Too many captures");
      UNREACHABLE();
    }
    captures_started_++;

    if (is_named_capture) {
      capture_name = ParseCaptureGroupName();
    }
  }
  // Store current state and begin new disjunction parsing.
  return new (Z)
      RegExpParserState(state, subexpr_type, lookaround_type, captures_started_,
                        capture_name, state->builder()->flags(), Z);
}

// In order to know whether an escape is a backreference or not we have to scan
// the entire regexp and find the number of capturing parentheses.  However we
// don't want to scan the regexp twice unless it is necessary.  This mini-parser
// is called when needed.  It can see the difference between capturing and
// noncapturing parentheses and can skip character classes and backslash-escaped
// characters.
void RegExpParser::ScanForCaptures() {
  ASSERT(!is_scanned_for_captures_);
  const intptr_t saved_position = position();
  // Start with captures started previous to current position
  intptr_t capture_count = captures_started();
  // Add count of captures after this position.
  uintptr_t n;
  while ((n = current()) != kEndMarker) {
    Advance();
    switch (n) {
      case '\\':
        Advance();
        break;
      case '[': {
        uintptr_t c;
        while ((c = current()) != kEndMarker) {
          Advance();
          if (c == '\\') {
            Advance();
          } else {
            if (c == ']') break;
          }
        }
        break;
      }
      case '(':
        // At this point we could be in
        // * a non-capturing group '(:',
        // * a lookbehind assertion '(?<=' '(?<!'
        // * or a named capture '(?<'.
        //
        // Of these, only named captures are capturing groups.
        if (current() == '?') {
          Advance();
          if (current() != '<') break;

          Advance();
          if (current() == '=' || current() == '!') break;

          // Found a possible named capture. It could turn out to be a syntax
          // error (e.g. an unterminated or invalid name), but that distinction
          // does not matter for our purposes.
          has_named_captures_ = true;
        }
        capture_count++;
        break;
    }
  }
  capture_count_ = capture_count;
  is_scanned_for_captures_ = true;
  Reset(saved_position);
}

bool RegExpParser::ParseBackReferenceIndex(intptr_t* index_out) {
  ASSERT('\\' == current());
  ASSERT('1' <= Next() && Next() <= '9');
  // Try to parse a decimal literal that is no greater than the total number
  // of left capturing parentheses in the input.
  intptr_t start = position();
  intptr_t value = Next() - '0';
  Advance(2);
  while (true) {
    uint32_t c = current();
    if (Utils::IsDecimalDigit(c)) {
      value = 10 * value + (c - '0');
      if (value > kMaxCaptures) {
        Reset(start);
        return false;
      }
      Advance();
    } else {
      break;
    }
  }
  if (value > captures_started()) {
    if (!is_scanned_for_captures_) ScanForCaptures();
    if (value > capture_count_) {
      Reset(start);
      return false;
    }
  }
  *index_out = value;
  return true;
}

namespace {

static inline constexpr bool IsAsciiIdentifierPart(uint32_t ch) {
  return Utils::IsAlphaNumeric(ch) || ch == '_' || ch == '$';
}

// ES#sec-names-and-keywords Names and Keywords
// UnicodeIDStart, '$', '_' and '\'
static bool IsIdentifierStartSlow(uint32_t c) {
  // cannot use u_isIDStart because it does not work for
  // Other_ID_Start characters.
  return u_hasBinaryProperty(c, UCHAR_ID_START) ||
         (c < 0x60 && (c == '$' || c == '\\' || c == '_'));
}

// ES#sec-names-and-keywords Names and Keywords
// UnicodeIDContinue, '$', '_', '\', ZWJ, and ZWNJ
static bool IsIdentifierPartSlow(uint32_t c) {
  const uint32_t kZeroWidthNonJoiner = 0x200C;
  const uint32_t kZeroWidthJoiner = 0x200D;
  // Can't use u_isIDPart because it does not work for
  // Other_ID_Continue characters.
  return u_hasBinaryProperty(c, UCHAR_ID_CONTINUE) ||
         (c < 0x60 && (c == '$' || c == '\\' || c == '_')) ||
         c == kZeroWidthNonJoiner || c == kZeroWidthJoiner;
}

static inline bool IsIdentifierStart(uint32_t c) {
  if (c > 127) return IsIdentifierStartSlow(c);
  return IsAsciiIdentifierPart(c) && !Utils::IsDecimalDigit(c);
}

static inline bool IsIdentifierPart(uint32_t c) {
  if (c > 127) return IsIdentifierPartSlow(c);
  return IsAsciiIdentifierPart(c);
}

static bool IsSameName(const RegExpCaptureName* name1,
                       const RegExpCaptureName* name2) {
  if (name1->length() != name2->length()) return false;
  for (intptr_t i = 0; i < name1->length(); i++) {
    if (name1->At(i) != name2->At(i)) return false;
  }
  return true;
}

}  // end namespace

static void PushCodeUnit(RegExpCaptureName* v, uint32_t code_unit) {
  if (code_unit <= Utf16::kMaxCodeUnit) {
    v->Add(code_unit);
  } else {
    uint16_t units[2];
    Utf16::Encode(code_unit, units);
    v->Add(units[0]);
    v->Add(units[1]);
  }
}

const RegExpCaptureName* RegExpParser::ParseCaptureGroupName() {
  auto name = new (Z) RegExpCaptureName();

  bool at_start = true;
  while (true) {
    uint32_t c = current();
    Advance();

    // Convert unicode escapes.
    if (c == '\\' && current() == 'u') {
      Advance();
      if (!ParseUnicodeEscape(&c)) {
        ReportError("Invalid Unicode escape sequence");
        UNREACHABLE();
      }
    }

    // The backslash char is misclassified as both ID_Start and ID_Continue.
    if (c == '\\') {
      ReportError("Invalid capture group name");
      UNREACHABLE();
    }

    if (at_start) {
      if (!IsIdentifierStart(c)) {
        ReportError("Invalid capture group name");
        UNREACHABLE();
      }
      PushCodeUnit(name, c);
      at_start = false;
    } else {
      if (c == '>') {
        break;
      } else if (IsIdentifierPart(c)) {
        PushCodeUnit(name, c);
      } else {
        ReportError("Invalid capture group name");
        UNREACHABLE();
      }
    }
  }

  return name;
}

intptr_t RegExpParser::GetNamedCaptureIndex(const RegExpCaptureName* name) {
  for (const auto& capture : *named_captures_) {
    if (IsSameName(name, capture->name())) return capture->index();
  }
  return -1;
}

void RegExpParser::CreateNamedCaptureAtIndex(const RegExpCaptureName* name,
                                             intptr_t index) {
  ASSERT(0 < index && index <= captures_started_);
  ASSERT(name != nullptr);

  if (named_captures_ == nullptr) {
    named_captures_ = new (Z) ZoneGrowableArray<RegExpCapture*>(1);
  } else {
    // Check for duplicates and bail if we find any. Currently O(n^2).
    if (GetNamedCaptureIndex(name) >= 0) {
      ReportError("Duplicate capture group name");
      UNREACHABLE();
    }
  }

  RegExpCapture* capture = GetCapture(index);
  ASSERT(capture->name() == nullptr);

  capture->set_name(name);
  named_captures_->Add(capture);
}

bool RegExpParser::ParseNamedBackReference(RegExpBuilder* builder,
                                           RegExpParserState* state) {
  // The parser is assumed to be on the '<' in \k<name>.
  if (current() != '<') {
    ReportError("Invalid named reference");
    UNREACHABLE();
  }

  Advance();
  const RegExpCaptureName* name = ParseCaptureGroupName();
  if (name == nullptr) {
    return false;
  }

  if (state->IsInsideCaptureGroup(name)) {
    builder->AddEmpty();
  } else {
    RegExpBackReference* atom = new (Z) RegExpBackReference(builder->flags());
    atom->set_name(name);

    builder->AddAtom(atom);

    if (named_back_references_ == nullptr) {
      named_back_references_ =
          new (Z) ZoneGrowableArray<RegExpBackReference*>(1);
    }
    named_back_references_->Add(atom);
  }

  return true;
}

void RegExpParser::PatchNamedBackReferences() {
  if (named_back_references_ == nullptr) return;

  if (named_captures_ == nullptr) {
    ReportError("Invalid named capture referenced");
    return;
  }

  // Look up and patch the actual capture for each named back reference.
  // Currently O(n^2), optimize if necessary.
  for (intptr_t i = 0; i < named_back_references_->length(); i++) {
    RegExpBackReference* ref = named_back_references_->At(i);
    intptr_t index = GetNamedCaptureIndex(ref->name());

    if (index < 0) {
      ReportError("Invalid named capture referenced");
      UNREACHABLE();
    }
    ref->set_capture(GetCapture(index));
  }
}

RegExpCapture* RegExpParser::GetCapture(intptr_t index) {
  // The index for the capture groups are one-based. Its index in the list is
  // zero-based.
  const intptr_t know_captures =
      is_scanned_for_captures_ ? capture_count_ : captures_started_;
  ASSERT(index <= know_captures);
  if (captures_ == nullptr) {
    captures_ = new (Z) ZoneGrowableArray<RegExpCapture*>(know_captures);
  }
  while (captures_->length() < know_captures) {
    captures_->Add(new (Z) RegExpCapture(captures_->length() + 1));
  }
  return captures_->At(index - 1);
}

ArrayPtr RegExpParser::CreateCaptureNameMap() {
  if (named_captures_ == nullptr || named_captures_->is_empty()) {
    return Array::null();
  }

  const intptr_t len = named_captures_->length() * 2;

  const Array& array = Array::Handle(Array::New(len));

  auto& name = String::Handle();
  auto& smi = Smi::Handle();
  for (intptr_t i = 0; i < named_captures_->length(); i++) {
    RegExpCapture* capture = named_captures_->At(i);
    name =
        String::FromUTF16(capture->name()->data(), capture->name()->length());
    smi = Smi::New(capture->index());
    array.SetAt(i * 2, name);
    array.SetAt(i * 2 + 1, smi);
  }

  return array.ptr();
}

bool RegExpParser::HasNamedCaptures() {
  if (has_named_captures_ || is_scanned_for_captures_) {
    return has_named_captures_;
  }

  ScanForCaptures();
  ASSERT(is_scanned_for_captures_);
  return has_named_captures_;
}

bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(intptr_t index) {
  for (RegExpParserState* s = this; s != nullptr; s = s->previous_state()) {
    if (s->group_type() != CAPTURE) continue;
    // Return true if we found the matching capture index.
    if (index == s->capture_index()) return true;
    // Abort if index is larger than what has been parsed up till this state.
    if (index > s->capture_index()) return false;
  }
  return false;
}

bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(
    const RegExpCaptureName* name) {
  ASSERT(name != nullptr);
  for (RegExpParserState* s = this; s != nullptr; s = s->previous_state()) {
    if (s->capture_name() == nullptr) continue;
    if (IsSameName(s->capture_name(), name)) return true;
  }
  return false;
}

// QuantifierPrefix ::
//   { DecimalDigits }
//   { DecimalDigits , }
//   { DecimalDigits , DecimalDigits }
//
// Returns true if parsing succeeds, and set the min_out and max_out
// values. Values are truncated to RegExpTree::kInfinity if they overflow.
bool RegExpParser::ParseIntervalQuantifier(intptr_t* min_out,
                                           intptr_t* max_out) {
  ASSERT(current() == '{');
  intptr_t start = position();
  Advance();
  intptr_t min = 0;
  if (!Utils::IsDecimalDigit(current())) {
    Reset(start);
    return false;
  }
  while (Utils::IsDecimalDigit(current())) {
    intptr_t next = current() - '0';
    if (min > (RegExpTree::kInfinity - next) / 10) {
      // Overflow. Skip past remaining decimal digits and return -1.
      do {
        Advance();
      } while (Utils::IsDecimalDigit(current()));
      min = RegExpTree::kInfinity;
      break;
    }
    min = 10 * min + next;
    Advance();
  }
  intptr_t max = 0;
  if (current() == '}') {
    max = min;
    Advance();
  } else if (current() == ',') {
    Advance();
    if (current() == '}') {
      max = RegExpTree::kInfinity;
      Advance();
    } else {
      while (Utils::IsDecimalDigit(current())) {
        intptr_t next = current() - '0';
        if (max > (RegExpTree::kInfinity - next) / 10) {
          do {
            Advance();
          } while (Utils::IsDecimalDigit(current()));
          max = RegExpTree::kInfinity;
          break;
        }
        max = 10 * max + next;
        Advance();
      }
      if (current() != '}') {
        Reset(start);
        return false;
      }
      Advance();
    }
  } else {
    Reset(start);
    return false;
  }
  *min_out = min;
  *max_out = max;
  return true;
}

uint32_t RegExpParser::ParseOctalLiteral() {
  ASSERT(('0' <= current() && current() <= '7') || current() == kEndMarker);
  // For compatibility with some other browsers (not all), we parse
  // up to three octal digits with a value below 256.
  uint32_t value = current() - '0';
  Advance();
  if ('0' <= current() && current() <= '7') {
    value = value * 8 + current() - '0';
    Advance();
    if (value < 32 && '0' <= current() && current() <= '7') {
      value = value * 8 + current() - '0';
      Advance();
    }
  }
  return value;
}

// Returns the value (0 .. 15) of a hexadecimal character c.
// If c is not a legal hexadecimal character, returns a value < 0.
static inline intptr_t HexValue(uint32_t c) {
  c -= '0';
  if (static_cast<unsigned>(c) <= 9) return c;
  c = (c | 0x20) - ('a' - '0');  // detect 0x11..0x16 and 0x31..0x36.
  if (static_cast<unsigned>(c) <= 5) return c + 10;
  return -1;
}

bool RegExpParser::ParseHexEscape(intptr_t length, uint32_t* value) {
  intptr_t start = position();
  uint32_t val = 0;
  bool done = false;
  for (intptr_t i = 0; !done; i++) {
    uint32_t c = current();
    intptr_t d = HexValue(c);
    if (d < 0) {
      Reset(start);
      return false;
    }
    val = val * 16 + d;
    Advance();
    if (i == length - 1) {
      done = true;
    }
  }
  *value = val;
  return true;
}

// This parses RegExpUnicodeEscapeSequence as described in ECMA262.
bool RegExpParser::ParseUnicodeEscape(uint32_t* value) {
  // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
  // allowed). In the latter case, the number of hex digits between { } is
  // arbitrary. \ and u have already been read.
  if (current() == '{' && is_unicode()) {
    int start = position();
    Advance();
    if (ParseUnlimitedLengthHexNumber(Utf::kMaxCodePoint, value)) {
      if (current() == '}') {
        Advance();
        return true;
      }
    }
    Reset(start);
    return false;
  }
  // \u but no {, or \u{...} escapes not allowed.
  bool result = ParseHexEscape(4, value);
  if (result && is_unicode() && Utf16::IsLeadSurrogate(*value) &&
      current() == '\\') {
    // Attempt to read trail surrogate.
    int start = position();
    if (Next() == 'u') {
      Advance(2);
      uint32_t trail;
      if (ParseHexEscape(4, &trail) && Utf16::IsTrailSurrogate(trail)) {
        *value = Utf16::Decode(static_cast<uint16_t>(*value),
                               static_cast<uint16_t>(trail));
        return true;
      }
    }
    Reset(start);
  }
  return result;
}

namespace {

bool IsExactPropertyAlias(const char* property_name, UProperty property) {
  const char* short_name = u_getPropertyName(property, U_SHORT_PROPERTY_NAME);
  if (short_name != nullptr && strcmp(property_name, short_name) == 0) {
    return true;
  }
  for (int i = 0;; i++) {
    const char* long_name = u_getPropertyName(
        property, static_cast<UPropertyNameChoice>(U_LONG_PROPERTY_NAME + i));
    if (long_name == nullptr) break;
    if (strcmp(property_name, long_name) == 0) return true;
  }
  return false;
}

bool IsExactPropertyValueAlias(const char* property_value_name,
                               UProperty property,
                               int32_t property_value) {
  const char* short_name =
      u_getPropertyValueName(property, property_value, U_SHORT_PROPERTY_NAME);
  if (short_name != nullptr && strcmp(property_value_name, short_name) == 0) {
    return true;
  }
  for (int i = 0;; i++) {
    const char* long_name = u_getPropertyValueName(
        property, property_value,
        static_cast<UPropertyNameChoice>(U_LONG_PROPERTY_NAME + i));
    if (long_name == nullptr) break;
    if (strcmp(property_value_name, long_name) == 0) return true;
  }
  return false;
}

bool LookupPropertyValueName(UProperty property,
                             const char* property_value_name,
                             bool negate,
                             ZoneGrowableArray<CharacterRange>* result) {
  UProperty property_for_lookup = property;
  if (property_for_lookup == UCHAR_SCRIPT_EXTENSIONS) {
    // For the property Script_Extensions, we have to do the property value
    // name lookup as if the property is Script.
    property_for_lookup = UCHAR_SCRIPT;
  }
  int32_t property_value =
      u_getPropertyValueEnum(property_for_lookup, property_value_name);
  if (property_value == UCHAR_INVALID_CODE) return false;

  // We require the property name to match exactly to one of the property value
  // aliases. However, u_getPropertyValueEnum uses loose matching.
  if (!IsExactPropertyValueAlias(property_value_name, property_for_lookup,
                                 property_value)) {
    return false;
  }

  UErrorCode ec = U_ZERO_ERROR;
  icu::UnicodeSet set;
  set.applyIntPropertyValue(property, property_value, ec);
  bool success = ec == U_ZERO_ERROR && (set.isEmpty() == 0);

  if (success) {
    set.removeAllStrings();
    if (negate) set.complement();
    for (int i = 0; i < set.getRangeCount(); i++) {
      result->Add(
          CharacterRange::Range(set.getRangeStart(i), set.getRangeEnd(i)));
    }
  }
  return success;
}

template <size_t N>
inline bool NameEquals(const char* name, const char (&literal)[N]) {
  return strncmp(name, literal, N + 1) == 0;
}

bool LookupSpecialPropertyValueName(const char* name,
                                    ZoneGrowableArray<CharacterRange>* result,
                                    bool negate) {
  if (NameEquals(name, "Any")) {
    if (negate) {
      // Leave the list of character ranges empty, since the negation of 'Any'
      // is the empty set.
    } else {
      result->Add(CharacterRange::Everything());
    }
  } else if (NameEquals(name, "ASCII")) {
    result->Add(negate ? CharacterRange::Range(0x80, Utf::kMaxCodePoint)
                       : CharacterRange::Range(0x0, 0x7F));
  } else if (NameEquals(name, "Assigned")) {
    return LookupPropertyValueName(UCHAR_GENERAL_CATEGORY, "Unassigned",
                                   !negate, result);
  } else {
    return false;
  }
  return true;
}

// Explicitly list supported binary properties. The spec forbids supporting
// properties outside of this set to ensure interoperability.
bool IsSupportedBinaryProperty(UProperty property) {
  switch (property) {
    case UCHAR_ALPHABETIC:
    // 'Any' is not supported by ICU. See LookupSpecialPropertyValueName.
    // 'ASCII' is not supported by ICU. See LookupSpecialPropertyValueName.
    case UCHAR_ASCII_HEX_DIGIT:
    // 'Assigned' is not supported by ICU. See LookupSpecialPropertyValueName.
    case UCHAR_BIDI_CONTROL:
    case UCHAR_BIDI_MIRRORED:
    case UCHAR_CASE_IGNORABLE:
    case UCHAR_CASED:
    case UCHAR_CHANGES_WHEN_CASEFOLDED:
    case UCHAR_CHANGES_WHEN_CASEMAPPED:
    case UCHAR_CHANGES_WHEN_LOWERCASED:
    case UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED:
    case UCHAR_CHANGES_WHEN_TITLECASED:
    case UCHAR_CHANGES_WHEN_UPPERCASED:
    case UCHAR_DASH:
    case UCHAR_DEFAULT_IGNORABLE_CODE_POINT:
    case UCHAR_DEPRECATED:
    case UCHAR_DIACRITIC:
    case UCHAR_EMOJI:
    case UCHAR_EMOJI_COMPONENT:
    case UCHAR_EMOJI_MODIFIER_BASE:
    case UCHAR_EMOJI_MODIFIER:
    case UCHAR_EMOJI_PRESENTATION:
    case UCHAR_EXTENDED_PICTOGRAPHIC:
    case UCHAR_EXTENDER:
    case UCHAR_GRAPHEME_BASE:
    case UCHAR_GRAPHEME_EXTEND:
    case UCHAR_HEX_DIGIT:
    case UCHAR_ID_CONTINUE:
    case UCHAR_ID_START:
    case UCHAR_IDEOGRAPHIC:
    case UCHAR_IDS_BINARY_OPERATOR:
    case UCHAR_IDS_TRINARY_OPERATOR:
    case UCHAR_JOIN_CONTROL:
    case UCHAR_LOGICAL_ORDER_EXCEPTION:
    case UCHAR_LOWERCASE:
    case UCHAR_MATH:
    case UCHAR_NONCHARACTER_CODE_POINT:
    case UCHAR_PATTERN_SYNTAX:
    case UCHAR_PATTERN_WHITE_SPACE:
    case UCHAR_QUOTATION_MARK:
    case UCHAR_RADICAL:
    case UCHAR_REGIONAL_INDICATOR:
    case UCHAR_S_TERM:
    case UCHAR_SOFT_DOTTED:
    case UCHAR_TERMINAL_PUNCTUATION:
    case UCHAR_UNIFIED_IDEOGRAPH:
    case UCHAR_UPPERCASE:
    case UCHAR_VARIATION_SELECTOR:
    case UCHAR_WHITE_SPACE:
    case UCHAR_XID_CONTINUE:
    case UCHAR_XID_START:
      return true;
    default:
      break;
  }
  return false;
}

bool IsUnicodePropertyValueCharacter(char c) {
  // https://tc39.github.io/proposal-regexp-unicode-property-escapes/
  //
  // Note that using this to validate each parsed char is quite conservative.
  // A possible alternative solution would be to only ensure the parsed
  // property name/value candidate string does not contain '\0' characters and
  // let ICU lookups trigger the final failure.
  if (Utils::IsAlphaNumeric(c)) return true;
  return (c == '_');
}

}  // anonymous namespace

bool RegExpParser::ParsePropertyClassName(ZoneGrowableArray<char>* name_1,
                                          ZoneGrowableArray<char>* name_2) {
  ASSERT(name_1->is_empty());
  ASSERT(name_2->is_empty());
  // Parse the property class as follows:
  // - In \p{name}, 'name' is interpreted
  //   - either as a general category property value name.
  //   - or as a binary property name.
  // - In \p{name=value}, 'name' is interpreted as an enumerated property name,
  //   and 'value' is interpreted as one of the available property value names.
  // - Aliases in PropertyAlias.txt and PropertyValueAlias.txt can be used.
  // - Loose matching is not applied.
  if (current() == '{') {
    // Parse \p{[PropertyName=]PropertyNameValue}
    for (Advance(); current() != '}' && current() != '='; Advance()) {
      if (!IsUnicodePropertyValueCharacter(current())) return false;
      if (!has_next()) return false;
      name_1->Add(static_cast<char>(current()));
    }
    if (current() == '=') {
      for (Advance(); current() != '}'; Advance()) {
        if (!IsUnicodePropertyValueCharacter(current())) return false;
        if (!has_next()) return false;
        name_2->Add(static_cast<char>(current()));
      }
      name_2->Add(0);  // null-terminate string.
    }
  } else {
    return false;
  }
  Advance();
  name_1->Add(0);  // null-terminate string.

  ASSERT(static_cast<size_t>(name_1->length() - 1) == strlen(name_1->data()));
  ASSERT(name_2->is_empty() ||
         static_cast<size_t>(name_2->length() - 1) == strlen(name_2->data()));
  return true;
}

bool RegExpParser::AddPropertyClassRange(
    ZoneGrowableArray<CharacterRange>* add_to,
    bool negate,
    ZoneGrowableArray<char>* name_1,
    ZoneGrowableArray<char>* name_2) {
  ASSERT(name_1->At(name_1->length() - 1) == '\0');
  ASSERT(name_2->is_empty() || name_2->At(name_2->length() - 1) == '\0');
  if (name_2->is_empty()) {
    // First attempt to interpret as general category property value name.
    const char* name = name_1->data();
    if (LookupPropertyValueName(UCHAR_GENERAL_CATEGORY_MASK, name, negate,
                                add_to)) {
      return true;
    }
    // Interpret "Any", "ASCII", and "Assigned".
    if (LookupSpecialPropertyValueName(name, add_to, negate)) {
      return true;
    }
    // Then attempt to interpret as binary property name with value name 'Y'.
    UProperty property = u_getPropertyEnum(name);
    if (!IsSupportedBinaryProperty(property)) return false;
    if (!IsExactPropertyAlias(name, property)) return false;
    return LookupPropertyValueName(property, negate ? "N" : "Y", false, add_to);
  } else {
    // Both property name and value name are specified. Attempt to interpret
    // the property name as enumerated property.
    const char* property_name = name_1->data();
    const char* value_name = name_2->data();
    UProperty property = u_getPropertyEnum(property_name);
    if (!IsExactPropertyAlias(property_name, property)) return false;
    if (property == UCHAR_GENERAL_CATEGORY) {
      // We want to allow aggregate value names such as "Letter".
      property = UCHAR_GENERAL_CATEGORY_MASK;
    } else if (property != UCHAR_SCRIPT &&
               property != UCHAR_SCRIPT_EXTENSIONS) {
      return false;
    }
    return LookupPropertyValueName(property, value_name, negate, add_to);
  }
}

bool RegExpParser::ParseUnlimitedLengthHexNumber(uint32_t max_value,
                                                 uint32_t* value) {
  uint32_t x = 0;
  int d = HexValue(current());
  if (d < 0) {
    return false;
  }
  while (d >= 0) {
    x = x * 16 + d;
    if (x > max_value) {
      return false;
    }
    Advance();
    d = HexValue(current());
  }
  *value = x;
  return true;
}

uint32_t RegExpParser::ParseClassCharacterEscape() {
  ASSERT(current() == '\\');
  DEBUG_ASSERT(has_next() && !IsSpecialClassEscape(Next()));
  Advance();
  switch (current()) {
    case 'b':
      Advance();
      return '\b';
    // ControlEscape :: one of
    //   f n r t v
    case 'f':
      Advance();
      return '\f';
    case 'n':
      Advance();
      return '\n';
    case 'r':
      Advance();
      return '\r';
    case 't':
      Advance();
      return '\t';
    case 'v':
      Advance();
      return '\v';
    case 'c': {
      uint32_t controlLetter = Next();
      uint32_t letter = controlLetter & ~('A' ^ 'a');
      // For compatibility with JSC, inside a character class
      // we also accept digits and underscore as control characters.
      if (letter >= 'A' && letter <= 'Z') {
        Advance(2);
        // Control letters mapped to ASCII control characters in the range
        // 0x00-0x1f.
        return controlLetter & 0x1f;
      }
      if (is_unicode()) {
        // With /u, \c# or \c_ are invalid.
        ReportError("Invalid class escape");
        UNREACHABLE();
      }
      if (Utils::IsDecimalDigit(controlLetter) || controlLetter == '_') {
        Advance(2);
        return controlLetter & 0x1f;
      }
      // We match JSC in reading the backslash as a literal
      // character instead of as starting an escape.
      return '\\';
    }
    case '0':
      // With /u, \0 is interpreted as NUL if not followed by another digit.
      if (is_unicode() && !(Next() >= '0' && Next() <= '9')) {
        Advance();
        return 0;
      }
      FALL_THROUGH;
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      // For compatibility, we interpret a decimal escape that isn't
      // a back reference (and therefore either \0 or not valid according
      // to the specification) as a 1..3 digit octal character code.
      if (is_unicode()) {
        // With \u, decimal escape is not interpreted as octal character code.
        ReportError("Invalid class escape");
        UNREACHABLE();
      }
      return ParseOctalLiteral();
    case 'x': {
      Advance();
      uint32_t value;
      if (ParseHexEscape(2, &value)) {
        return value;
      }
      if (is_unicode()) {
        // With \u, invalid escapes are not treated as identity escapes.
        ReportError("Invalid escape");
        UNREACHABLE();
      }
      // If \x is not followed by a two-digit hexadecimal, treat it
      // as an identity escape.
      return 'x';
    }
    case 'u': {
      Advance();
      uint32_t value;
      if (ParseUnicodeEscape(&value)) {
        return value;
      }
      if (is_unicode()) {
        // With \u, invalid escapes are not treated as identity escapes.
        ReportError(kUnicodeIdentity);
        UNREACHABLE();
      }
      // If \u is not followed by a four-digit hexadecimal, treat it
      // as an identity escape.
      return 'u';
    }
    default: {
      // Extended identity escape. We accept any character that hasn't
      // been matched by a more specific case, not just the subset required
      // by the ECMAScript specification.
      uint32_t result = current();
      if (!is_unicode() || IsSyntaxCharacterOrSlash(result) || result == '-') {
        Advance();
        return result;
      }
      ReportError(kUnicodeIdentity);
      UNREACHABLE();
    }
  }
  return 0;
}

bool RegExpParser::ParseClassEscape(ZoneGrowableArray<CharacterRange>* ranges,
                                    bool add_unicode_case_equivalents,
                                    uint32_t* char_out) {
  uint32_t first = current();
  if (first == '\\') {
    switch (Next()) {
      case 'w':
      case 'W':
      case 'd':
      case 'D':
      case 's':
      case 'S': {
        CharacterRange::AddClassEscape(static_cast<uint16_t>(Next()), ranges,
                                       add_unicode_case_equivalents);
        Advance(2);
        return true;
      }
      case 'p':
      case 'P': {
        if (!is_unicode()) break;
        bool negate = Next() == 'P';
        Advance(2);
        auto name_1 = new (Z) ZoneGrowableArray<char>();
        auto name_2 = new (Z) ZoneGrowableArray<char>();
        if (!ParsePropertyClassName(name_1, name_2) ||
            !AddPropertyClassRange(ranges, negate, name_1, name_2)) {
          ReportError("Invalid property name in character class");
          UNREACHABLE();
        }
        return true;
      }
      case kEndMarker:
        ReportError("\\ at end of pattern");
        UNREACHABLE();
      default:
        break;
    }
    *char_out = ParseClassCharacterEscape();
    return false;
  }
  Advance();
  *char_out = first;
  return false;
}

RegExpTree* RegExpParser::ParseCharacterClass(const RegExpBuilder* builder) {
  static const char* kUnterminated = "Unterminated character class";
  static const char* kRangeInvalid = "Invalid character class";
  static const char* kRangeOutOfOrder = "Range out of order in character class";

  ASSERT(current() == '[');
  Advance();
  bool is_negated = false;
  if (current() == '^') {
    is_negated = true;
    Advance();
  }
  ZoneGrowableArray<CharacterRange>* ranges =
      new (Z) ZoneGrowableArray<CharacterRange>(2);
  bool add_unicode_case_equivalents = is_unicode() && builder->ignore_case();
  while (has_more() && current() != ']') {
    uint32_t char_1 = 0;
    bool is_class_1 =
        ParseClassEscape(ranges, add_unicode_case_equivalents, &char_1);
    if (current() == '-') {
      Advance();
      if (current() == kEndMarker) {
        // If we reach the end we break out of the loop and let the
        // following code report an error.
        break;
      } else if (current() == ']') {
        if (!is_class_1) ranges->Add(CharacterRange::Singleton(char_1));
        ranges->Add(CharacterRange::Singleton('-'));
        break;
      }
      uint32_t char_2 = 0;
      bool is_class_2 =
          ParseClassEscape(ranges, add_unicode_case_equivalents, &char_2);
      if (is_class_1 || is_class_2) {
        // Either end is an escaped character class. Treat the '-' verbatim.
        if (is_unicode()) {
          // ES2015 21.2.2.15.1 step 1.
          ReportError(kRangeInvalid);
          UNREACHABLE();
        }
        if (!is_class_1) ranges->Add(CharacterRange::Singleton(char_1));
        ranges->Add(CharacterRange::Singleton('-'));
        if (!is_class_2) ranges->Add(CharacterRange::Singleton(char_2));
        continue;
      }
      if (char_1 > char_2) {
        ReportError(kRangeOutOfOrder);
        UNREACHABLE();
      }
      ranges->Add(CharacterRange::Range(char_1, char_2));
    } else {
      if (!is_class_1) ranges->Add(CharacterRange::Singleton(char_1));
    }
  }
  if (!has_more()) {
    ReportError(kUnterminated);
    UNREACHABLE();
  }
  Advance();
  RegExpCharacterClass::CharacterClassFlags character_class_flags =
      RegExpCharacterClass::DefaultFlags();
  if (is_negated) character_class_flags |= RegExpCharacterClass::NEGATED;
  return new (Z)
      RegExpCharacterClass(ranges, builder->flags(), character_class_flags);
}

// ----------------------------------------------------------------------------
// The Parser interface.

void RegExpParser::ParseRegExp(const String& input,
                               RegExpFlags flags,
                               RegExpCompileData* result) {
  ASSERT(result != NULL);
  RegExpParser parser(input, &result->error, flags);
  // Throws an exception if 'input' is not valid.
  RegExpTree* tree = parser.ParsePattern();
  ASSERT(tree != NULL);
  ASSERT(result->error.IsNull());
  result->tree = tree;
  intptr_t capture_count = parser.captures_started();
  result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
  result->contains_anchor = parser.contains_anchor();
  result->capture_name_map = parser.CreateCaptureNameMap();
  result->capture_count = capture_count;
}

}  // namespace dart
