// Copyright 2006-2008 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.

// The infrastructure used for (localized) message reporting in V8.
//
// Note: there's a big unresolved issue about ownership of the data
// structures used by this framework.

#ifndef V8_MESSAGES_H_
#define V8_MESSAGES_H_

#include <memory>

#include "src/handles.h"
#include "src/message-template.h"

namespace v8 {
namespace internal {
namespace wasm {
class WasmCode;
}

// Forward declarations.
class AbstractCode;
class FrameArray;
class IncrementalStringBuilder;
class JSMessageObject;
class LookupIterator;
class SharedFunctionInfo;
class SourceInfo;
class WasmInstanceObject;

class MessageLocation {
 public:
  MessageLocation(Handle<Script> script, int start_pos, int end_pos);
  MessageLocation(Handle<Script> script, int start_pos, int end_pos,
                  Handle<SharedFunctionInfo> shared);
  MessageLocation();

  Handle<Script> script() const { return script_; }
  int start_pos() const { return start_pos_; }
  int end_pos() const { return end_pos_; }
  Handle<SharedFunctionInfo> shared() const { return shared_; }

 private:
  Handle<Script> script_;
  int start_pos_;
  int end_pos_;
  Handle<SharedFunctionInfo> shared_;
};

class StackFrameBase {
 public:
  virtual ~StackFrameBase() = default;

  virtual Handle<Object> GetReceiver() const = 0;
  virtual Handle<Object> GetFunction() const = 0;

  virtual Handle<Object> GetFileName() = 0;
  virtual Handle<Object> GetFunctionName() = 0;
  virtual Handle<Object> GetScriptNameOrSourceUrl() = 0;
  virtual Handle<Object> GetMethodName() = 0;
  virtual Handle<Object> GetTypeName() = 0;
  virtual Handle<Object> GetEvalOrigin();

  // Returns the script ID if one is attached, -1 otherwise.
  int GetScriptId() const;

  virtual int GetPosition() const = 0;
  // Return 1-based line number, including line offset.
  virtual int GetLineNumber() = 0;
  // Return 1-based column number, including column offset if first line.
  virtual int GetColumnNumber() = 0;

  // Returns index for Promise.all() async frames, or -1 for other frames.
  virtual int GetPromiseIndex() const = 0;

  virtual bool IsNative() = 0;
  virtual bool IsToplevel() = 0;
  virtual bool IsEval();
  virtual bool IsAsync() const = 0;
  virtual bool IsPromiseAll() const = 0;
  virtual bool IsConstructor() = 0;
  virtual bool IsStrict() const = 0;

  MaybeHandle<String> ToString();
  virtual void ToString(IncrementalStringBuilder& builder) = 0;

  // Used to signal that the requested field is unknown.
  static const int kNone = -1;

 protected:
  StackFrameBase() = default;
  explicit StackFrameBase(Isolate* isolate) : isolate_(isolate) {}
  Isolate* isolate_;

 private:
  virtual bool HasScript() const = 0;
  virtual Handle<Script> GetScript() const = 0;
};

class JSStackFrame : public StackFrameBase {
 public:
  JSStackFrame(Isolate* isolate, Handle<Object> receiver,
               Handle<JSFunction> function, Handle<AbstractCode> code,
               int offset);
  ~JSStackFrame() override = default;

  Handle<Object> GetReceiver() const override { return receiver_; }
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override;
  Handle<Object> GetFunctionName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override;
  Handle<Object> GetMethodName() override;
  Handle<Object> GetTypeName() override;

  int GetPosition() const override;
  int GetLineNumber() override;
  int GetColumnNumber() override;

  int GetPromiseIndex() const override;

  bool IsNative() override;
  bool IsToplevel() override;
  bool IsAsync() const override { return is_async_; }
  bool IsPromiseAll() const override { return is_promise_all_; }
  bool IsConstructor() override { return is_constructor_; }
  bool IsStrict() const override { return is_strict_; }

  void ToString(IncrementalStringBuilder& builder) override;

 private:
  JSStackFrame() = default;
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

  bool HasScript() const override;
  Handle<Script> GetScript() const override;

  Handle<Object> receiver_;
  Handle<JSFunction> function_;
  Handle<AbstractCode> code_;
  int offset_;

  bool is_async_ : 1;
  bool is_constructor_ : 1;
  bool is_promise_all_ : 1;
  bool is_strict_ : 1;

  friend class FrameArrayIterator;
};

class WasmStackFrame : public StackFrameBase {
 public:
  ~WasmStackFrame() override = default;

  Handle<Object> GetReceiver() const override;
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override { return Null(); }
  Handle<Object> GetFunctionName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); }
  Handle<Object> GetMethodName() override { return Null(); }
  Handle<Object> GetTypeName() override { return Null(); }

  int GetPosition() const override;
  int GetLineNumber() override { return wasm_func_index_; }
  int GetColumnNumber() override { return kNone; }

