/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "perfetto/tracing/traced_value.h"

#include <array>
#include <deque>
#include <forward_list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>

#include "perfetto/base/template_util.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/test/traced_value_test_support.h"
#include "perfetto/tracing/debug_annotation.h"
#include "perfetto/tracing/track_event.h"
#include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
#include "protos/perfetto/trace/track_event/debug_annotation.pb.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {

// static asserts checking for conversion support for known types.

#define ASSERT_TYPE_SUPPORTED(T)                           \
  static_assert(check_traced_value_support<T>::value, ""); \
  static_assert(internal::has_traced_value_support<T>::value, "")

#define ASSERT_TYPE_NOT_SUPPORTED(T) \
  static_assert(!internal::has_traced_value_support<T>::value, "")

struct NonSupportedType {};

ASSERT_TYPE_SUPPORTED(bool);

ASSERT_TYPE_NOT_SUPPORTED(NonSupportedType);

// Integer types.
ASSERT_TYPE_SUPPORTED(short int);
ASSERT_TYPE_SUPPORTED(unsigned short int);
ASSERT_TYPE_SUPPORTED(int);
ASSERT_TYPE_SUPPORTED(unsigned int);
ASSERT_TYPE_SUPPORTED(long int);
ASSERT_TYPE_SUPPORTED(unsigned long int);
ASSERT_TYPE_SUPPORTED(long long int);
ASSERT_TYPE_SUPPORTED(unsigned long long int);

// References and const references types.
ASSERT_TYPE_SUPPORTED(int&);
ASSERT_TYPE_SUPPORTED(const int&);
ASSERT_TYPE_NOT_SUPPORTED(NonSupportedType&);
ASSERT_TYPE_NOT_SUPPORTED(const NonSupportedType&);

// Character types.
ASSERT_TYPE_SUPPORTED(signed char);
ASSERT_TYPE_SUPPORTED(unsigned char);
ASSERT_TYPE_SUPPORTED(char);
ASSERT_TYPE_SUPPORTED(wchar_t);

// Float types.
ASSERT_TYPE_SUPPORTED(float);
ASSERT_TYPE_SUPPORTED(double);
ASSERT_TYPE_SUPPORTED(long double);

// Strings.
ASSERT_TYPE_SUPPORTED(const char*);
ASSERT_TYPE_SUPPORTED(const char[]);
ASSERT_TYPE_SUPPORTED(const char[2]);
ASSERT_TYPE_SUPPORTED(std::string);

// Pointers.
ASSERT_TYPE_SUPPORTED(int*);
ASSERT_TYPE_SUPPORTED(const int*);
ASSERT_TYPE_SUPPORTED(void*);
ASSERT_TYPE_SUPPORTED(const void*);
ASSERT_TYPE_SUPPORTED(std::nullptr_t);
ASSERT_TYPE_NOT_SUPPORTED(NonSupportedType*);
ASSERT_TYPE_NOT_SUPPORTED(const NonSupportedType*);

// Arrays.
ASSERT_TYPE_NOT_SUPPORTED(int[]);
ASSERT_TYPE_NOT_SUPPORTED(const int[]);
ASSERT_TYPE_NOT_SUPPORTED(NonSupportedType[]);
ASSERT_TYPE_NOT_SUPPORTED(const NonSupportedType[]);
ASSERT_TYPE_SUPPORTED(int (&)[3]);
ASSERT_TYPE_SUPPORTED(const int (&)[3]);
ASSERT_TYPE_NOT_SUPPORTED(NonSupportedType (&)[3]);
ASSERT_TYPE_NOT_SUPPORTED(const NonSupportedType (&)[3]);

// STL containers.
ASSERT_TYPE_SUPPORTED(std::vector<int>);
ASSERT_TYPE_NOT_SUPPORTED(std::vector<NonSupportedType>);

