// Copyright 2016 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_

#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"

namespace blink {

class File;
class Transferables;

// Serializes V8 values according to the HTML structured clone algorithm:
// https://html.spec.whatwg.org/C/#structured-clone
//
// Supports only basic JavaScript objects and core DOM types. Support for
// modules types is implemented in a subclass.
//
// A serializer cannot be used multiple times; it is expected that its serialize
// method will be invoked exactly once.
class CORE_EXPORT V8ScriptValueSerializer
    : public v8::ValueSerializer::Delegate {
  STACK_ALLOCATED();

 public:
  using Options = SerializedScriptValue::SerializeOptions;
  explicit V8ScriptValueSerializer(ScriptState*, const Options& = Options());

  scoped_refptr<SerializedScriptValue> Serialize(v8::Local<v8::Value>,
                                                 ExceptionState&);

 protected:
  // Returns true if the DOM object was successfully written.
  // If false is returned and no more specific exception is thrown, a generic
  // DataCloneError message will be used.
  virtual bool WriteDOMObject(ScriptWrappable*, ExceptionState&);

  ScriptState* GetScriptState() const { return script_state_; }

  void WriteTag(SerializationTag tag) {
    uint8_t tag_byte = tag;
    serializer_.WriteRawBytes(&tag_byte, 1);
  }
  void WriteUint32(uint32_t value) { serializer_.WriteUint32(value); }
  void WriteUint64(uint64_t value) { serializer_.WriteUint64(value); }
  void WriteDouble(double value) { serializer_.WriteDouble(value); }
  void WriteRawBytes(const void* data, size_t size) {
    serializer_.WriteRawBytes(data, size);
  }
  void WriteUTF8String(const String&);

  template <typename E>
  void WriteUint32Enum(E value) {
    static_assert(
        std::is_enum<E>::value &&
            std::is_same<uint32_t,
                         typename std::underlying_type<E>::type>::value,
        "Only enums backed by uint32_t are accepted.");
    WriteUint32(static_cast<uint32_t>(value));
  }

  SerializedScriptValue* GetSerializedScriptValue() {
    return serialized_script_value_.get();
  }

  bool IsForStorage() const { return for_storage_; }

 private:
  // Transfer is split into two phases: scanning the transferables so that we
  // don't have to serialize the data (just an index), and finalizing (to
  // neuter objects in the source context).
  // This separation is required by the spec (it prevents neutering from
  // happening if there's a failure earlier in serialization).
  void PrepareTransfer(ExceptionState&);
  void FinalizeTransfer(ExceptionState&);

  // Shared between File and FileList logic; does not write a leading tag.
  bool WriteFile(File*, ExceptionState&);

  // v8::ValueSerializer::Delegate
  void ThrowDataCloneError(v8::Local<v8::String> message) override;
  v8::Maybe<bool> WriteHostObject(v8::Isolate*,
                                  v8::Local<v8::Object> message) override;
  v8::Maybe<uint32_t> GetSharedArrayBufferId(
      v8::Isolate*,
      v8::Local<v8::SharedArrayBuffer>) override;

  v8::Maybe<uint32_t> GetWasmModuleTransferId(
      v8::Isolate*,
      v8::Local<v8::WasmModuleObject>) override;
  // Reallocates memory at |ptr| to the new size and returns the new pointer or
  // nullptr on failure. |actual_size| will hold the actual size of allocation
  // requested.
  void* ReallocateBufferMemory(void* old_buffer,
                               size_t,
                               size_t* actual_size) override;
  void FreeBufferMemory(void* buffer) override;

  bool TransferableStreamsEnabled() const;

  ScriptState* script_state_;
  scoped_refptr<SerializedScriptValue> serialized_script_value_;
  v8::ValueSerializer serializer_;
  const Transferables* transferables_ = nullptr;
  const ExceptionState* exception_state_ = nullptr;
  WebBlobInfoArray* blob_info_array_ = nullptr;
  SharedArrayBufferArray shared_array_buffers_;
  Options::WasmSerializationPolicy wasm_policy_;
  bool for_storage_ = false;
#if DCHECK_IS_ON()
  bool serialize_invoked_ = false;
#endif

  DISALLOW_COPY_AND_ASSIGN(V8ScriptValueSerializer);
};

// For code testing V8ScriptValueSerializer
scoped_refptr<SerializedScriptValue> SerializedValue(
    const Vector<uint8_t>& bytes);

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_V8_SCRIPT_VALUE_SERIALIZER_H_