  int GetPromiseIndex() const override { return kNone; }

  bool IsNative() override { return false; }
  bool IsToplevel() override { return false; }
  bool IsAsync() const override { return false; }
  bool IsPromiseAll() const override { return false; }
  bool IsConstructor() override { return false; }
  bool IsStrict() const override { return false; }
  bool IsInterpreted() const { return code_ == nullptr; }

  void ToString(IncrementalStringBuilder& builder) override;

 protected:
  Handle<Object> Null() const;

  bool HasScript() const override;
  Handle<Script> GetScript() const override;

  Handle<WasmInstanceObject> wasm_instance_;
  uint32_t wasm_func_index_;
  wasm::WasmCode* code_;  // null for interpreted frames.
  int offset_;

 private:
  WasmStackFrame() = default;
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

  friend class FrameArrayIterator;
  friend class AsmJsWasmStackFrame;
};

class AsmJsWasmStackFrame : public WasmStackFrame {
 public:
  ~AsmJsWasmStackFrame() override = default;

  Handle<Object> GetReceiver() const override;
  Handle<Object> GetFunction() const override;

  Handle<Object> GetFileName() override;
  Handle<Object> GetScriptNameOrSourceUrl() override;

  int GetPosition() const override;
  int GetLineNumber() override;
  int GetColumnNumber() override;

  void ToString(IncrementalStringBuilder& builder) override;

 private:
  friend class FrameArrayIterator;
  AsmJsWasmStackFrame() = default;
  void FromFrameArray(Isolate* isolate, Handle<FrameArray> array, int frame_ix);

  bool is_at_number_conversion_;
};

class FrameArrayIterator {
 public:
  FrameArrayIterator(Isolate* isolate, Handle<FrameArray> array,
                     int frame_ix = 0);

  StackFrameBase* Frame();

  bool HasFrame() const;
  void Advance();

 private:
  Isolate* isolate_;

  Handle<FrameArray> array_;
  int frame_ix_;

  WasmStackFrame wasm_frame_;
  AsmJsWasmStackFrame asm_wasm_frame_;
  JSStackFrame js_frame_;
};

// Determines how stack trace collection skips frames.
enum FrameSkipMode {
  // Unconditionally skips the first frame. Used e.g. when the Error constructor
  // is called, in which case the first frame is always a BUILTIN_EXIT frame.
  SKIP_FIRST,
  // Skip all frames until a specified caller function is seen.
  SKIP_UNTIL_SEEN,
  SKIP_NONE,
};

class ErrorUtils : public AllStatic {
 public:
  static MaybeHandle<Object> Construct(
      Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target,
      Handle<Object> message, FrameSkipMode mode, Handle<Object> caller,
      bool suppress_detailed_trace);

  static MaybeHandle<String> ToString(Isolate* isolate, Handle<Object> recv);

  static MaybeHandle<Object> MakeGenericError(
      Isolate* isolate, Handle<JSFunction> constructor, MessageTemplate index,
      Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2,
      FrameSkipMode mode);

  // Formats a textual stack trace from the given structured stack trace.
  // Note that this can call arbitrary JS code through Error.prepareStackTrace.
  static MaybeHandle<Object> FormatStackTrace(Isolate* isolate,
                                              Handle<JSObject> error,
                                              Handle<Object> stack_trace);
};

class MessageFormatter {
 public:
  static const char* TemplateString(MessageTemplate index);

  static MaybeHandle<String> Format(Isolate* isolate, MessageTemplate index,
                                    Handle<String> arg0, Handle<String> arg1,
                                    Handle<String> arg2);

  static Handle<String> Format(Isolate* isolate, MessageTemplate index,
                               Handle<Object> arg);
};


// A message handler is a convenience interface for accessing the list
// of message listeners registered in an environment
class MessageHandler {
 public:
  // Returns a message object for the API to use.
  static Handle<JSMessageObject> MakeMessageObject(
      Isolate* isolate, MessageTemplate type, const MessageLocation* location,
      Handle<Object> argument, Handle<FixedArray> stack_frames);

  // Report a formatted message (needs JS allocation).
  static void ReportMessage(Isolate* isolate, const MessageLocation* loc,
                            Handle<JSMessageObject> message);

  static void DefaultMessageReport(Isolate* isolate, const MessageLocation* loc,
                                   Handle<Object> message_obj);
  static Handle<String> GetMessage(Isolate* isolate, Handle<Object> data);
  static std::unique_ptr<char[]> GetLocalizedMessage(Isolate* isolate,
                                                     Handle<Object> data);

 private:
  static void ReportMessageNoExceptions(Isolate* isolate,
                                        const MessageLocation* loc,
                                        Handle<Object> message_obj,
                                        v8::Local<v8::Value> api_exception_obj);
};


}  // namespace internal
}  // namespace v8

#endif  // V8_MESSAGES_H_