using array_int_t = std::array<int, 4>;
ASSERT_TYPE_SUPPORTED(array_int_t);
ASSERT_TYPE_SUPPORTED(std::deque<int>);
ASSERT_TYPE_SUPPORTED(std::forward_list<int>);
ASSERT_TYPE_SUPPORTED(std::list<int>);
ASSERT_TYPE_NOT_SUPPORTED(std::stack<int>);
ASSERT_TYPE_NOT_SUPPORTED(std::queue<int>);
ASSERT_TYPE_NOT_SUPPORTED(std::priority_queue<int>);
ASSERT_TYPE_SUPPORTED(std::set<int>);
ASSERT_TYPE_SUPPORTED(std::multiset<int>);
using map_int_int_t = std::map<int, int>;
ASSERT_TYPE_NOT_SUPPORTED(map_int_int_t);
using multimap_int_int_t = std::multimap<int, int>;
ASSERT_TYPE_NOT_SUPPORTED(multimap_int_int_t);
ASSERT_TYPE_SUPPORTED(std::unordered_set<int>);
ASSERT_TYPE_SUPPORTED(std::unordered_multiset<int>);
using unordered_map_int_int_t = std::unordered_map<int, int>;
ASSERT_TYPE_NOT_SUPPORTED(unordered_map_int_int_t);
using unordered_multimap_int_int_t = std::unordered_multimap<int, int>;
ASSERT_TYPE_NOT_SUPPORTED(unordered_multimap_int_int_t);

// unique_ptr.
ASSERT_TYPE_SUPPORTED(std::unique_ptr<int>);
ASSERT_TYPE_NOT_SUPPORTED(std::unique_ptr<NonSupportedType>);


TEST(TracedValueTest, FlatDictionary_Explicit) {
  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
  {
    auto dict =
        internal::CreateTracedValueFromProto(message.get()).WriteDictionary();
    dict.AddItem("bool").WriteBoolean(true);
    dict.AddItem("double").WriteDouble(0.0);
    dict.AddItem("int").WriteInt64(2014);
    dict.AddItem("string").WriteString("string");
    dict.AddItem("truncated_string").WriteString("truncated_string", 9);
    dict.AddItem("ptr").WritePointer(reinterpret_cast<void*>(0x1234));
  }
  EXPECT_EQ(
      "{bool:true,double:0,int:2014,string:string,truncated_string:truncated,"
      "ptr:0x1234}",
      internal::DebugAnnotationToString(message.SerializeAsString()));
}

TEST(TracedValueTest, FlatDictionary_Short) {
  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
  {
    auto dict =
        internal::CreateTracedValueFromProto(message.get()).WriteDictionary();
    dict.Add("bool", true);
    dict.Add("double", 0.0);
    dict.Add("int", 2014);
    dict.Add("string", "string");
    dict.Add("ptr", reinterpret_cast<void*>(0x1234));
  }
  EXPECT_EQ("{bool:true,double:0,int:2014,string:string,ptr:0x1234}",
            internal::DebugAnnotationToString(message.SerializeAsString()));
}

TEST(TracedValueTest, Hierarchy_Explicit) {
  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
  {
    auto root_dict =
        internal::CreateTracedValueFromProto(message.get()).WriteDictionary();
    {
      auto array = root_dict.AddItem("a1").WriteArray();
      array.AppendItem().WriteInt64(1);
      array.AppendItem().WriteBoolean(true);
      {
        auto dict = array.AppendItem().WriteDictionary();
        dict.AddItem("i2").WriteInt64(3);
      }
    }
    root_dict.AddItem("b0").WriteBoolean(true);
    root_dict.AddItem("d0").WriteDouble(0.0);
    {
      auto dict1 = root_dict.AddItem("dict1").WriteDictionary();
      {
        auto dict2 = dict1.AddItem("dict2").WriteDictionary();
        dict2.AddItem("b2").WriteBoolean(false);
      }
      dict1.AddItem("i1").WriteInt64(2014);
      dict1.AddItem("s1").WriteString("foo");
    }
    root_dict.AddItem("i0").WriteInt64(2014);
    root_dict.AddItem("s0").WriteString("foo");
  }

  EXPECT_EQ(
      "{"
      "a1:[1,true,{i2:3}],"
      "b0:true,"
      "d0:0,"
      "dict1:{dict2:{b2:false},i1:2014,s1:foo},"
      "i0:2014,"
      "s0:foo}",
      internal::DebugAnnotationToString(message.SerializeAsString()));
}

