// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/traced_value.h"

#include <inttypes.h>
#include <stdint.h>

#include <atomic>
#include <utility>

#include "base/bits.h"
#include "base/containers/circular_deque.h"
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_impl.h"
#include "base/trace_event/trace_event_memory_overhead.h"
#include "base/trace_event/trace_log.h"
#include "base/values.h"

namespace base {
namespace trace_event {

namespace {
const char kTypeStartDict = '{';
const char kTypeEndDict = '}';
const char kTypeStartArray = '[';
const char kTypeEndArray = ']';
const char kTypeBool = 'b';
const char kTypeInt = 'i';
const char kTypeDouble = 'd';
const char kTypeString = 's';
const char kTypeCStr = '*';  // only used for key names

std::atomic<TracedValue::WriterFactoryCallback> g_writer_factory_callback;

#ifndef NDEBUG
const bool kStackTypeDict = false;
const bool kStackTypeArray = true;
#define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
#define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
#define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
#else
#define DCHECK_CURRENT_CONTAINER_IS(x) \
  do {                                 \
  } while (0)
#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) \
  do {                                     \
  } while (0)
#define DEBUG_PUSH_CONTAINER(x) \
  do {                          \
  } while (0)
#define DEBUG_POP_CONTAINER() \
  do {                        \
  } while (0)
#endif

inline void WriteKeyNameAsRawPtr(Pickle& pickle, const char* ptr) {
  pickle.WriteBytes(&kTypeCStr, 1);
  pickle.WriteUInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)));
}

inline void WriteKeyNameWithCopy(Pickle& pickle, base::StringPiece str) {
  pickle.WriteBytes(&kTypeString, 1);
  pickle.WriteString(str);
}

std::string ReadKeyName(PickleIterator& pickle_iterator) {
  const char* type = nullptr;
  bool res = pickle_iterator.ReadBytes(&type, 1);
  std::string key_name;
  if (res && *type == kTypeCStr) {
    uint64_t ptr_value = 0;
    res = pickle_iterator.ReadUInt64(&ptr_value);
    key_name = reinterpret_cast<const char*>(static_cast<uintptr_t>(ptr_value));
  } else if (res && *type == kTypeString) {
    res = pickle_iterator.ReadString(&key_name);
  }
  DCHECK(res);
  return key_name;
}

class PickleWriter final : public TracedValue::Writer {
 public:
  explicit PickleWriter(size_t capacity) {
    if (capacity) {
      pickle_.Reserve(capacity);
    }
  }

  bool IsPickleWriter() const override { return true; }
  bool IsProtoWriter() const override { return false; }

