// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_PENDING_COMPILATION_ERROR_HANDLER_H_
#define V8_PENDING_COMPILATION_ERROR_HANDLER_H_

#include <forward_list>

#include "src/base/macros.h"
#include "src/globals.h"
#include "src/handles.h"
#include "src/messages.h"

namespace v8 {
namespace internal {

class AstRawString;
class AstValueFactory;
class Isolate;
class Script;

// Helper class for handling pending compilation errors consistently in various
// compilation phases.
class PendingCompilationErrorHandler {
 public:
  PendingCompilationErrorHandler()
      : has_pending_error_(false),
        stack_overflow_(false),
        error_type_(kSyntaxError) {}

  void ReportMessageAt(int start_position, int end_position,
                       MessageTemplate::Template message,
                       const char* arg = nullptr,
                       ParseErrorType error_type = kSyntaxError);

  void ReportMessageAt(int start_position, int end_position,
                       MessageTemplate::Template message,
                       const AstRawString* arg,
                       ParseErrorType error_type = kSyntaxError);

  void ReportWarningAt(int start_position, int end_position,
                       MessageTemplate::Template message,
                       const char* arg = nullptr);

  bool stack_overflow() const { return stack_overflow_; }

  void set_stack_overflow() {
    has_pending_error_ = true;
    stack_overflow_ = true;
  }

  bool has_pending_error() const { return has_pending_error_; }
  bool has_pending_warnings() const { return !warning_messages_.empty(); }

  // Handle errors detected during parsing.
  void ReportErrors(Isolate* isolate, Handle<Script> script,
                    AstValueFactory* ast_value_factory);

  // Handle warnings detected during compilation.
  void ReportWarnings(Isolate* isolate, Handle<Script> script);

  Handle<String> FormatErrorMessageForTest(Isolate* isolate) const;

 private:
  class MessageDetails {
   public:
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(MessageDetails);
    MessageDetails()
        : start_position_(-1),
          end_position_(-1),
          message_(MessageTemplate::kNone),
          arg_(nullptr),
          char_arg_(nullptr) {}
    MessageDetails(int start_position, int end_position,
                   MessageTemplate::Template message, const AstRawString* arg,
                   const char* char_arg)
        : start_position_(start_position),
          end_position_(end_position),
          message_(message),
          arg_(arg),
          char_arg_(char_arg) {}

    Handle<String> ArgumentString(Isolate* isolate) const;
    MessageLocation GetLocation(Handle<Script> script) const;
    MessageTemplate::Template message() const { return message_; }

   private:
    int start_position_;
    int end_position_;
    MessageTemplate::Template message_;
    const AstRawString* arg_;
    const char* char_arg_;
  };

  void ThrowPendingError(Isolate* isolate, Handle<Script> script);

  bool has_pending_error_;
  bool stack_overflow_;

  MessageDetails error_details_;
  ParseErrorType error_type_;

  std::forward_list<MessageDetails> warning_messages_;

  DISALLOW_COPY_AND_ASSIGN(PendingCompilationErrorHandler);
};

}  // namespace internal
}  // namespace v8
#endif  // V8_PENDING_COMPILATION_ERROR_HANDLER_H_