TEST(TracedValueTest, Hierarchy_Short) {
  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
  {
    auto root_dict =
        internal::CreateTracedValueFromProto(message.get()).WriteDictionary();
    {
      auto array = root_dict.AddArray("a1");
      array.Append(1);
      array.Append(true);
      {
        auto dict = array.AppendDictionary();
        dict.Add("i2", 3);
      }
    }
    root_dict.Add("b0", true);
    root_dict.Add("d0", 0.0);
    {
      auto dict1 = root_dict.AddDictionary("dict1");
      {
        auto dict2 = dict1.AddDictionary("dict2");
        dict2.Add("b2", false);
      }
      dict1.Add("i1", 2014);
      dict1.Add("s1", "foo");
    }
    root_dict.Add("i0", 2014);
    root_dict.Add("s0", "foo");
  }

  EXPECT_EQ(
      "{"
      "a1:[1,true,{i2:3}],"
      "b0:true,"
      "d0:0,"
      "dict1:{dict2:{b2:false},i1:2014,s1:foo},"
      "i0:2014,"
      "s0:foo}",
      internal::DebugAnnotationToString(message.SerializeAsString()));
}

namespace {

class HasWriteIntoTracedValueConvertorMember {
 public:
  void WriteIntoTracedValue(TracedValue context) const {
    auto dict = std::move(context).WriteDictionary();
    dict.Add("int", 42);
    dict.Add("bool", false);
  }
};

class HasWriteIntoTraceConvertorMember {
 public:
  void WriteIntoTrace(TracedValue context) const {
    auto dict = std::move(context).WriteDictionary();
    dict.Add("int", 42);
    dict.Add("bool", false);
  }
};

class HasExternalWriteIntoTraceConvertor {};
class HasExternalWriteIntoTracedValueConvertor {};

class HasAllConversionMethods {
 public:
  void WriteIntoTracedValue(TracedValue context) const {
    std::move(context).WriteString("T::WriteIntoTracedValue");
  }

  void operator()(TracedValue context) const {
    std::move(context).WriteString("T::()");
  }
};

class NoConversions {};

class HasConstWriteMember {
 public:
  void WriteIntoTracedValue(TracedValue context) const {
    std::move(context).WriteString("T::WriteIntoTracedValue const");
  }
};

class HasNonConstWriteMember {
 public:
  void WriteIntoTracedValue(TracedValue context) {
    std::move(context).WriteString("T::WriteIntoTracedValue");
  }
};

class HasConstAndNonConstWriteMember {
 public:
  void WriteIntoTracedValue(TracedValue context) {
    std::move(context).WriteString("T::WriteIntoTracedValue");
  }

  void WriteIntoTracedValue(TracedValue context) const {
    std::move(context).WriteString("T::WriteIntoTracedValue const");
  }
};

}  // namespace

template <>
struct TraceFormatTraits<HasExternalWriteIntoTraceConvertor> {
  static void WriteIntoTrace(TracedValue context,
                             const HasExternalWriteIntoTraceConvertor&) {
    std::move(context).WriteString("TraceFormatTraits::WriteIntoTrace");
  }
};

template <>
struct TraceFormatTraits<HasExternalWriteIntoTracedValueConvertor> {
  static void WriteIntoTracedValue(
      TracedValue context,
      const HasExternalWriteIntoTracedValueConvertor&) {
    std::move(context).WriteString("TraceFormatTraits::WriteIntoTracedValue");
  }
};

template <>
struct TraceFormatTraits<HasAllConversionMethods> {
  static void WriteIntoTracedValue(TracedValue context,
                                   const HasAllConversionMethods&) {
    std::move(context).WriteString("TraceFormatTraits::WriteIntoTracedValue");
  }
};

