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

#ifndef RUNTIME_VM_REGEXP_PARSER_H_
#define RUNTIME_VM_REGEXP_PARSER_H_

#include "vm/allocation.h"
#include "vm/growable_array.h"
#include "vm/regexp_ast.h"

namespace dart {

// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
class RegExpBuilder : public ZoneAllocated {
 public:
  explicit RegExpBuilder(RegExpFlags flags);

  void AddCharacter(uint16_t character);
  void AddUnicodeCharacter(uint32_t character);
  void AddEscapedUnicodeCharacter(uint32_t character);
  // "Adds" an empty expression. Does nothing except consume a
  // following quantifier
  void AddEmpty();
  void AddCharacterClass(RegExpCharacterClass* cc);
  void AddCharacterClassForDesugaring(uint32_t c);
  void AddAtom(RegExpTree* tree);
  void AddTerm(RegExpTree* tree);
  void AddAssertion(RegExpTree* tree);
  void NewAlternative();  // '|'
  // Attempt to add a quantifier to the last atom added. The return value
  // denotes whether the attempt succeeded, since some atoms like lookbehind
  // cannot be quantified.
  bool AddQuantifierToAtom(intptr_t min,
                           intptr_t max,
                           RegExpQuantifier::QuantifierType type);
  RegExpTree* ToRegExp();
  RegExpFlags flags() const { return flags_; }
  bool ignore_case() const { return flags_.IgnoreCase(); }
  bool is_multi_line() const { return flags_.IsMultiLine(); }
  bool is_dot_all() const { return flags_.IsDotAll(); }

 private:
  static constexpr uint16_t kNoPendingSurrogate = 0;
  void AddLeadSurrogate(uint16_t lead_surrogate);
  void AddTrailSurrogate(uint16_t trail_surrogate);
  void FlushPendingSurrogate();
  void FlushCharacters();
  void FlushText();
  void FlushTerms();
  bool NeedsDesugaringForUnicode(RegExpCharacterClass* cc);
  bool NeedsDesugaringForIgnoreCase(uint32_t c);

  Zone* zone() const { return zone_; }
  bool is_unicode() const { return flags_.IsUnicode(); }

  Zone* zone_;
  bool pending_empty_;
  RegExpFlags flags_;
  ZoneGrowableArray<uint16_t>* characters_;
  uint16_t pending_surrogate_;
  GrowableArray<RegExpTree*> terms_;
  GrowableArray<RegExpTree*> text_;
  GrowableArray<RegExpTree*> alternatives_;
#ifdef DEBUG
  enum { ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM } last_added_;
#define LAST(x) last_added_ = x;
#else
#define LAST(x)
#endif
};

using RegExpCaptureName = ZoneGrowableArray<uint16_t>;

class RegExpParser : public ValueObject {
 public:
  RegExpParser(const String& in, String* error, RegExpFlags regexp_flags);

  static void ParseRegExp(const String& input,
                          RegExpFlags regexp_flags,
                          RegExpCompileData* result);

  RegExpTree* ParsePattern();
  RegExpTree* ParseDisjunction();
  RegExpTree* ParseGroup();

  // Parses a {...,...} quantifier and stores the range in the given
  // out parameters.
  bool ParseIntervalQuantifier(intptr_t* min_out, intptr_t* max_out);

  // Parses and returns a single escaped character.  The character
  // must not be 'b' or 'B' since they are usually handle specially.
  uint32_t ParseClassCharacterEscape();

  // Checks whether the following is a length-digit hexadecimal number,
  // and sets the value if it is.
  bool ParseHexEscape(intptr_t length, uint32_t* value);
  bool ParseUnicodeEscape(uint32_t* value);
  bool ParseUnlimitedLengthHexNumber(uint32_t max_value, uint32_t* value);

  // Parses either {UNICODE_PROPERTY_NAME=UNICODE_PROPERTY_VALUE} or
  // the shorthand {UNICODE_PROPERTY_NAME_OR_VALUE} and stores the
  // result in the given out parameters. If the shorthand is used,
  // nothing will be added to name_2.
  bool ParsePropertyClassName(ZoneGrowableArray<char>* name_1,
                              ZoneGrowableArray<char>* name_2);
  // Adds the specified unicode property to the provided character range.
  bool AddPropertyClassRange(ZoneGrowableArray<CharacterRange>* add_to,
                             bool negate,
                             ZoneGrowableArray<char>* name_1,
                             ZoneGrowableArray<char>* name_2);
  // Returns a regexp node that corresponds to one of these unicode
  // property sequences: "Any", "ASCII", "Assigned".
  RegExpTree* GetPropertySequence(ZoneGrowableArray<char>* name_1);
  RegExpTree* ParseCharacterClass(const RegExpBuilder* builder);

  uint32_t ParseOctalLiteral();

  // Tries to parse the input as a back reference.  If successful it
  // stores the result in the output parameter and returns true.  If
  // it fails it will push back the characters read so the same characters
  // can be reparsed.
  bool ParseBackReferenceIndex(intptr_t* index_out);

  // Attempts to parse a possible escape within a character class.
  bool ParseClassEscape(ZoneGrowableArray<CharacterRange>* ranges,
                        bool add_unicode_case_equivalents,
                        uint32_t* char_out);
  void ReportError(const char* message);
  void Advance();
  void Advance(intptr_t dist);
  void Reset(intptr_t pos);