  void SetInteger(const char* name, int value) override {
    pickle_.WriteBytes(&kTypeInt, 1);
    pickle_.WriteInt(value);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void SetIntegerWithCopiedName(base::StringPiece name, int value) override {
    pickle_.WriteBytes(&kTypeInt, 1);
    pickle_.WriteInt(value);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void SetDouble(const char* name, double value) override {
    pickle_.WriteBytes(&kTypeDouble, 1);
    pickle_.WriteDouble(value);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void SetDoubleWithCopiedName(base::StringPiece name, double value) override {
    pickle_.WriteBytes(&kTypeDouble, 1);
    pickle_.WriteDouble(value);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void SetBoolean(const char* name, bool value) override {
    pickle_.WriteBytes(&kTypeBool, 1);
    pickle_.WriteBool(value);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void SetBooleanWithCopiedName(base::StringPiece name, bool value) override {
    pickle_.WriteBytes(&kTypeBool, 1);
    pickle_.WriteBool(value);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void SetString(const char* name, base::StringPiece value) override {
    pickle_.WriteBytes(&kTypeString, 1);
    pickle_.WriteString(value);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void SetStringWithCopiedName(base::StringPiece name,
                               base::StringPiece value) override {
    pickle_.WriteBytes(&kTypeString, 1);
    pickle_.WriteString(value);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void SetValue(const char* name, Writer* value) override {
    DCHECK(value->IsPickleWriter());
    const PickleWriter* pickle_writer = static_cast<const PickleWriter*>(value);

    BeginDictionary(name);
    pickle_.WriteBytes(pickle_writer->pickle_.payload(),
                       pickle_writer->pickle_.payload_size());
    EndDictionary();
  }

  void SetValueWithCopiedName(base::StringPiece name, Writer* value) override {
    DCHECK(value->IsPickleWriter());
    const PickleWriter* pickle_writer = static_cast<const PickleWriter*>(value);

    BeginDictionaryWithCopiedName(name);
    pickle_.WriteBytes(pickle_writer->pickle_.payload(),
                       pickle_writer->pickle_.payload_size());
    EndDictionary();
  }

  void BeginArray() override { pickle_.WriteBytes(&kTypeStartArray, 1); }

  void BeginDictionary() override { pickle_.WriteBytes(&kTypeStartDict, 1); }

  void BeginDictionary(const char* name) override {
    pickle_.WriteBytes(&kTypeStartDict, 1);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void BeginDictionaryWithCopiedName(base::StringPiece name) override {
    pickle_.WriteBytes(&kTypeStartDict, 1);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void BeginArray(const char* name) override {
    pickle_.WriteBytes(&kTypeStartArray, 1);
    WriteKeyNameAsRawPtr(pickle_, name);
  }

  void BeginArrayWithCopiedName(base::StringPiece name) override {
    pickle_.WriteBytes(&kTypeStartArray, 1);
    WriteKeyNameWithCopy(pickle_, name);
  }

  void EndDictionary() override { pickle_.WriteBytes(&kTypeEndDict, 1); }
  void EndArray() override { pickle_.WriteBytes(&kTypeEndArray, 1); }

  void AppendInteger(int value) override {
    pickle_.WriteBytes(&kTypeInt, 1);
    pickle_.WriteInt(value);
  }

  void AppendDouble(double value) override {
    pickle_.WriteBytes(&kTypeDouble, 1);
    pickle_.WriteDouble(value);
  }

  void AppendBoolean(bool value) override {
    pickle_.WriteBytes(&kTypeBool, 1);
    pickle_.WriteBool(value);
  }

  void AppendString(base::StringPiece value) override {
    pickle_.WriteBytes(&kTypeString, 1);
    pickle_.WriteString(value);
  }

  void AppendAsTraceFormat(std::string* out) const override {
    struct State {
      enum Type { kTypeDict, kTypeArray };
      Type type;
      bool needs_comma;
    };

    auto maybe_append_key_name = [](State current_state, PickleIterator* it,
                                    std::string* out) {
      if (current_state.type == State::kTypeDict) {
        EscapeJSONString(ReadKeyName(*it), true, out);
        out->append(":");
      }
    };

    base::circular_deque<State> state_stack;

    out->append("{");
    state_stack.push_back({State::kTypeDict});

    PickleIterator it(pickle_);
    for (const char* type; it.ReadBytes(&type, 1);) {
      switch (*type) {
        case kTypeEndDict:
          out->append("}");
          state_stack.pop_back();
          continue;

        case kTypeEndArray:
          out->append("]");
          state_stack.pop_back();
          continue;
      }

      // Use an index so it will stay valid across resizes.
      size_t current_state_index = state_stack.size() - 1;
      if (state_stack[current_state_index].needs_comma) {
        out->append(",");
      }

      switch (*type) {
        case kTypeStartDict: {
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          out->append("{");
          state_stack.push_back({State::kTypeDict});
          break;
        }

        case kTypeStartArray: {
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          out->append("[");
          state_stack.push_back({State::kTypeArray});
          break;
        }

        case kTypeBool: {
          TraceEvent::TraceValue json_value;
          CHECK(it.ReadBool(&json_value.as_bool));
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          json_value.AppendAsJSON(TRACE_VALUE_TYPE_BOOL, out);
          break;
        }

        case kTypeInt: {
          int value;
          CHECK(it.ReadInt(&value));
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          TraceEvent::TraceValue json_value;
          json_value.as_int = value;
          json_value.AppendAsJSON(TRACE_VALUE_TYPE_INT, out);
          break;
        }

        case kTypeDouble: {
          TraceEvent::TraceValue json_value;
          CHECK(it.ReadDouble(&json_value.as_double));
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          json_value.AppendAsJSON(TRACE_VALUE_TYPE_DOUBLE, out);
          break;
        }

        case kTypeString: {
          std::string value;
          CHECK(it.ReadString(&value));
          maybe_append_key_name(state_stack[current_state_index], &it, out);
          TraceEvent::TraceValue json_value;
          json_value.as_string = value.c_str();
          json_value.AppendAsJSON(TRACE_VALUE_TYPE_STRING, out);
          break;
        }

        default:
          NOTREACHED();
      }

      state_stack[current_state_index].needs_comma = true;
    }

    out->append("}");
    state_stack.pop_back();

    DCHECK(state_stack.empty());
  }

  void EstimateTraceMemoryOverhead(
      TraceEventMemoryOverhead* overhead) override {
    overhead->Add(TraceEventMemoryOverhead::kTracedValue,
                  /* allocated size */
                  pickle_.GetTotalAllocatedSize(),
                  /* resident size */
                  pickle_.size());
  }

  std::unique_ptr<base::Value> ToBaseValue() const {
    base::Value root(base::Value::Type::DICT);
    Value* cur_dict = &root;
    Value* cur_list = nullptr;
    std::vector<Value*> stack;
    PickleIterator it(pickle_);
    const char* type;

    while (it.ReadBytes(&type, 1)) {
      DCHECK((cur_dict && !cur_list) || (cur_list && !cur_dict));
      switch (*type) {
        case kTypeStartDict: {
          if (cur_dict) {
            stack.push_back(cur_dict);
            cur_dict = cur_dict->GetDict().Set(ReadKeyName(it),
                                               Value(Value::Type::DICT));
          } else {
            cur_list->GetList().Append(Value(Value::Type::DICT));
            // Update |cur_dict| to point to the newly added dictionary.
            cur_dict = &cur_list->GetList().back();
            stack.push_back(cur_list);
            cur_list = nullptr;
          }
        } break;

        case kTypeEndArray:
        case kTypeEndDict: {
          if (stack.back()->is_dict()) {
            cur_dict = stack.back();
            cur_list = nullptr;
          } else if (stack.back()->is_list()) {
            cur_list = stack.back();
            cur_dict = nullptr;
          }
          stack.pop_back();
        } break;

        case kTypeStartArray: {
          Value::List new_list;
          if (cur_dict) {
            stack.push_back(cur_dict);
            cur_list =
                cur_dict->GetDict().Set(ReadKeyName(it), std::move(new_list));
            cur_dict = nullptr;
          } else {
            cur_list->GetList().Append(std::move(new_list));
            stack.push_back(cur_list);
            // |cur_list| is invalidated at this point by the Append, so it
            // needs to be reset.
            cur_list = &cur_list->GetList().back();
          }
        } break;

        case kTypeBool: {
          bool value;
          CHECK(it.ReadBool(&value));
          if (cur_dict) {
            cur_dict->GetDict().Set(ReadKeyName(it), value);
          } else {
            cur_list->GetList().Append(value);
          }
        } break;

        case kTypeInt: {
          int value;
          CHECK(it.ReadInt(&value));
          if (cur_dict) {
            cur_dict->GetDict().Set(ReadKeyName(it), value);
          } else {
            cur_list->GetList().Append(value);
          }
        } break;

        case kTypeDouble: {
          TraceEvent::TraceValue trace_value;
          CHECK(it.ReadDouble(&trace_value.as_double));
          Value base_value;
          if (!std::isfinite(trace_value.as_double)) {
            // base::Value doesn't support nan and infinity values. Use strings
            // for them instead. This follows the same convention in
            // AppendAsTraceFormat(), supported by TraceValue::Append*().
            std::string value_string;
            trace_value.AppendAsString(TRACE_VALUE_TYPE_DOUBLE, &value_string);
            base_value = Value(value_string);
          } else {
            base_value = Value(trace_value.as_double);
          }
          if (cur_dict) {
            cur_dict->GetDict().Set(ReadKeyName(it), std::move(base_value));
          } else {
            cur_list->GetList().Append(std::move(base_value));
          }
        } break;

        case kTypeString: {
          std::string value;
          CHECK(it.ReadString(&value));
          if (cur_dict) {
            cur_dict->GetDict().Set(ReadKeyName(it), std::move(value));
          } else {
            cur_list->GetList().Append(std::move(value));
          }
        } break;

        default:
          NOTREACHED();
      }
    }
    DCHECK(stack.empty());
    return base::Value::ToUniquePtrValue(std::move(root));
  }

 private:
  Pickle pickle_;
};

std::unique_ptr<TracedValue::Writer> CreateWriter(size_t capacity) {
  TracedValue::WriterFactoryCallback callback =
      g_writer_factory_callback.load(std::memory_order_relaxed);
  if (callback) {
    return callback(capacity);
  }

  return std::make_unique<PickleWriter>(capacity);
}

}  // namespace

bool TracedValue::Writer::AppendToProto(ProtoAppender* appender) {
  return false;
}

// static
void TracedValue::SetWriterFactoryCallback(WriterFactoryCallback callback) {
  g_writer_factory_callback.store(callback);
}

TracedValue::TracedValue(size_t capacity)
    : TracedValue(capacity, /*forced_json*/ false) {}

TracedValue::TracedValue(size_t capacity, bool forced_json) {
  DEBUG_PUSH_CONTAINER(kStackTypeDict);

  writer_ = forced_json ? std::make_unique<PickleWriter>(capacity)
                        : CreateWriter(capacity);
}

TracedValue::~TracedValue() {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_POP_CONTAINER();
  DCHECK_CONTAINER_STACK_DEPTH_EQ(0u);
}

void TracedValue::SetInteger(const char* name, int value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetInteger(name, value);
}

void TracedValue::SetIntegerWithCopiedName(base::StringPiece name, int value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetIntegerWithCopiedName(name, value);
}

void TracedValue::SetDouble(const char* name, double value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetDouble(name, value);
}

void TracedValue::SetDoubleWithCopiedName(base::StringPiece name,
                                          double value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetDoubleWithCopiedName(name, value);
}

void TracedValue::SetBoolean(const char* name, bool value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetBoolean(name, value);
}

void TracedValue::SetBooleanWithCopiedName(base::StringPiece name, bool value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetBooleanWithCopiedName(name, value);
}

void TracedValue::SetString(const char* name, base::StringPiece value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetString(name, value);
}

void TracedValue::SetStringWithCopiedName(base::StringPiece name,
                                          base::StringPiece value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetStringWithCopiedName(name, value);
}

void TracedValue::SetValue(const char* name, TracedValue* value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetValue(name, value->writer_.get());
}

void TracedValue::SetValueWithCopiedName(base::StringPiece name,
                                         TracedValue* value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetValueWithCopiedName(name, value->writer_.get());
}

namespace {

// TODO(altimin): Add native support for pointers for nested values in
// DebugAnnotation proto.
std::string PointerToString(void* value) {
  return base::StringPrintf(
      "0x%" PRIx64, static_cast<uint64_t>(reinterpret_cast<uintptr_t>(value)));
}

}  // namespace

void TracedValue::SetPointer(const char* name, void* value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetString(name, PointerToString(value));
}

void TracedValue::SetPointerWithCopiedName(base::StringPiece name,
                                           void* value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  writer_->SetStringWithCopiedName(name, PointerToString(value));
}

void TracedValue::BeginDictionary(const char* name) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_PUSH_CONTAINER(kStackTypeDict);
  writer_->BeginDictionary(name);
}

void TracedValue::BeginDictionaryWithCopiedName(base::StringPiece name) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_PUSH_CONTAINER(kStackTypeDict);
  writer_->BeginDictionaryWithCopiedName(name);
}

void TracedValue::BeginArray(const char* name) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_PUSH_CONTAINER(kStackTypeArray);
  writer_->BeginArray(name);
}

void TracedValue::BeginArrayWithCopiedName(base::StringPiece name) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_PUSH_CONTAINER(kStackTypeArray);
  writer_->BeginArrayWithCopiedName(name);
}

void TracedValue::AppendInteger(int value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  writer_->AppendInteger(value);
}

void TracedValue::AppendDouble(double value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  writer_->AppendDouble(value);
}

void TracedValue::AppendBoolean(bool value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  writer_->AppendBoolean(value);
}

void TracedValue::AppendString(base::StringPiece value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  writer_->AppendString(value);
}

void TracedValue::AppendPointer(void* value) {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  writer_->AppendString(PointerToString(value));
}

void TracedValue::BeginArray() {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  DEBUG_PUSH_CONTAINER(kStackTypeArray);
  writer_->BeginArray();
}

void TracedValue::BeginDictionary() {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  DEBUG_PUSH_CONTAINER(kStackTypeDict);
  writer_->BeginDictionary();
}

void TracedValue::EndArray() {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
  DEBUG_POP_CONTAINER();
  writer_->EndArray();
}

void TracedValue::EndDictionary() {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DEBUG_POP_CONTAINER();
  writer_->EndDictionary();
}

std::unique_ptr<base::Value> TracedValue::ToBaseValue() const {
  DCHECK(writer_->IsPickleWriter());
  return static_cast<const PickleWriter*>(writer_.get())->ToBaseValue();
}

void TracedValue::AppendAsTraceFormat(std::string* out) const {
  DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
  DCHECK_CONTAINER_STACK_DEPTH_EQ(1u);

  writer_->AppendAsTraceFormat(out);
}

bool TracedValue::AppendToProto(ProtoAppender* appender) const {
  return writer_->AppendToProto(appender);
}

void TracedValue::EstimateTraceMemoryOverhead(
    TraceEventMemoryOverhead* overhead) {
  writer_->EstimateTraceMemoryOverhead(overhead);
}

TracedValue::Array::Array(const std::initializer_list<ArrayItem> items) {
  items_ = std::move(items);
}

TracedValue::Array::Array(TracedValue::Array&& other) {
  items_ = std::move(other.items_);
}

void TracedValue::Array::WriteToValue(TracedValue* value) const {
  for (const auto& item : items_) {
    item.WriteToValue(value);
  }
}

TracedValue::Dictionary::Dictionary(
    const std::initializer_list<DictionaryItem> items) {
  items_ = items;
}

TracedValue::Dictionary::Dictionary(TracedValue::Dictionary&& other) {
  items_ = std::move(other.items_);
}

void TracedValue::Dictionary::WriteToValue(TracedValue* value) const {
  for (const auto& item : items_) {
    item.WriteToValue(value);
  }
}

TracedValue::ValueHolder::ValueHolder(int value) {
  kept_value_.int_value = value;
  kept_value_type_ = KeptValueType::kIntType;
}

TracedValue::ValueHolder::ValueHolder(double value) {
  kept_value_.double_value = value;
  kept_value_type_ = KeptValueType::kDoubleType;
}

TracedValue::ValueHolder::ValueHolder(bool value) {
  kept_value_.bool_value = value;
  kept_value_type_ = KeptValueType::kBoolType;
}

TracedValue::ValueHolder::ValueHolder(base::StringPiece value) {
  kept_value_.string_piece_value = value;
  kept_value_type_ = KeptValueType::kStringPieceType;
}

TracedValue::ValueHolder::ValueHolder(std::string value) {
  new (&kept_value_.std_string_value) std::string(std::move(value));
  kept_value_type_ = KeptValueType::kStdStringType;
}

TracedValue::ValueHolder::ValueHolder(void* value) {
  kept_value_.void_ptr_value = value;
  kept_value_type_ = KeptValueType::kVoidPtrType;
}

TracedValue::ValueHolder::ValueHolder(const char* value) {
  kept_value_.string_piece_value = value;
  kept_value_type_ = KeptValueType::kStringPieceType;
}

TracedValue::ValueHolder::ValueHolder(TracedValue::Dictionary& value) {
  new (&kept_value_.dictionary_value) TracedValue::Dictionary(std::move(value));
  kept_value_type_ = KeptValueType::kDictionaryType;
}

TracedValue::ValueHolder::ValueHolder(TracedValue::Array& value) {
  new (&kept_value_.array_value) TracedValue::Array(std::move(value));
  kept_value_type_ = KeptValueType::kArrayType;
}

TracedValue::ValueHolder::ValueHolder(TracedValue::ValueHolder&& other) {
  // Remember to call a destructor if necessary.
  if (kept_value_type_ == KeptValueType::kStdStringType) {
    delete (&kept_value_.std_string_value);
  }
  switch (other.kept_value_type_) {
    case KeptValueType::kIntType: {
      kept_value_.int_value = other.kept_value_.int_value;
      break;
    }
    case KeptValueType::kDoubleType: {
      kept_value_.double_value = other.kept_value_.double_value;
      break;
    }
    case KeptValueType::kBoolType: {
      kept_value_.bool_value = other.kept_value_.bool_value;
      break;
    }
    case KeptValueType::kStringPieceType: {
      kept_value_.string_piece_value = other.kept_value_.string_piece_value;
      break;
    }
    case KeptValueType::kStdStringType: {
      new (&kept_value_.std_string_value)
          std::string(std::move(other.kept_value_.std_string_value));
      break;
    }
    case KeptValueType::kVoidPtrType: {
      kept_value_.void_ptr_value = other.kept_value_.void_ptr_value;
      break;
    }
    case KeptValueType::kArrayType: {
      new (&kept_value_.array_value)
          TracedValue::Array(std::move(other.kept_value_.array_value));
      break;
    }
    case KeptValueType::kDictionaryType: {
      new (&kept_value_.dictionary_value) TracedValue::Dictionary(
          std::move(other.kept_value_.dictionary_value));
      break;
    }
  }
  kept_value_type_ = other.kept_value_type_;
}

void TracedValue::ValueHolder::WriteToValue(TracedValue* value) const {
  switch (kept_value_type_) {
    case KeptValueType::kIntType: {
      value->AppendInteger(kept_value_.int_value);
      break;
    }
    case KeptValueType::kDoubleType: {
      value->AppendDouble(kept_value_.double_value);
      break;
    }
    case KeptValueType::kBoolType: {
      value->AppendBoolean(kept_value_.bool_value);
      break;
    }
    case KeptValueType::kStringPieceType: {
      value->AppendString(kept_value_.string_piece_value);
      break;
    }
    case KeptValueType::kStdStringType: {
      value->AppendString(kept_value_.std_string_value);
      break;
    }
    case KeptValueType::kVoidPtrType: {
      value->AppendPointer(kept_value_.void_ptr_value);
      break;
    }
    case KeptValueType::kArrayType: {
      value->BeginArray();
      kept_value_.array_value.WriteToValue(value);
      value->EndArray();
      break;
    }
    case KeptValueType::kDictionaryType: {
      value->BeginDictionary();
      kept_value_.dictionary_value.WriteToValue(value);
      value->EndDictionary();
      break;
    }
  }
}

void TracedValue::ValueHolder::WriteToValue(const char* name,
                                            TracedValue* value) const {
  switch (kept_value_type_) {
    case KeptValueType::kIntType: {
      value->SetInteger(name, kept_value_.int_value);
      break;
    }
    case KeptValueType::kDoubleType: {
      value->SetDouble(name, kept_value_.double_value);
      break;
    }
    case KeptValueType::kBoolType: {
      value->SetBoolean(name, kept_value_.bool_value);
      break;
    }
    case KeptValueType::kStringPieceType: {
      value->SetString(name, kept_value_.string_piece_value);
      break;
    }
    case KeptValueType::kStdStringType: {
      value->SetString(name, kept_value_.std_string_value);
      break;
    }
    case KeptValueType::kVoidPtrType: {
      value->SetPointer(name, kept_value_.void_ptr_value);
      break;
    }
    case KeptValueType::kArrayType: {
      value->BeginArray(name);
      kept_value_.array_value.WriteToValue(value);
      value->EndArray();
      break;
    }
    case KeptValueType::kDictionaryType: {
      value->BeginDictionary(name);
      kept_value_.dictionary_value.WriteToValue(value);
      value->EndDictionary();
      break;
    }
  }
}

void TracedValue::ArrayItem::WriteToValue(TracedValue* value) const {
  ValueHolder::WriteToValue(value);
}

void TracedValue::DictionaryItem::WriteToValue(TracedValue* value) const {
  ValueHolder::WriteToValue(name_, value);
}

std::unique_ptr<TracedValue> TracedValue::Build(
    const std::initializer_list<DictionaryItem> items) {
  std::unique_ptr<TracedValue> value(new TracedValue());
  for (const auto& item : items) {
    item.WriteToValue(value.get());
  }
  return value;
}

std::string TracedValueJSON::ToJSON() const {
  std::string result;
  AppendAsTraceFormat(&result);
  return result;
}

std::string TracedValueJSON::ToFormattedJSON() const {
  std::string str;
  base::JSONWriter::WriteWithOptions(
      *ToBaseValue(),
      base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION |
          base::JSONWriter::OPTIONS_PRETTY_PRINT,
      &str);
  return str;
}

TracedValue::ArrayScope::ArrayScope(TracedValue* value) : value_(value) {}

TracedValue::ArrayScope::~ArrayScope() {
  value_->EndArray();
}

TracedValue::ArrayScope TracedValue::AppendArrayScoped() {
  BeginArray();
  return TracedValue::ArrayScope(this);
}

TracedValue::ArrayScope TracedValue::BeginArrayScoped(const char* name) {
  BeginArray(name);
  return TracedValue::ArrayScope(this);
}

TracedValue::ArrayScope TracedValue::BeginArrayScopedWithCopiedName(
    base::StringPiece name) {
  BeginArrayWithCopiedName(name);
  return TracedValue::ArrayScope(this);
}

TracedValue::DictionaryScope::DictionaryScope(TracedValue* value)
    : value_(value) {}

TracedValue::DictionaryScope::~DictionaryScope() {
  value_->EndDictionary();
}

TracedValue::DictionaryScope TracedValue::AppendDictionaryScoped() {
  BeginDictionary();
  return TracedValue::DictionaryScope(this);
}

TracedValue::DictionaryScope TracedValue::BeginDictionaryScoped(
    const char* name) {
  BeginDictionary(name);
  return TracedValue::DictionaryScope(this);
}

TracedValue::DictionaryScope TracedValue::BeginDictionaryScopedWithCopiedName(
    base::StringPiece name) {
  BeginDictionaryWithCopiedName(name);
  return TracedValue::DictionaryScope(this);
}

}  // namespace trace_event
}  // namespace base