template <typename T>
std::string ToStringWithFallback(T&& value, const std::string& fallback) {
  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
  WriteIntoTracedValueWithFallback(
      internal::CreateTracedValueFromProto(message.get()),
      std::forward<T>(value), fallback);
  return internal::DebugAnnotationToString(message.SerializeAsString());
}

ASSERT_TYPE_SUPPORTED(HasWriteIntoTraceConvertorMember);
ASSERT_TYPE_SUPPORTED(HasWriteIntoTracedValueConvertorMember);
ASSERT_TYPE_SUPPORTED(HasExternalWriteIntoTraceConvertor);
ASSERT_TYPE_SUPPORTED(HasExternalWriteIntoTracedValueConvertor);
ASSERT_TYPE_SUPPORTED(HasAllConversionMethods);

ASSERT_TYPE_SUPPORTED(HasConstWriteMember);
ASSERT_TYPE_SUPPORTED(HasConstWriteMember&);
ASSERT_TYPE_SUPPORTED(HasConstWriteMember*);
ASSERT_TYPE_SUPPORTED(std::unique_ptr<HasConstWriteMember>);
ASSERT_TYPE_SUPPORTED(std::vector<HasConstWriteMember>);
ASSERT_TYPE_SUPPORTED(const HasConstWriteMember);
ASSERT_TYPE_SUPPORTED(const HasConstWriteMember&);
ASSERT_TYPE_SUPPORTED(const HasConstWriteMember*);
ASSERT_TYPE_SUPPORTED(std::unique_ptr<const HasConstWriteMember>);
ASSERT_TYPE_SUPPORTED(const std::vector<HasConstWriteMember>);
ASSERT_TYPE_SUPPORTED(std::vector<const HasConstWriteMember*>);

ASSERT_TYPE_SUPPORTED(HasNonConstWriteMember);
ASSERT_TYPE_SUPPORTED(HasNonConstWriteMember&);
ASSERT_TYPE_SUPPORTED(HasNonConstWriteMember*);
ASSERT_TYPE_SUPPORTED(std::unique_ptr<HasNonConstWriteMember>);
ASSERT_TYPE_SUPPORTED(std::vector<HasNonConstWriteMember>);
ASSERT_TYPE_NOT_SUPPORTED(const HasNonConstWriteMember);
ASSERT_TYPE_NOT_SUPPORTED(const HasNonConstWriteMember&);
ASSERT_TYPE_NOT_SUPPORTED(const HasNonConstWriteMember*);
ASSERT_TYPE_NOT_SUPPORTED(std::unique_ptr<const HasNonConstWriteMember>);
ASSERT_TYPE_NOT_SUPPORTED(const std::vector<HasNonConstWriteMember>);
ASSERT_TYPE_NOT_SUPPORTED(std::vector<const HasNonConstWriteMember*>);

ASSERT_TYPE_SUPPORTED(HasConstAndNonConstWriteMember);
ASSERT_TYPE_SUPPORTED(HasConstAndNonConstWriteMember&);
ASSERT_TYPE_SUPPORTED(HasConstAndNonConstWriteMember*);
ASSERT_TYPE_SUPPORTED(std::unique_ptr<HasConstAndNonConstWriteMember>);
ASSERT_TYPE_SUPPORTED(const HasConstAndNonConstWriteMember);
ASSERT_TYPE_SUPPORTED(const HasConstAndNonConstWriteMember&);
ASSERT_TYPE_SUPPORTED(const HasConstAndNonConstWriteMember*);
ASSERT_TYPE_SUPPORTED(std::unique_ptr<const HasConstAndNonConstWriteMember*>);