  // Reports whether the pattern might be used as a literal search string.
  // Only use if the result of the parse is a single atom node.
  bool simple();
  bool contains_anchor() { return contains_anchor_; }
  void set_contains_anchor() { contains_anchor_ = true; }
  intptr_t captures_started() { return captures_started_; }
  intptr_t position() { return next_pos_ - 1; }
  bool is_unicode() const { return top_level_flags_.IsUnicode(); }

  static bool IsSyntaxCharacterOrSlash(uint32_t c);

  static constexpr intptr_t kMaxCaptures = 1 << 16;
  static constexpr uint32_t kEndMarker = (1 << 21);

 private:
  enum SubexpressionType {
    INITIAL,
    CAPTURE,  // All positive values represent captures.
    POSITIVE_LOOKAROUND,
    NEGATIVE_LOOKAROUND,
    GROUPING
  };

  class RegExpParserState : public ZoneAllocated {
   public:
    RegExpParserState(RegExpParserState* previous_state,
                      SubexpressionType group_type,
                      RegExpLookaround::Type lookaround_type,
                      intptr_t disjunction_capture_index,
                      const RegExpCaptureName* capture_name,
                      RegExpFlags flags,
                      Zone* zone)
        : previous_state_(previous_state),
          builder_(new(zone) RegExpBuilder(flags)),
          group_type_(group_type),
          lookaround_type_(lookaround_type),
          disjunction_capture_index_(disjunction_capture_index),
          capture_name_(capture_name) {}
    // Parser state of containing expression, if any.
    RegExpParserState* previous_state() { return previous_state_; }
    bool IsSubexpression() { return previous_state_ != nullptr; }
    // RegExpBuilder building this regexp's AST.
    RegExpBuilder* builder() { return builder_; }
    // Type of regexp being parsed (parenthesized group or entire regexp).
    SubexpressionType group_type() { return group_type_; }
    // Lookahead or lookbehind.
    RegExpLookaround::Type lookaround_type() { return lookaround_type_; }
    // Index in captures array of first capture in this sub-expression, if any.
    // Also the capture index of this sub-expression itself, if group_type
    // is CAPTURE.
    intptr_t capture_index() { return disjunction_capture_index_; }
    const RegExpCaptureName* capture_name() const { return capture_name_; }

    bool IsNamedCapture() const { return capture_name_ != nullptr; }

    // Check whether the parser is inside a capture group with the given index.
    bool IsInsideCaptureGroup(intptr_t index);
    // Check whether the parser is inside a capture group with the given name.
    bool IsInsideCaptureGroup(const RegExpCaptureName* name);

   private:
    // Linked list implementation of stack of states.
    RegExpParserState* previous_state_;
    // Builder for the stored disjunction.
    RegExpBuilder* builder_;
    // Stored disjunction type (capture, look-ahead or grouping), if any.
    SubexpressionType group_type_;
    // Stored read direction.
    const RegExpLookaround::Type lookaround_type_;
    // Stored disjunction's capture index (if any).
    intptr_t disjunction_capture_index_;
    // Stored capture name (if any).
    const RegExpCaptureName* const capture_name_;
  };

  // Return the 1-indexed RegExpCapture object, allocate if necessary.
  RegExpCapture* GetCapture(intptr_t index);

  // Creates a new named capture at the specified index. Must be called exactly
  // once for each named capture. Fails if a capture with the same name is
  // encountered.
  void CreateNamedCaptureAtIndex(const RegExpCaptureName* name, intptr_t index);

  // Parses the name of a capture group (?<name>pattern). The name must adhere
  // to IdentifierName in the ECMAScript standard.
  const RegExpCaptureName* ParseCaptureGroupName();

  bool ParseNamedBackReference(RegExpBuilder* builder,
                               RegExpParserState* state);
  RegExpParserState* ParseOpenParenthesis(RegExpParserState* state);
  intptr_t GetNamedCaptureIndex(const RegExpCaptureName* name);

  // After the initial parsing pass, patch corresponding RegExpCapture objects
  // into all RegExpBackReferences. This is done after initial parsing in order
  // to avoid complicating cases in which references come before the capture.
  void PatchNamedBackReferences();

  ArrayPtr CreateCaptureNameMap();

  // Returns true iff the pattern contains named captures. May call
  // ScanForCaptures to look ahead at the remaining pattern.
  bool HasNamedCaptures();

  Zone* zone() { return zone_; }

  uint32_t current() { return current_; }
  bool has_more() { return has_more_; }
  bool has_next() { return next_pos_ < in().Length(); }
  uint32_t Next();
  uint32_t ReadNext(bool update_position);
  const String& in() { return in_; }
  void ScanForCaptures();

  Zone* zone_;
  ZoneGrowableArray<RegExpCapture*>* captures_;
  ZoneGrowableArray<RegExpCapture*>* named_captures_;
  ZoneGrowableArray<RegExpBackReference*>* named_back_references_;
  const String& in_;
  uint32_t current_;
  intptr_t next_pos_;
  intptr_t captures_started_;
  // The capture count is only valid after we have scanned for captures.
  intptr_t capture_count_;
  bool has_more_;
  RegExpFlags top_level_flags_;
  bool simple_;
  bool contains_anchor_;
  bool is_scanned_for_captures_;
  bool has_named_captures_;
};

}  // namespace dart

#endif  // RUNTIME_VM_REGEXP_PARSER_H_