TEST(TracedValueTest, UserDefinedConvertors) {
  HasWriteIntoTraceConvertorMember value1;
  EXPECT_EQ(TracedValueToString(value1), "{int:42,bool:false}");
  EXPECT_EQ(TracedValueToString(&value1), "{int:42,bool:false}");

  HasWriteIntoTracedValueConvertorMember value2;
  EXPECT_EQ(TracedValueToString(value2), "{int:42,bool:false}");
  EXPECT_EQ(TracedValueToString(&value2), "{int:42,bool:false}");

  HasExternalWriteIntoTracedValueConvertor value3;
  EXPECT_EQ(TracedValueToString(value3),
            "TraceFormatTraits::WriteIntoTracedValue");
  EXPECT_EQ(TracedValueToString(&value3),
            "TraceFormatTraits::WriteIntoTracedValue");

  HasExternalWriteIntoTraceConvertor value4;
  EXPECT_EQ(TracedValueToString(value4), "TraceFormatTraits::WriteIntoTrace");
  EXPECT_EQ(TracedValueToString(&value4), "TraceFormatTraits::WriteIntoTrace");

  HasAllConversionMethods value5;
  EXPECT_EQ(TracedValueToString(value5), "T::WriteIntoTracedValue");
  EXPECT_EQ(TracedValueToString(&value5), "T::WriteIntoTracedValue");
}

TEST(TracedValueTest, WriteAsLambda) {
  EXPECT_EQ("42", TracedValueToString([&](TracedValue context) {
              std::move(context).WriteInt64(42);
            }));
}

#if PERFETTO_DCHECK_IS_ON()
// This death test makes sense only when dchecks are enabled.
TEST(TracedValueTest, FailOnIncorrectUsage) {
  // A new call to AddItem is not allowed before the previous result is
  // consumed.
  EXPECT_DEATH(

      {
        protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
        auto dict = internal::CreateTracedValueFromProto(message.get())
                        .WriteDictionary();
        auto scope1 = dict.AddItem("key1");
        auto scope2 = dict.AddItem("key2");
        std::move(scope1).WriteInt64(1);
        std::move(scope2).WriteInt64(2);
      },
      "");

  // A new call to AppendItem is not allowed before the previous result is
  // consumed.
  EXPECT_DEATH(
      {
        protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
        auto array =
            internal::CreateTracedValueFromProto(message.get()).WriteArray();
        auto scope1 = array.AppendItem();
        auto scope2 = array.AppendItem();
        std::move(scope1).WriteInt64(1);
        std::move(scope2).WriteInt64(2);
      },
      "");

  // Writing to parent scope is not allowed.
  EXPECT_DEATH(
      {
        protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
        auto outer_dict = internal::CreateTracedValueFromProto(message.get())
                              .WriteDictionary();
        {
          auto inner_dict = outer_dict.AddDictionary("inner");
          outer_dict.Add("key", "value");
        }
      },
      "");
}
#endif  // PERFETTO_DCHECK_IS_ON()

TEST(TracedValueTest, PrimitiveTypesSupport) {
  EXPECT_EQ("0x0", TracedValueToString(nullptr));
  EXPECT_EQ("0x1", TracedValueToString(reinterpret_cast<void*>(1)));

  const int int_value = 1;
  EXPECT_EQ("1", TracedValueToString(int_value));
  EXPECT_EQ("1", TracedValueToString(&int_value));

  EXPECT_EQ("1.5", TracedValueToString(1.5));
  EXPECT_EQ("true", TracedValueToString(true));
  EXPECT_EQ("foo", TracedValueToString("foo"));
  EXPECT_EQ("bar", TracedValueToString(std::string("bar")));
}

TEST(TracedValueTest, UniquePtrSupport) {
  std::unique_ptr<int> value1;
  EXPECT_EQ("0x0", TracedValueToString(value1));

  std::unique_ptr<int> value2(new int(4));
  EXPECT_EQ("4", TracedValueToString(value2));
}

namespace {

enum OldStyleEnum { kFoo, kBar };

enum class NewStyleEnum { kValue1, kValue2 };

enum class EnumWithPrettyPrint { kValue1, kValue2 };

}  // namespace

template <>
struct TraceFormatTraits<EnumWithPrettyPrint> {
  static void WriteIntoTracedValue(TracedValue context,
                                   EnumWithPrettyPrint value) {
    switch (value) {
      case EnumWithPrettyPrint::kValue1:
        std::move(context).WriteString("value1");
        return;
      case EnumWithPrettyPrint::kValue2:
        std::move(context).WriteString("value2");
        return;
    }
  }
};

TEST(TracedValueTest, EnumSupport) {
  EXPECT_EQ(TracedValueToString(kFoo), "0");
  EXPECT_EQ(TracedValueToString(NewStyleEnum::kValue2), "1");
  EXPECT_EQ(TracedValueToString(EnumWithPrettyPrint::kValue2), "value2");
}

TEST(TracedValueTest, ContainerSupport) {
  std::vector<std::list<int>> value1{{1, 2}, {3, 4}};
  EXPECT_EQ("[[1,2],[3,4]]", TracedValueToString(value1));
}

TEST(TracedValueTest, WriteWithFallback) {
  EXPECT_EQ("1", ToStringWithFallback(1, "fallback"));
  EXPECT_EQ("true", ToStringWithFallback(true, "fallback"));
  EXPECT_EQ("fallback", ToStringWithFallback(NonSupportedType(), "fallback"));
}

TEST(TracedValueTest, ConstAndNotConstSupport) {
  {
    HasConstWriteMember value;
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(value));
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(&value));

    std::vector<HasConstWriteMember> arr(1, value);
    EXPECT_EQ("[T::WriteIntoTracedValue const]", TracedValueToString(arr));
  }

  {
    const HasConstWriteMember value;
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(value));
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(&value));

    const std::vector<HasConstWriteMember> arr(1, value);
    EXPECT_EQ("[T::WriteIntoTracedValue const]", TracedValueToString(arr));
  }

  {
    HasNonConstWriteMember value;
    EXPECT_EQ("T::WriteIntoTracedValue", TracedValueToString(value));
    EXPECT_EQ("T::WriteIntoTracedValue", TracedValueToString(&value));

    std::vector<HasNonConstWriteMember> arr(1, value);
    EXPECT_EQ("[T::WriteIntoTracedValue]", TracedValueToString(arr));
  }

  {
    HasConstAndNonConstWriteMember value;
    EXPECT_EQ("T::WriteIntoTracedValue", TracedValueToString(value));
    EXPECT_EQ("T::WriteIntoTracedValue", TracedValueToString(&value));

    std::vector<HasConstAndNonConstWriteMember> arr(1, value);
    EXPECT_EQ("[T::WriteIntoTracedValue]", TracedValueToString(arr));
  }

  {
    const HasConstAndNonConstWriteMember value;
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(value));
    EXPECT_EQ("T::WriteIntoTracedValue const", TracedValueToString(&value));

    const std::vector<HasConstAndNonConstWriteMember> arr(1, value);
    EXPECT_EQ("[T::WriteIntoTracedValue const]", TracedValueToString(arr));
  }
}

// Note: interning of the dictionary keys is not implemented yet, so there is no
// difference in behaviour for StaticString and DynamicString yet.
TEST(TracedValueTest, DictionaryKeys) {
  EXPECT_EQ("{literal:1}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
              dict.Add("literal", 1);
            }));

  EXPECT_EQ("{static:1}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
              const char* key = "static";
              dict.Add(StaticString{key}, 1);
            }));

  EXPECT_EQ("{dynamic:1}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
              std::string key = "dynamic";
              dict.Add(DynamicString{key.data()}, 1);
            }));

  EXPECT_EQ("{dynamic:1}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
              std::string key = "dynamic";
              dict.Add(DynamicString{key.data(), key.length()}, 1);
            }));

  EXPECT_EQ("{dynamic:1}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
              std::string key = "dynamic";
              dict.Add(DynamicString{key}, 1);
            }));
}

TEST(TracedValueTest, EmptyDict) {
  EXPECT_EQ("{}", TracedValueToString([&](TracedValue context) {
              auto dict = std::move(context).WriteDictionary();
            }));
}

TEST(TracedValueTest, EmptyArray) {
  // For now we do not distinguish between empty arrays and empty dicts on proto
  // level as trace processor ignores them anyway.
  EXPECT_EQ("{}", TracedValueToString([&](TracedValue context) {
              auto array = std::move(context).WriteArray();
            }));
}

}  // namespace perfetto
